Last active
August 17, 2022 12:37
-
-
Save JustinGrote/a1a41ea4f88308dcf687 to your computer and use it in GitHub Desktop.
Manageable Device Pester Tests
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#requires -module Pester,PoshRSJob,SharpSNMP | |
<# | |
.SYNOPSIS | |
A set of Pester Tests for determining if a device is remotely manageable. | |
#> | |
#region Params | |
param ( | |
$ComputerName = 'localhost', | |
$SNMPCommunity = 'public', | |
$SNMPPort = '161', | |
$Timeout = 10, | |
$ShowTestOutputs = $true | |
) | |
#endregion Params | |
#region Includes | |
function Test-TCPPort { | |
<# | |
.SYNOPSIS | |
Does a TCP connection on specified port (135 by default) | |
.LINK | |
http://poshcode.org/85 | |
#> | |
[CmdletBinding()] | |
Param( | |
[string]$ComputerName, | |
[int]$Port=135, | |
[int]$Timeout=3 | |
) | |
$ErrorActionPreference = "SilentlyContinue" | |
# Create TCP Client | |
$tcpclient = new-Object system.Net.Sockets.TcpClient | |
# Tell TCP Client to connect to machine on Port | |
$iar = $tcpclient.BeginConnect($ComputerName,$Port,$null,$null) | |
# Set the wait time | |
$wait = $iar.AsyncWaitHandle.WaitOne($Timeout*1000,$false) | |
# Check to see if the connection is done | |
if(!$wait) | |
{ | |
# Close the connection and report timeout | |
$tcpclient.Close() | |
if($verbose){Write-verbose "Connection Timeout"} | |
Return $false | |
} | |
else | |
{ | |
# Close the connection and report the error if there is one | |
$error.Clear() | |
$tcpclient.EndConnect($iar) | out-Null | |
if(!$?){if($verbose){write-verbose $error[0]};$failed = $true} | |
$tcpclient.Close() | |
} | |
# Return $true if connection Establish else $False | |
if($failed){return $false}else{return $true} | |
} #Test-TCPPort | |
function Get-ComputerVirtualStatus { | |
<# | |
.SYNOPSIS | |
Validate if a remote server is virtual or physical | |
.DESCRIPTION | |
Uses wmi (along with an optional credential) to determine if a remote computers, or list of remote computers are virtual. | |
If found to be virtual, a best guess effort is done on which type of virtual platform it is running on. | |
.PARAMETER ComputerName | |
Computer or IP address of machine | |
.PARAMETER Credential | |
Provide an alternate credential | |
.EXAMPLE | |
$Credential = Get-Credential | |
Get-RemoteServerVirtualStatus 'Server1','Server2' -Credential $Credential | select ComputerName,IsVirtual,VirtualType | ft | |
Description: | |
------------------ | |
Using an alternate credential, determine if server1 and server2 are virtual. Return the results along with the type of virtual machine it might be. | |
.EXAMPLE | |
(Get-RemoteServerVirtualStatus server1).IsVirtual | |
Description: | |
------------------ | |
Determine if server1 is virtual and returns either true or false. | |
.LINK | |
http://www.the-little-things.net/ | |
.LINK | |
http://nl.linkedin.com/in/zloeber | |
.NOTES | |
Name : Get-RemoteServerVirtualStatus | |
Version : 1.1.0 12/09/2014 | |
- Removed prompt for credential | |
- Refactored some of the code a bit. | |
1.0.0 07/27/2013 | |
- First release | |
Author : Zachary Loeber | |
#> | |
[cmdletBinding(SupportsShouldProcess = $true)] | |
param( | |
[parameter(Position=0, ValueFromPipeline=$true, HelpMessage="Computer or IP address of machine to test")] | |
[string[]]$ComputerName = $env:COMPUTERNAME, | |
[parameter(HelpMessage="Pass an alternate credential")] | |
[System.Management.Automation.PSCredential]$Credential = $null | |
) | |
begin { | |
$WMISplat = @{} | |
if ($Credential -ne $null) { | |
$WMISplat.Credential = $Credential | |
} | |
$results = @() | |
$computernames = @() | |
} | |
process { | |
$computernames += $ComputerName | |
} | |
end { | |
foreach($computer in $computernames) { | |
$WMISplat.ComputerName = $computer | |
try { | |
$wmibios = Get-WmiObject Win32_BIOS @WMISplat -ErrorAction Stop | Select-Object version,serialnumber | |
$wmisystem = Get-WmiObject Win32_ComputerSystem @WMISplat -ErrorAction Stop | Select-Object model,manufacturer | |
$ResultProps = @{ | |
ComputerName = $computer | |
BIOSVersion = $wmibios.Version | |
SerialNumber = $wmibios.serialnumber | |
Manufacturer = $wmisystem.manufacturer | |
Model = $wmisystem.model | |
IsVirtual = $false | |
VirtualType = $null | |
} | |
if ($wmibios.SerialNumber -like "*VMware*") { | |
$ResultProps.IsVirtual = $true | |
$ResultProps.VirtualType = "Virtual - VMWare" | |
} | |
else { | |
switch -wildcard ($wmibios.Version) { | |
'VIRTUAL' { | |
$ResultProps.IsVirtual = $true | |
$ResultProps.VirtualType = "Virtual - Hyper-V" | |
} | |
'A M I' { | |
$ResultProps.IsVirtual = $true | |
$ResultProps.VirtualType = "Virtual - Virtual PC" | |
} | |
'*Xen*' { | |
$ResultProps.IsVirtual = $true | |
$ResultProps.VirtualType = "Virtual - Xen" | |
} | |
} | |
} | |
if (-not $ResultProps.IsVirtual) { | |
if (($wmisystem.manufacturer -like "*Microsoft*") -and ($wmisystem.model -notmatch "Surface")) | |
{ | |
$ResultProps.IsVirtual = $true | |
$ResultProps.VirtualType = "Virtual - Hyper-V" | |
} | |
elseif ($wmisystem.manufacturer -like "*VMWare*") | |
{ | |
$ResultProps.IsVirtual = $true | |
$ResultProps.VirtualType = "Virtual - VMWare" | |
} | |
elseif ($wmisystem.model -like "*Virtual*") { | |
$ResultProps.IsVirtual = $true | |
$ResultProps.VirtualType = "Unknown Virtual Machine" | |
} | |
} | |
$results += New-Object PsObject -Property $ResultProps | |
} | |
catch { | |
Throw "Cannot connect to $computer" | |
} | |
} | |
return $results | |
} | |
} #Get-ComputerVirtualStatus | |
#endregion | |
#region Main | |
Describe "Host Networking" { | |
It "Responds to ICMP Ping" { | |
Test-Connection -Quiet -Count 2 -ComputerName $ComputerName | Should Be $true | |
} | |
} | |
Describe "Windows Remote Management" { | |
It "Responds to RPC TCP Port within $Timeout seconds" { | |
Test-TCPPort -ComputerName $ComputerName -Timeout $Timeout -Port 135 | Should Be $true | |
} | |
It "Responds to RDP TCP Port within $Timeout seconds" { | |
Test-TCPPort -ComputerName $ComputerName -Timeout $Timeout -Port 3389 | Should Be $true | |
} | |
It "Returns a WMI Computer Manufacturer and Model within $Timeout seconds" { | |
$Script:MakeModelResult = Start-Job {Get-WMIObject -ComputerName $Using:ComputerName Win32_ComputerSystem} | | |
Wait-Job -Timeout $Timeout | | |
Receive-Job | |
$MakeModelResult.Manufacturer | Should Not BeNullOrEmpty | |
$MakeModelResult.Model | Should Not BeNullOrEmpty | |
} | |
#Show Make and Model Output if enabled and present | |
if ($ShowTestOutputs) { | |
It -skip:(!$MakeModelResult) " OUTPUT: WMI Computer Manufacturer: $($MakeModelResult.Manufacturer)" { | |
#Workaround to keep Pester from marking the test as "Pending" | |
$null = $null | |
} | |
It -skip:(!$MakeModelResult) " OUTPUT: WMI Computer Model: $($MakeModelResult.Model)" { | |
#Workaround to keep Pester from marking the test as "Pending" | |
$null = $null | |
} | |
} | |
It "Reports whether it is a physical or virtual machine" { | |
$Script:ComputerIsVirtual = (Get-ComputerVirtualStatus $ComputerName).IsVirtual | |
$ComputerIsVirtual | Should Not BeNullOrEmpty | |
} | |
if ($ShowTestOutputs) { | |
It -skip:(!$ComputerIsVirtual) " OUTPUT: Is a Virtual Machine?: $ComputerIsVirtual" { | |
#Workaround to keep Pester from marking the test as "Pending" | |
$null = $null | |
} | |
} | |
} | |
Describe "Host SNMP" { | |
It "Responds to an SNMPv2 Get Query for System.SysUptime.0 within $Timeout seconds" { | |
Set-Variable SNMPUptimeOID -option ReadOnly -value '1.3.6.1.2.1.1.3.0' | |
$Script:SNMPUptimeResult = (Invoke-SnmpGet -ComputerName $ComputerName -Community $SNMPCommunity -UDPport $SNMPPort -ObjectIdentifier $SNMPUptimeOID -Timeout ($Timeout*1000)).data | |
$SNMPUptimeResult | Should Not BeNullOrEmpty | |
} | |
It "Reports at least one MIB-2 Interface" { | |
Set-Variable SNMPIfCountOID -option ReadOnly -value '1.3.6.1.2.1.2' | |
$Script:SNMPIfCountResult = (Invoke-SnmpGet -ComputerName $ComputerName -Community $SNMPCommunity -UDPport $SNMPPort -ObjectIdentifier $SNMPUptimeOID -Timeout ($Timeout*1000)).data | |
$SNMPIFCountResult | Should Not BeNullOrEmpty | |
} | |
It "Reports Host Resources MIB CPU Utilization" { | |
Set-Variable SNMPHostResCPUOID -option ReadOnly -value '.1.3.6.1.2.1.25.3.3.1.2' | |
$Script:SNMPHostResCPUResult = (Invoke-SnmpGet -ComputerName $ComputerName -Community $SNMPCommunity -UDPport $SNMPPort -ObjectIdentifier $SNMPUptimeOID -Timeout ($Timeout*1000)).data | |
$SNMPHostResCPUResult | Should Not BeNullOrEmpty | |
} | |
} | |
Describe "Windows SNMP Service" { | |
It "Windows SNMP Service is Installed" { | |
$WMIResult = Start-Job {Get-WMIObject -Computername $Using:ComputerName Win32_Service -Filter "Name='snmp'"} | | |
wait-job -timeout $Timeout | | |
Receive-Job | | |
Should Not BeNullOrEmpty | |
} | |
It "Windows SNMP Service is Running" { | |
$WMIResult = Start-Job {Get-WMIObject -Computername $Using:ComputerName Win32_Service -Filter "Name='snmp'"} | | |
wait-job -timeout $Timeout | | |
Receive-Job | |
$WmiResult.State | Should Be "Running" | |
write-verbose "Host SNMP Windows Service State: $($WmiResult.State)" | |
} | |
} | |
#endregion Main |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#Test-ManageableDevice.ps1 | |
param ( | |
#List of Computers to Test | |
[String[]]$ComputerName, | |
[String[]]$TestName | |
) | |
foreach ($ComputerNameItem in $ComputerName) { | |
$ManageDeviceTestParams = @{ | |
ComputerName = $ComputerNameItem | |
SNMPCommunity = 'public' | |
SNMPPort = '161' | |
Timeout = 10 | |
ShowTestOutputs = $true | |
} | |
Invoke-Pester -TestName $TestName -Script @{ | |
Path = "$(Split-path $MyInvocation.InvocationName -Parent)" | |
Parameters = $ManageDeviceTestParams | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment