Configurations/PowerShellLab/VMValidate.test.ps1
#requires -version 5.1 #test if VM setup is complete #set error action preference to suppress all error messages which would be normal while configurations are converging BeforeDiscovery { #Write-Host "Pester Test development v2.0.0" -ForegroundColor Yellow $LabData = Import-PowerShellDataFile -Path $PSScriptRoot\VMConfigurationData.psd1 $Domain = $LabData.AllNodes.DomainName $Secure = ConvertTo-SecureString -String "$($LabData.AllNodes.LabPassword)" -AsPlainText -Force $cred = New-Object PSCredential "$Domain\Administrator", $Secure $cl = New-PSSession -VMName WIN10 -Credential $Cred -ErrorAction Stop $FireWallRules = $LabData.AllNodes.FirewallRuleNames $rsat = @( 'Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0', 'Rsat.BitLocker.Recovery.Tools~~~~0.0.1.0', 'Rsat.CertificateServices.Tools~~~~0.0.1.0', 'Rsat.DHCP.Tools~~~~0.0.1.0', 'Rsat.Dns.Tools~~~~0.0.1.0', 'Rsat.FailoverCluster.Management.Tools~~~~0.0.1.0', 'Rsat.FileServices.Tools~~~~0.0.1.0', 'Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0', 'Rsat.IPAM.Client.Tools~~~~0.0.1.0', 'Rsat.ServerManager.Tools~~~~0.0.1.0' ) $pkg = Invoke-Command { $using:rsat | ForEach-Object { Get-WindowsCapability -Online -Name $_ } } -Session $cl $rsatStatus = '{0}/{1}' -f ($pkg.where({ $_.state -eq 'installed' }).Name).count, $rsat.count if ($cl) { $cl | Remove-PSSession } } Describe DOM1 { BeforeAll { $LabData = Import-PowerShellDataFile -Path $PSScriptRoot\*.psd1 $Secure = ConvertTo-SecureString -String "$($LabData.AllNodes.LabPassword)" -AsPlainText -Force $Computername = $LabData.AllNodes[1].NodeName $Domain = $LabData.AllNodes.DomainName $cred = New-Object PSCredential "$Domain\Administrator", $Secure #The prefix only changes the name of the VM not the guest computername $prefix = $LabData.NonNodeData.Lability.EnvironmentPrefix $VMName = "$($prefix)$Computername" #set error action preference to suppress all error messages which would be normal while configurations are converging #turn off progress bars $prep = { $ProgressPreference = 'SilentlyContinue' $errorActionPreference = 'SilentlyContinue' } $VMSess = New-PSSession -VMName $VMName -Credential $Cred -ErrorAction Stop Invoke-Command $prep -Session $VMSess $OS = Invoke-Command { Get-CimInstance -ClassName win32_OperatingSystem -Property caption, csname } -Session $VMSess $dns = Invoke-Command { Get-DnsClientServerAddress -InterfaceAlias ethernet -AddressFamily IPv4 } -Session $VMSess $sys = Invoke-Command { Get-CimInstance Win32_ComputerSystem } -Session $VMSess $if = Invoke-Command -Scriptblock { Get-NetIPAddress -InterfaceAlias 'Ethernet' -AddressFamily IPv4 } -Session $VMSess $resolve = Invoke-Command { Resolve-DnsName www.pluralsight.com -Type A | Select-Object -First 1 } -Session $VMSess $PS2Test = Invoke-Command { (Get-WindowsFeature -Name 'PowerShell-V2').Installed } -Session $VMSess $rec = Invoke-Command { Resolve-DnsName Srv3.company.pri } -Session $VMSess $computer = Invoke-Command { Try { Get-ADComputer -Filter * -ErrorAction SilentlyContinue } Catch { #ignore the error - Domain still spinning up } } -Session $VMSess $users = Invoke-Command { Try { Get-ADUser -Filter * -ErrorAction Stop } Catch { #ignore the error - Domain still spinning up } } -Session $VMSess $groups = Invoke-Command { Try { Get-ADGroup -Filter * -ErrorAction Stop } Catch { #ignore the error - Domain still spinning up } } -Session $VMSess $ADDomain = Invoke-Command { Try { Get-ADDomain -ErrorAction Stop } Catch { #ignore the error - Domain still spinning up } } -Session $VMSess $OUs = Invoke-Command { Try { Get-ADOrganizationalUnit -Filter * -ErrorAction Stop } Catch { #ignore the error - Domain still spinning up } } -Session $VMSess $admins = Invoke-Command { Get-ADGroupMember 'Domain Admins'-ErrorAction SilentlyContinue } -Session $VMSess $feat = Invoke-Command { Get-WindowsFeature | Where-Object installed } -Session $VMSess $rdpTest = Invoke-Command { Get-ItemPropertyValue -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\' -Name fDenyTSConnections } -Session $VMSess $FireWallRules = $LabData.AllNodes.FirewallRuleNames $fw = Invoke-Command { Get-NetFirewallRule -Name $using:FireWallRules } -Session $VMSess | ForEach-Object -Begin { $tmp = @{} } -Process { $tmp.Add($_.Name, $_.Enabled) } -End { $tmp } } AfterAll { if ($VMSess) { $VMSess | Remove-PSSession } } It '[DOM1] Should Be running Windows Server 2019' { $OS.caption | Should -BeLike '*2019*' } It '[DOM1] Should have feature <_> installed' -ForEach @('AD-Domain-Services', 'DNS', 'RSAT-AD-Tools', 'RSAT-AD-PowerShell') { $feat.Name -contains $_ | Should -Be $True } It '[DOM1] Should have an IP address of 192.168.3.10' { $if.ipv4Address | Should -Be '192.168.3.10' } It "[DOM1] Should Belong to the $domain domain" { $sys.domain | Should -Be $domain } It '[DOM1] Should have RDP for admin access enabled' { $rdpTest | Should -Be 0 } It '[DOM1] Should have firewall rule <_> enabled' -ForEach $FireWallRules { $fw[$_] | Should -Be $True } Context ActiveDirectory { It "[DOM1] Should have a domain name of $domain" { $ADDomain.DNSRoot | Should -Be $domain } It '[DOM1] Should have organizational unit <_>' -ForEach @('IT', 'Dev', 'Marketing', 'Sales', 'Accounting', 'JEA_Operators', 'Servers') { $OUs.name -contains $_ | Should -Be $True } It '[DOM1] Should have a group called <_>' -ForEach @('IT', 'Sales', 'Marketing', 'Accounting', 'JEA Operators') { $groups.Name -contains $_ | Should -Be $True } It '[DOM1] Should have at least 15 user accounts' { $users.count | Should -BeGreaterThan 15 } It '[DOM1] ArtD is a member of Domain Admins' { $admins.name -contains 'artd' | Should -Be $True } It '[DOM1] AprilS is a member of Domain Admins' { $admins.name -contains 'aprils' | Should -Be $True } It '[DOM1] Should have a computer account for WIN10' { $computer.name -contains 'Win10' | Should -Be $True } It '[DOM1] Should have a computer account for SRV1' { $computer.name -contains 'SRV1' | Should -Be $True } It '[DOM1] Should have a computer account for SRV2' { $computer.name -contains 'SRV2' | Should -Be $True } } Context DNS { It '[DOM1] Should have a DNS record for SRV3.COMPANY.PRI' { $rec.Name | Should -Be 'srv3.company.pri' $rec.IPAddress | Should -Be '192.168.3.60' } It '[DOM1] Should Be able to resolve an internet address' { $resolve.name | Should -Be 'www.pluralsight.com' } It '[DOM1] Should have a DNS server configuration of 192.168.3.10' { $dns.ServerAddresses -contains '192.168.3.10' | Should -Be $True } } } #DOM1 Describe SRV1 { BeforeAll { $LabData = Import-PowerShellDataFile -Path $PSScriptRoot\*.psd1 $Secure = ConvertTo-SecureString -String "$($LabData.AllNodes.LabPassword)" -AsPlainText -Force $Computername = $LabData.AllNodes[2].NodeName $Domain = $LabData.AllNodes.DomainName $cred = New-Object PSCredential "$Domain\Administrator", $Secure #The prefix only changes the name of the VM not the guest computername $prefix = $LabData.NonNodeData.Lability.EnvironmentPrefix $VMName = "$($prefix)$Computername" #set error action preference to suppress all error messages which would be normal while configurations are converging #turn off progress bars $prep = { $ProgressPreference = 'SilentlyContinue' $errorActionPreference = 'SilentlyContinue' } $VMSess = New-PSSession -VMName $VMName -Credential $Cred -ErrorAction Stop Invoke-Command $prep -Session $VMSess $OS = Invoke-Command { Get-CimInstance -ClassName win32_OperatingSystem -Property caption, csname } -Session $VMSess $dns = Invoke-Command { Get-DnsClientServerAddress -InterfaceAlias ethernet -AddressFamily IPv4 } -Session $VMSess $sys = Invoke-Command { Get-CimInstance Win32_ComputerSystem } -Session $VMSess $if = Invoke-Command -Scriptblock { Get-NetIPAddress -InterfaceAlias 'Ethernet' -AddressFamily IPv4 } -Session $VMSess $resolve = Invoke-Command { Resolve-DnsName www.pluralsight.com -Type A | Select-Object -First 1 } -Session $VMSess #$feat = Invoke-Command { Get-WindowsFeature | Where-Object installed } -Session $VMSess $rdpTest = Invoke-Command { Get-ItemPropertyValue -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\' -Name fDenyTSConnections } -Session $VMSess $FireWallRules = $LabData.AllNodes.FirewallRuleNames $fw = Invoke-Command { Get-NetFirewallRule -Name $using:FireWallRules } -Session $VMSess | ForEach-Object -Begin { $tmp = @{} } -Process { $tmp.Add($_.Name, $_.Enabled) } -End { $tmp } } AfterAll { if ($VMSess) { $VMSess | Remove-PSSession } } It "[SRV1] Should Belong to the $domain domain" { $sys.domain | Should -Be $domain } It '[SRV1] Should have an IP address of 192.168.3.50' { $if.ipv4Address | Should -Be '192.168.3.50' } It '[SRV1] Should have a DNS server configuration of 192.168.3.10' { $dns.ServerAddresses -contains '192.168.3.10' | Should -Be 'True' } It '[SRV1] Should have firewall rule <_> enabled' -ForEach $FireWallRules { $fw[$_] | Should -Be $True } It '[SRV1] Should Be running Windows Server 2019' { $OS.caption | Should -BeLike '*2019*' } It '[SRV1] Should have RDP for admin access enabled' { $rdpTest | Should -Be 0 } It '[SRV1] Should Be able to resolve an internet address' { $resolve.name | Should -Be 'www.pluralsight.com' } } Describe SRV2 { BeforeAll { $LabData = Import-PowerShellDataFile -Path $PSScriptRoot\*.psd1 $Secure = ConvertTo-SecureString -String "$($LabData.AllNodes.LabPassword)" -AsPlainText -Force $Computername = $LabData.AllNodes[3].NodeName $Domain = $LabData.AllNodes.DomainName $cred = New-Object PSCredential "$Domain\Administrator", $Secure #The prefix only changes the name of the VM not the guest computername $prefix = $LabData.NonNodeData.Lability.EnvironmentPrefix $VMName = "$($prefix)$Computername" #set error action preference to suppress all error messages which would be normal while configurations are converging #turn off progress bars $prep = { $ProgressPreference = 'SilentlyContinue' $errorActionPreference = 'SilentlyContinue' } $VMSess = New-PSSession -VMName $VMName -Credential $Cred -ErrorAction Stop Invoke-Command $prep -Session $VMSess $OS = Invoke-Command { Get-CimInstance -ClassName win32_OperatingSystem -Property caption, csname } -Session $VMSess $dns = Invoke-Command { Get-DnsClientServerAddress -InterfaceAlias ethernet -AddressFamily IPv4 } -Session $VMSess $sys = Invoke-Command { Get-CimInstance Win32_ComputerSystem } -Session $VMSess $if = Invoke-Command -Scriptblock { Get-NetIPAddress -InterfaceAlias 'Ethernet' -AddressFamily IPv4 } -Session $VMSess $resolve = Invoke-Command { Resolve-DnsName www.pluralsight.com -Type A | Select-Object -First 1 } -Session $VMSess $feature = Invoke-Command { Get-WindowsFeature -Name web-server } -Session $VMSess $file = Invoke-Command { Get-Item C:\MyWebServices\firstservice.asmx } -Session $VMSess $app = Invoke-Command { Try { Get-WebApplication -Name MyWebServices -ErrorAction stop } Catch {} } -Session $VMSess $rdpTest = Invoke-Command { Get-ItemPropertyValue -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\' -Name fDenyTSConnections } -Session $VMSess $FireWallRules = $LabData.AllNodes.FirewallRuleNames $fw = Invoke-Command { Get-NetFirewallRule -Name $using:FireWallRules } -Session $VMSess | ForEach-Object -Begin { $tmp = @{} } -Process { $tmp.Add($_.Name, $_.Enabled) } -End { $tmp } } AfterAll { if ($VMSess) { $VMSess | Remove-PSSession } } It "[SRV2] Should Belong to the $domain domain" { $sys.domain | Should -Be $domain } It '[SRV2] Should have an IP address of 192.168.3.51' { $if.ipv4Address | Should -Be '192.168.3.51' } It '[SRV2] Should have a DNS server configuration of 192.168.3.10' { $dns.ServerAddresses -contains '192.168.3.10' | Should -Be $True } It '[SRV2] Should have firewall rule <_> enabled' -ForEach $FireWallRules { $fw[$_] | Should -Be $True } It '[SRV2] Should Be running Windows Server 2019' { $OS.caption | Should -BeLike '*2019*' } It '[SRV2] Should have RDP for admin access enabled' { $rdpTest | Should -Be 0 } It '[SRV2] Should Be able to resolve an internet address' { $resolve.name | Should -Be 'www.pluralsight.com' } Context Web { It '[SRV2] Should have the Web-Server feature installed' { $feature.Installed | Should -Be $True } It '[SRV2] Should have a sample web service file' { $file.name | Should -Be 'firstservice.asmx' } It '[SRV2] Should have a WebApplication called MyWebServices' { $app.path | Should -Be '/MyWebServices' $app.PhysicalPath | Should -Be 'c:\MyWebServices' } } } Describe SRV3 { #this is a workgroup server BeforeAll { $LabData = Import-PowerShellDataFile -Path $PSScriptRoot\*.psd1 $Secure = ConvertTo-SecureString -String "$($LabData.AllNodes.LabPassword)" -AsPlainText -Force $Computername = $LabData.AllNodes[4].NodeName $Domain = $Computername $cred = New-Object PSCredential "$Domain\Administrator", $Secure #The prefix only changes the name of the VM not the guest computername $prefix = $LabData.NonNodeData.Lability.EnvironmentPrefix $VMName = "$($prefix)$Computername" #set error action preference to suppress all error messages which would be normal while configurations are converging #turn off progress bars $prep = { $ProgressPreference = 'SilentlyContinue' $errorActionPreference = 'SilentlyContinue' } $VMSess = New-PSSession -VMName $VMName -Credential $Cred -ErrorAction Stop Invoke-Command $prep -Session $VMSess $OS = Invoke-Command { Get-CimInstance -ClassName win32_OperatingSystem -Property caption, csname } -Session $VMSess $dns = Invoke-Command { Get-DnsClientServerAddress -InterfaceAlias ethernet -AddressFamily IPv4 } -Session $VMSess $sys = Invoke-Command { Get-CimInstance Win32_ComputerSystem } -Session $VMSess $if = Invoke-Command -Scriptblock { Get-NetIPAddress -InterfaceAlias 'Ethernet' -AddressFamily IPv4 } -Session $VMSess $resolve = Invoke-Command { Resolve-DnsName www.pluralsight.com -Type A | Select-Object -First 1 } -Session $VMSess $rdpTest = Invoke-Command { Get-ItemPropertyValue -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\' -Name fDenyTSConnections } -Session $VMSess $FireWallRules = $LabData.AllNodes.FirewallRuleNames $fw = Invoke-Command { Get-NetFirewallRule -Name $using:FireWallRules } -Session $VMSess | ForEach-Object -Begin { $tmp = @{} } -Process { $tmp.Add($_.Name, $_.Enabled) } -End { $tmp } } AfterAll { if ($VMSess) { $VMSess | Remove-PSSession } } It '[SRV3] Should have an IP address of 192.168.3.60' { $if.IPv4Address | Should -Be '192.168.3.60' } It '[SRV3] Should Belong to a Workgroup' { $sys.Domain | Should -Be 'Workgroup' } It '[SRV3] Should Be running Windows Server 2022' { $os.caption | Should -BeLike '*2022*' } It '[SRV3] Should have RDP for admin access enabled' { $rdpTest | Should -Be 0 } It '[SRV3] Should have firewall rule <_> enabled' -ForEach $FireWallRules { $fw[$_] | Should -Be $True } It '[SRV3] Should have a DNS server configuration of 192.168.3.10' { $dns.ServerAddresses -contains '192.168.3.10' | Should -Be $True } It '[SRV3] Should Be able to resolve an internet address' { $resolve.name | Should -Be 'www.pluralsight.com' } } Describe Win10 { BeforeAll { $LabData = Import-PowerShellDataFile -Path $PSScriptRoot\*.psd1 $Secure = ConvertTo-SecureString -String "$($LabData.AllNodes.LabPassword)" -AsPlainText -Force $Computername = $LabData.AllNodes[5].NodeName $Domain = $LabData.AllNodes.DomainName $cred = New-Object PSCredential "$Domain\Administrator", $Secure #The prefix only changes the name of the VM not the guest computername $prefix = $LabData.NonNodeData.Lability.EnvironmentPrefix $VMName = "$($prefix)$Computername" #set error action preference to suppress all error messages which would be normal while configurations are converging #turn off progress bars $prep = { $ProgressPreference = 'SilentlyContinue' $errorActionPreference = 'SilentlyContinue' } $VMSess = New-PSSession -VMName $VMName -Credential $Cred -ErrorAction Stop Invoke-Command $prep -Session $VMSess $OS = Invoke-Command { Get-CimInstance -ClassName win32_OperatingSystem -Property caption, csname } -Session $VMSess $dns = Invoke-Command { Get-DnsClientServerAddress -InterfaceAlias ethernet -AddressFamily IPv4 } -Session $VMSess $sys = Invoke-Command { Get-CimInstance Win32_ComputerSystem } -Session $VMSess $if = Invoke-Command -Scriptblock { Get-NetIPAddress -InterfaceAlias 'Ethernet' -AddressFamily IPv4 } -Session $VMSess $resolve = Invoke-Command { Resolve-DnsName www.pluralsight.com -Type A | Select-Object -First 1 } -Session $VMSess #$feat = Invoke-Command { Get-WindowsFeature | Where-Object installed } -Session $VMSess $rdpTest = Invoke-Command { Get-ItemPropertyValue -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\' -Name fDenyTSConnections } -Session $VMSess $rsat = @( 'Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0', 'Rsat.BitLocker.Recovery.Tools~~~~0.0.1.0', 'Rsat.CertificateServices.Tools~~~~0.0.1.0', 'Rsat.DHCP.Tools~~~~0.0.1.0', 'Rsat.Dns.Tools~~~~0.0.1.0', 'Rsat.FailoverCluster.Management.Tools~~~~0.0.1.0', 'Rsat.FileServices.Tools~~~~0.0.1.0', 'Rsat.GroupPolicy.Management.Tools~~~~0.0.1.0', 'Rsat.IPAM.Client.Tools~~~~0.0.1.0', 'Rsat.ServerManager.Tools~~~~0.0.1.0' ) $pkg2 = Invoke-Command { $using:rsat | ForEach-Object { Get-WindowsCapability -Online -Name $_ } } -Session $cl $FireWallRules = $LabData.AllNodes.FirewallRuleNames $fw = Invoke-Command { Get-NetFirewallRule -Name $using:FireWallRules } -Session $VMSess | ForEach-Object -Begin { $tmp = @{} } -Process { $tmp.Add($_.Name, $_.Enabled) } -End { $tmp } } AfterAll { if ($VMSess) { $VMSess | Remove-PSSession } } It "[WIN10] Should Belong to the $Domain domain" { $sys.domain | Should -Be $Domain } It '[WIN10] Should Be running Windows 10 Enterprise' { $OS.caption | Should -BeLike '*Enterprise*' } It '[WIN10] Should have an IP address of 192.168.3.100' { $if.ipv4Address | Should -Be '192.168.3.100' } It '[WIN10] Should have firewall rule <_> enabled' -ForEach $FireWallRules { $fw[$_] | Should -Be $True } It '[WIN10] Should have a DNS server configuration of 192.168.3.10' { $dns.ServerAddresses -contains '192.168.3.10' | Should -Be $True } It '[WIN10] Should have RDP for admin access enabled' { $rdpTest | Should -Be 0 } It '[WIN10] Should Be able to resolve an internet address' { $resolve.name | Should -Be 'www.pluralsight.com' } It "[WIN10] Should have RSAT installed [$rsatStatus]" { $pkg2 | Where-Object { $_.state -ne 'installed' } | Should -Be $Null } } |