197 lines
8.9 KiB
PowerShell
197 lines
8.9 KiB
PowerShell
<#
|
|
.SYNOPSIS
|
|
Installs, configures, and secures the SNMP Service and components on a remote Windows Server.
|
|
It includes optional parameters for setting Agent Contact and Location details.
|
|
|
|
.DESCRIPTION
|
|
This script is idempotent. It installs the SNMP features, uses the RFC1156Agent key to set sysServices, sysContact, and sysLocation,
|
|
configures the Community String (Read Only), checks if the Allowed IP is already present before adding it to the Permitted Managers,
|
|
creates missing registry keys only if needed, and opens UDP 161 in the Windows Firewall.
|
|
|
|
.PARAMETER ComputerName
|
|
The name of the remote computer (Windows Server) where SNMP will be installed.
|
|
|
|
.PARAMETER CommunityString
|
|
The custom community string to be configured for the SNMP Service.
|
|
|
|
.PARAMETER AllowedIPOrHost
|
|
The IP address, IP range, or hostname allowed to query the SNMP Service.
|
|
This is used for both SNMP service configuration and the Firewall rule. Use "0.0.0.0" for any host.
|
|
|
|
.PARAMETER AgentContact
|
|
Optional. The contact person or email address for the SNMP agent (written to sysContact).
|
|
|
|
.PARAMETER AgentLocation
|
|
Optional. The physical location of the SNMP agent (written to sysLocation).
|
|
|
|
.EXAMPLE
|
|
.\Install-Configure-SNMP.ps1 -ComputerName "Server01" -CommunityString "MySecureString" -AllowedIPOrHost "192.168.1.10" -AgentContact "IT Operations" -AgentLocation "Server Room A"
|
|
|
|
.EXAMPLE
|
|
.\Install-Configure-SNMP.ps1 -ComputerName "TestServer" -CommunityString "PublicAccess" -AllowedIPOrHost "0.0.0.0"
|
|
#>
|
|
param(
|
|
[Parameter(Mandatory=$true)]
|
|
[string]$ComputerName,
|
|
|
|
[Parameter(Mandatory=$true)]
|
|
[string]$CommunityString,
|
|
|
|
[Parameter(Mandatory=$true)]
|
|
[string]$AllowedIPOrHost,
|
|
|
|
[Parameter(Mandatory=$false)]
|
|
[string]$AgentContact,
|
|
|
|
[Parameter(Mandatory=$false)]
|
|
[string]$AgentLocation
|
|
)
|
|
|
|
# Define the features to install and the firewall details
|
|
$SNMPFeatures = "SNMP-Service", "SNMP-WMI-Provider", "RSAT-SNMP"
|
|
$FirewallRuleName = "Allow-SNMP-Inbound-UDP161"
|
|
$SNMPPort = 161
|
|
$AgentServicesName = "sysServices"
|
|
$AgentServicesValue = 79
|
|
|
|
Write-Host "--- Starting SNMP Service installation, configuration, and firewall setup on $($ComputerName) ---"
|
|
|
|
try {
|
|
# 1. Install SNMP Service and WMI Provider (including RSAT-SNMP) remotely
|
|
Write-Host "1. Installing $($SNMPFeatures -join ', ') on $($ComputerName)..."
|
|
|
|
Invoke-Command -ComputerName $ComputerName -ScriptBlock {
|
|
param($Features)
|
|
# Install the features if not already present
|
|
$InstalledFeatures = Get-WindowsFeature $Features | Where-Object { $_.Installed -eq $true }
|
|
if ($InstalledFeatures.Count -ne $Features.Count) {
|
|
Write-Host "Installing features..."
|
|
$InstallationResult = Install-WindowsFeature -Name $Features -IncludeAllSubFeature -ErrorAction Stop
|
|
if (-not $InstallationResult.Success) {
|
|
throw "Feature installation failed. Details: $($InstallationResult | Out-String)"
|
|
}
|
|
} else {
|
|
Write-Host "SNMP features are already installed."
|
|
}
|
|
} -ArgumentList $SNMPFeatures -ErrorAction Stop
|
|
|
|
# 2. Configure SNMP Service remotely (Contact, Location, Community String, Allowed IPs, and Agent Services)
|
|
Write-Host "2. Configuring SNMP Service parameters on $($ComputerName)..."
|
|
|
|
Invoke-Command -ComputerName $ComputerName -ScriptBlock {
|
|
param($Community, $IPOrHost, $ServicesName, $ServicesValue, $Contact, $Location)
|
|
|
|
# Define Registry paths
|
|
$SNMPRegBase = "HKLM:\SYSTEM\CurrentControlSet\Services\SNMP\Parameters"
|
|
$RFC1156AgentRegKey = "$SNMPRegBase\RFC1156Agent"
|
|
$ValidCommunitiesRegKey = "$SNMPRegBase\ValidCommunities"
|
|
$PermittedManagersRegKey = "$SNMPRegBase\PermittedManagers"
|
|
|
|
# --- Ensure required registry keys exist recursively and create only if missing ---
|
|
Write-Host " -> Ensuring required registry keys exist..."
|
|
|
|
# Check and create the parent 'Parameters' key if it's missing (needed for subsequent checks)
|
|
if (-not (Test-Path $SNMPRegBase)) {
|
|
Write-Host " -> Creating base Parameters key: $SNMPRegBase"
|
|
New-Item -Path $SNMPRegBase -Type Directory -Force -ErrorAction Stop | Out-Null
|
|
}
|
|
|
|
# Array of subkeys to check and create
|
|
$SubKeysToCreate = @(
|
|
$RFC1156AgentRegKey,
|
|
$ValidCommunitiesRegKey,
|
|
$PermittedManagersRegKey
|
|
)
|
|
|
|
foreach ($KeyPath in $SubKeysToCreate) {
|
|
if (-not (Test-Path $KeyPath)) {
|
|
Write-Host " -> Creating missing subkey: $KeyPath"
|
|
New-Item -Path $KeyPath -Type Directory -ErrorAction Stop | Out-Null
|
|
}
|
|
}
|
|
|
|
# --- Configure Agent Contact (sysContact) ---
|
|
if (-not [string]::IsNullOrEmpty($Contact)) {
|
|
Write-Host " -> Setting Agent Contact (sysContact) to '$Contact'."
|
|
# Use Type STRING (RegSZ) for text fields
|
|
Set-ItemProperty -Path $RFC1156AgentRegKey -Name "sysContact" -Value $Contact -Type String -Force -ErrorAction Stop
|
|
} else {
|
|
Write-Host " -> Agent Contact parameter was empty, skipping sysContact configuration."
|
|
}
|
|
|
|
# --- Configure Agent Location (sysLocation) ---
|
|
if (-not [string]::IsNullOrEmpty($Location)) {
|
|
Write-Host " -> Setting Agent Location (sysLocation) to '$Location'."
|
|
# Use Type STRING (RegSZ) for text fields
|
|
Set-ItemProperty -Path $RFC1156AgentRegKey -Name "sysLocation" -Value $Location -Type String -Force -ErrorAction Stop
|
|
} else {
|
|
Write-Host " -> Agent Location parameter was empty, skipping sysLocation configuration."
|
|
}
|
|
|
|
# --- Community String Configuration ---
|
|
Write-Host " -> Setting Community String to '$Community' (Read Only, Value=4)."
|
|
Set-ItemProperty -Path $ValidCommunitiesRegKey -Name $Community -Value 4 -Type DWORD -Force -ErrorAction Stop
|
|
|
|
# --- Enable All Agent Services ---
|
|
Write-Host " -> Enabling all services under the SNMP Agent tab (Key: '$ServicesName', Value: $($ServicesValue))."
|
|
Set-ItemProperty -Path $RFC1156AgentRegKey -Name $ServicesName -Value $ServicesValue -Type DWORD -Force -ErrorAction Stop
|
|
|
|
# --- Allowed IP/Host Configuration (Idempotent Check) ---
|
|
Write-Host " -> Checking if host '$IPOrHost' is already in the Permitted Managers list..."
|
|
|
|
$ExistingManagers = Get-ItemProperty -Path $PermittedManagersRegKey | Select-Object -Property * -ExcludeProperty PS* | Out-String
|
|
|
|
if ($ExistingManagers -like "*$IPOrHost*") {
|
|
Write-Host " -> Host '$IPOrHost' already exists. Skipping addition."
|
|
} else {
|
|
$Index = 2
|
|
do {
|
|
$RegValue = Get-ItemProperty -Path $PermittedManagersRegKey -Name $Index -ErrorAction SilentlyContinue
|
|
if ($RegValue) { $Index++ }
|
|
} while ($RegValue)
|
|
|
|
Write-Host " -> Host '$IPOrHost' not found. Adding as index $Index."
|
|
Set-ItemProperty -Path $PermittedManagersRegKey -Name $Index -Value $IPOrHost -Type STRING -Force -ErrorAction Stop
|
|
}
|
|
|
|
} -ArgumentList $CommunityString, $AllowedIPOrHost, $AgentServicesName, $AgentServicesValue, $AgentContact, $AgentLocation -ErrorAction Stop
|
|
|
|
# 3. Configure Windows Firewall Rule (Idempotent: removes and re-creates)
|
|
Write-Host "3. Configuring Windows Firewall to allow UDP port $($SNMPPort) from $($AllowedIPOrHost) on $($ComputerName)..."
|
|
|
|
Invoke-Command -ComputerName $ComputerName -ScriptBlock {
|
|
param($RuleName, $Port, $IPOrHost)
|
|
|
|
# Remove existing rule if it exists (for clean updates)
|
|
if (Get-NetFirewallRule -DisplayName $RuleName -ErrorAction SilentlyContinue) {
|
|
Write-Host " -> Removing existing rule '$RuleName'."
|
|
Remove-NetFirewallRule -DisplayName $RuleName -Confirm:$false -ErrorAction SilentlyContinue
|
|
}
|
|
|
|
# Create the new firewall rule
|
|
Write-Host " -> Creating new inbound rule '$RuleName' for UDP $Port."
|
|
New-NetFirewallRule -DisplayName $RuleName `
|
|
-Direction Inbound `
|
|
-Action Allow `
|
|
-Protocol UDP `
|
|
-LocalPort $Port `
|
|
-RemoteAddress $IPOrHost `
|
|
-Profile Any `
|
|
-ErrorAction Stop
|
|
|
|
} -ArgumentList $FirewallRuleName, $SNMPPort, $AllowedIPOrHost -ErrorAction Stop
|
|
|
|
# 4. Restart SNMP Service
|
|
Write-Host "4. Restarting SNMP Service on $($ComputerName) to apply all changes (Configuration & Firewall)."
|
|
|
|
Invoke-Command -ComputerName $ComputerName -ScriptBlock {
|
|
Restart-Service -Name "SNMP" -ErrorAction Stop
|
|
} -ErrorAction Stop
|
|
|
|
Write-Host "--- SNMP installation, configuration, and firewall setup on $($ComputerName) is complete! ✅ ---"
|
|
|
|
}
|
|
catch {
|
|
Write-Error "An error occurred during execution on $($ComputerName). Error details: $($_.Exception.Message)"
|
|
exit 1
|
|
} |