-
Notifications
You must be signed in to change notification settings - Fork 10
/
Test-Snmp.ps1
140 lines (117 loc) · 6.89 KB
/
Test-Snmp.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#region Main
function Test-Snmp {
<#
.SYNOPSIS
Connects to a local or remote computer and gets the status of the SNMP agent.
.DESCRIPTION
Designed as a healthtest to verify configuration and connectivity. Will return "true" for each non-result test. If a test listing, it is assumed to have not run, which may occur (for instance, if a system is not pingable, there's no point running a SNMP test).
.NOTES
Makes the following assumptions when checking the Windows SNMP config.
* Computer is pingable
* Computer has remote registry enabled
* Computer is domain joined
* Currently logged in credentials have administrative rights on the remote Computer
The UDP Port Test is unreliable, as it will return "true" if the port is filtered rather than simply closed.
.EXAMPLE
Test-Snmp -computername demo.snmplabs.com
#>
[CmdletBinding()]
param (
#The DNS Hostname or IP Address of the system you wish to test. You may specify an array for multiple devices. Defaults to "localhost" if not specified.
[Parameter(ValueFromPipeline)][String]$ComputerName = "localhost",
#SNMP Community to test with. Defaults to "public" if not specified
[String]$Community = "public",
#SNMP OID to validate SNMP GET functionality. Defaults to "1.3.6.1.2.1.1.3.0" (System.SysUptime.0) if not specified.
[string[]]$ObjectIdentifier = "1.3.6.1.2.1.1.3.0",
#UDP Port to use to perform SNMP queries. Defaults to 161 if not specified.
[Parameter(Mandatory=$False)]
[int]$UDPPort = 161,
#Check Microsoft SNMP config (only if SNMP tests fail). See Notes for Caveats
[Switch]$CheckWindowsConfig,
#Skip the ping check. Useful if the SNMP host is behind a firewall that blocks ICMP but SNMP is still available via UDP.
[Switch]$NoPing
)
process {
foreach ($Computer in $ComputerName) {
Write-VerboseProgress -Activity "Test-Snmp" -status "$Computer" -CurrentOperation "Initializing Scan"
#Create Array for Test Results and initialize all test variables for consistent objects
$SNMPTestResultProps = [ordered]@{}
$SNMPTestResultProps.ComputerName = $Computer
$SNMPTestResultProps.Ping = $null
$SNMPTestResultProps.SNMPGet = $null
$SNMPTestResultProps.ResultSNMPGet = $null
#Additional Properties for Windows Config check
if ($CheckWindowsConfig) {
$SNMPTestResultProps.RPCPort = $null
$SNMPTestResultProps.WMIModel = $null
$SNMPTestResultProps.ResultWMIModel = $null
$SNMPTestResultProps.Registry = $null
}
#Ping to see if system is online. Stop here if it isn't.
if (!$NoPing) {
Write-VerboseProgress -Activity "Test-Snmp" -status "$Computer" -CurrentOperation "Pinging $Computer"
try {
$SNMPTestResultProps.Ping = test-connection $Computer -count 2 -quiet -ErrorAction stop
if (!$SNMPTestResultProps.Ping) {throw "FAILED"}
}
catch {
$SNMPTestResultProps.Ping = $_.Exception.Message
return [PSCustomObject]$SNMPTestResultProps
}
}
#Check if we can get the OID (SNMP system uptime by default and all systems should support this, so this not working is considered a failure)
try {
Write-VerboseProgress -Activity "Test-Snmp" -status "$Computer" -CurrentOperation "Performing SNMPv2 Get Test to port $UDPPort for $ObjectIdentifier using community $Community"
$ResultSNMPGetRaw = Invoke-SnmpGet -ComputerName $Computer -Community $Community -ObjectIdentifier $ObjectIdentifier -UDPport $UDPPort -ErrorAction Stop
$ResultSNMPGet = $ResultSNMPGetRaw.data
if ($ResultSNMPGet -match "NoSuchInstance") {throw "OID Wasn't found on System"}
if (!$ResultSNMPGet) {throw "No Data Returned"}
$SNMPTestResultProps.SNMPGet = ($ResultSNMPGet -ne $null)
$SNMPTestResultProps.ResultSNMPGet = $ResultSNMPGet
}
catch {
$SNMPTestResultProps.SNMPGet = $_.Exception.Message
$SNMPTestResultProps.ResultSNMPGet = $false
}
#Optional Microsoft Tests. Only run if SNMP Get Failed to save time.
if ($CheckWindowsConfig -and ($SNMPTestResultProps.SNMPGet -ne $true)) {
#RPC Port Test. Registry test has a long timeout that's not easily configurable, this is a fast way to avoid that.
try {
Write-VerboseProgress -Activity "Test-Snmp" -status "$Computer" -CurrentOperation "Testing RPC Port"
#Uses Private Function Test-TCPPort as it's faster, cannot rely on test-netconnection as it's too new still.
$SNMPTestResultProps.RPCPort = Test-TCPPort -srv $Computer -InformationLevel Quiet
if (!$SNMPTestResultProps.RPCPort) {throw "FAILED"}
}
catch {
$SNMPTestResultProps.RPCPort = $_.Exception.Message
return [PSCustomObject]$SNMPTestResultProps
}
#Test WMI by fetching the Computer Model. Using the Job is an ugly workaround for Get-WMIObject's lack of a timeout.
try {
Write-VerboseProgress -Activity "Test-Snmp" -status "$Computer" -CurrentOperation "Fetching Computer Make/Model via WMI"
$WMIGetComputerSystemJob = get-wmiobject Win32_ComputerSystem -computername $Computer -asjob -ErrorAction stop | wait-job -timeout 3 | receive-job
}
catch {
$SNMPTestResultProps.RPCPort = $_.Exception.Message
return [PSCustomObject]$SNMPTestResultProps
}
#Registry Access Test
try {
Write-VerboseProgress -Activity "Test-Snmp" -status "$Computer" -CurrentOperation "Attempting Registry Connection"
$ErrorActionPreference = "Stop"
$RemoteRegistry = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine",$Computer)
$ErrorActionPreference = "Continue"
$SNMPTestResultProps.Registry = ($RemoteRegistry -is [Microsoft.Win32.RegistryKey])
if (!$SNMPTestResultProps.Registry) {throw "FAILED"}
}
catch {
$SNMPTestResultProps.Registry = $_.Exception.Message
return [PSCustomObject]$SNMPTestResultProps
}
}
#Return Full results if it worked
[PSCustomObject]$SNMPTestResultProps
}
}
} #Test-Snmp
#endregion