Another Validation Solution for Prequel Challenge 4

The other day the Chairman shared a possible solution for prequel challenge #4. In his enthusiasm for PowerShell and automation, he jumped the gun on the next challenge which was to have you create a validation test.  But that’s ok. Because this provides an opportunity to share a variation on the validation tests.

In the previous solution, the Pester test ran in the remote machine, technically a container in the Chairman’s solution. That meant you needed to make sure Pester was up to date. But the Pester test could also be run from an administrator’s desktop which presumably is already running the latest version of Pester. In this example, the test file is run locally but all the assertions are executed remotely via a PowerShell session.

# You might also use TestCases in your Pester test

$computername = "SRV3"

$admin = Get-Credential -Message "enter the admin credential for $computername" -UserName "$computernameadministrator"

#the session is using PowerShell Direct to connect to a Hyper-V virtual machine
$remote = New-PSSession -VMName $computername -Credential $admin

Describe "ServerConfiguration for $Computername" {
  It "Should have a System event log maximum size of 2GB" {
    $log = Invoke-Command { (get-eventlog -list).where({$_.log -eq 'system'})} -session $remote
    $log.MaximumKilobytes | Should be (2gb/1kb) 
  }

  $paths = @("C:Data") 
  $months = (Get-Culture).DateTimeFormat.AbbreviatedMonthNames | Where-object {$_}
  foreach ($month in $months) {
      #build a path and add it to the array
      $paths+=(Join-Path -Path "C:Data" -ChildPath $month)
  }
  foreach ($path in $paths) {
      It "$path Should exist" {
        Invoke-command { Test-Path $using:Path} -session $remote | Should BeTrue
      }
  }
  
  #get current feature state
  Invoke-Command { Get-WindowsFeature} -Session $remote |
  Foreach-Object -Begin { $feat = @{} } -process {
    $feat.add($_.name,$_.installed)
  }

  $add = @("windows-server-backup","telnet-client","web-ftp-server","enhancedstorage")
  foreach ($feature in $add) {
      It "Windows feature $feature should be installed" {
        $feat[$feature] | Should BeTrue
      }
  }
  $remove = @("powershell-v2","snmp-service")
  foreach ($feature in $remove) {
      It "Windows feature $feature should NOT be installed" {
        $feat[$feature] | Should BeFalse
      }
  }

  $Policy = "Remotesigned"
  It "Should have an execution policy of $policy" {
    (Invoke-Command { Get-ExecutionPolicy} -session $Remote).value | should be $policy
  }

  $Trusted = "172.16.100.*"
  It "Includes $trusted in Trustedhosts" {
   (Invoke-Command { Get-Item WSMan:localhostClientTrustedHosts} -session $remote).value | Should -Match $trusted
  }
  It "Should have a local administrator account for RoyGBiv" {
    $user = Invoke-command { Get-Localuser RoyGBiv} -session $remote
    $group = Invoke-command { Get-LocalGroupMember administrators } -session $remote
    
    $user.name | Should Be "RoyGBiv"
    $group.Name | Should Contain "$computernameRoyGbiv" 
  }
  It "Should have the PSScriptTools Module installed" {
     $m = Invoke-Command {Get-Module PSScriptTools -listavailable} -session $remote
     $m.name | Should be "PSScriptTools"
  } 
}

 Remove-PSSession $remote

This test assumes a Hyper-V virtual machine as the remoting session is created via PowerShell Direct.

Running the Pester tests

Not that this type of test isn’t mocking or pretending to do anything. It is running the actual commands to verify the server configuration. This script too could be run with other Invoke-Pester parameters to automate further based on test results.

Remember, that if you encounter a road-block in creating a Pester test, you might first check the Pester wiki. Or get some friendly assistance in the forums at PowerShell.org.