Monday, April 2, 2012

Automatically Install SNMP with PowerShell and ConfigMgr

For various reasons I found that I need to deploy SNMP Services; the SNMP Service AND WMI provider to many servers in a more efficient manner. That mean installing to server 2003, 2008, and 2008R2 preferably with a single method. Whatever I came up with need to work even if some or none of the components were installed. I also wanted to configure the settings (covered in a different post). The following is what I came up with after quite a bit of effort. Hopefully this will save someone undo hardship!

I found this bit of PowerShell that will install SNMP in about 10 seconds or less.
Source: http://poshcode.org/2066

The basics

If you're just testing to make sure it works this is the core of the script....

   Import-Module ServerManager
   Add-WindowsFeature SNMP-Services


The Script's Shortcomings



So after tinkering with this code for the better part of 4-5 days straight. I came to a few conclusions.

  1. The script doesn't factor in server 2003 vs. 2008 OR PowerShell v1 vs. v2. The "ServerManager" module is only available in PowerShell v2 and only works on Server 2008R2. Therefore, I added a check to see if the ServerManager module was even available. This covers both of the aforementioned prerequisites.
  2. There is no check for whether or not some of the SNMP functionality is installed. i.e. the service but not the WMI provider (such was the case in my environment). It blindly checks for just SNMP Services as a whole. I added checks for SNMP Services, Service, and WMI Provider individually.
  3. There can be multiple blockers to implementing full automation.
    1. PowerShell Execution Policies for remote signing.
    2. Missing DLLs

Taking it to the Next Level

The rest of this post will be a comprehensive guide to fully automating this process. This includes the necessary group policies, shared DLL repositories, Configuration Manager packages, and more.

Why Not MDT?
Now if you're thinking, "why not just use MDT?!?" I'll tell you why...MDT doesn't support SNMP feature install to pre-2008R2 either since it ties into the ServerManager module as well (as I understand it). Though it does a handful of others including DNS and DHCP. Anyway, my logic was to have all server components managed with a single method vs. PowerShell sometimes and MDT others. That being said I hope to follow this up with an MDT how to for the same thing.

The Steps


  1. Extract i386 directory from Windows Server 2003 ISO/DVD to a share (preferably on site server if using ConfigMgr)
  2. Create Group Policies 
    • Set DLL Paths: Group Policy Preferences to modify the registry of targeted Windows Servers. Populate the install path for i386 files (default would typically be CD/ISO drive from initial install)
    • Configure PowerShell Execution Policy (or sign your scripts, both in posts to follow)
  3. Create an answer file for sysocmgr since that's the only way to automate pre-2008R2
  4. Create package containing the .PS1 script and .TXT answer file
When you see it as 4 steps it seems a little less intimidating. At least it seems that way to me :)


i386 DLLs

One of the first things I ran into with a working script was Server 2003 looking for the necessary DLLs


snmpcl.dll
snmpincl.dll
snmpsmir.dll
snmpthrd.dll
smi2smir.exe
snmpreg.mof
snmpsmir.mof
snmpstup.dll
smierrsm.dll
smierrsy.dll
smimsgif.dll

I decided to tackle this by placing the entire directory on a network share and update the default sourcepatc variables to that share. I figured this way future component installations beyond SNMP can reference the same path.

GPO

Neither of the following group policies are necessarily required for ALL environments. I'll explain...

DLL path via Group Policy Preference: Only required for pre-2008R2 deployments. If you're dealing with only 2008R2 servers you can probably skip this one for now since the ServerManager cmdlet will kick in.


HKLM\software\microsoft\windows\CurrentVersion\Setup

REG_SZ: SourcePath 
VALUE: <i386 share>

HKLM\software\microsoft\windows\CurrentVersion\Setup 
REG_SZ: ServicePackSourcePath
VALUE: <i386 share>


Configure PowerShell Execution Policy = Unrestricted: I believe this is the default for Windows Server so unless you've explicitly enabled remote signing via some other GPO or other method you may be able to skip this as well.


You can check this on any server by typing the following command at a shell prompt

   Get-ExecutionPolicy

SYSOCMGR and Answer File

There are lots of great resources for using SYSOCMGR so I won't belabor the point. Here's the command and the associated answer file. Just drop the answer in a text file. The rest is in my script. This execution correctly will ride on the correct placement of the source files and registry settings.

sysocmgr /i:%WINDIR%\inf\sysoc.inf /u:<SNMP ANSWER FILE>.txt /r /x /q

Answer File

;SetupMgrTag
[NetOptionalComponents]
SNMP=1
wbemsnmp=1
[SNMP]
Any_Host=YES

The Script


This is where all of the magic happens.




#Powershell Script To Install SNMP Services (SNMP Service, SNMP Service, SNMP WMI Provider)


#--------------------NON-SERVER 2008R2-----------------------

if ((get-module -ListAvailable ServerManager) -eq $Null)

{
write-output "Installing SNMP Components for non-Server2008R2 System"

sysocmgr /i:%WINDIR%\inf\sysoc.inf /u:<SNMP ANSWER FILE>.txt /r /x /q

exit
}


#--------------------SERVER 2008R2---------------------------


#Import ServerManger Module (adds Add-WindowsFeature cmdlet)
Import-Module ServerManager

#Check If SNMP Services Are Already Installed
$checkSNMPServices = Get-WindowsFeature | Where-Object {$_.Name -eq "SNMP-Services"}

If ($checkSNMPServices.Installed -eq "True")
{
    write-output "SNMP Services were found on this system. Checking if sub-components are installed."
   
    #Check If SNMP Service is Installed (note: "SNMP Service" not "Services")
    $checkSNMPService = Get-WindowsFeature | Where-Object {$_.Name -eq "SNMP-Service"}
    If ($checkSNMPService.Installed -ne "True"){
        #Install/Enable SNMP Service
        Write-output "SNMP Service is not currently installed: Installing"
        Add-WindowsFeature SNMP-Services | Out-Null
    }
   
    Else {Write-Output "SNMP Service Not Required"}
   
    #Check If SNMP-WMI-Provider is Installed
    $checkWMIProvider = Get-WindowsFeature | Where-Object {$_.Name -eq "SNMP-WMI-Provider"}
    If ($checkWMIProvider.Installed -ne "True"){
        #Install/Enable SNMP Service
        Write-output "SNMP WMI Provider is not currently installed: Installing"
        Add-WindowsFeature SNMP-Services | Out-Null
    }
    Else {Write-Output "SNMP WMI Provider Not Required"}
}

else
{
    write-output "No SNMP Services were found installed on this system. Installing SNMP and sub-components"
   
    #Install/Enable SNMP Services
    Add-WindowsFeature SNMP-Services | Out-Null
}





Automating the Push with ConfigMgr

So far I haven't been able to get this to work. I suspected it was an issues with the execution policy or UAC (hence the GPO for execution policy). Haven't been able to nail down the culprit yet. However, running the script is still faster. Here's what I was trying as my command line. I would love to hear from someone if they have success deploying the script through SCCM. I'll keep working on it.


Content 
InstallSNMP.PS1
SNMP-sysocmgr-answer.txt

Command
powershell.exe -WindowStyle hidden -file InstallSNMPComponents.ps1



Final Notes
I've read in a few spots that you do not want to use SYSOCMGR to install Windows components on a SQL Server because of how it stops services. Fortunately, I read this before trying it so I haven't done so myself. Just passing along the warning.


Feel free to drop me a note if you have questions about this process. I realize when thinking about the entirety it can be a bit overwhelming. Happy to help answer what I can.

-Shep

7 comments:

  1. or use Solarwinds "SNMP Enabler".

    ReplyDelete
    Replies
    1. Good tool. Thanks for pointing that out. I'd like to point out a few things. The overall objective was to use ConfigMgr for the deployment as a standing advertisement (still working on that). You could certainly export your list of systems from ConfigMgr and import into the SolarWinds tool. Also, this PowerShell method could be used to enable ANY Windows feature. SNMP just happened to be what I was working on at the time. Thanks again!

      Delete
    2. The problem with Solarwinds "SNMP Enabler" is that it only does Read Only community strings, not Read Write.

      Delete
    3. True, but I believe once you get the features enabled you can just use group policy to enforce strings and trap servers. Under Computer\Policies\Admin Templates\Network\SNMP. This, to me, would be the preferred method anyway.

      Delete
  2. Hey Shep, you can actually shorten up the 2008 section, while adding the ability to customize which features should be installed; in case you only wanted the base snmp-service installed for example.

    This will initially search for the windows features based on what is not installed, and compare to a list of items. Also with the changes, this will work on 2012. (In 2012 the feature name changes to just SNMP-Service)


    $snmpFeatures = @("SNMP-Service", "SNMP-WMI-Provider")
    #Import ServerManger Module (adds Add-WindowsFeature cmdlet)
    Import-Module ServerManager

    #Check If SNMP Services Are Already Installed
    $SNMPServices = Get-WindowsFeature | Where-Object {($_.Name -like "SNMP-*") -and $_.Installed -match $false}
    if ($SNMPServices) {
    foreach ($service in $SNMPServices) {
    if (($snmpFeatures -contains $service.name) -and ($service.installed -eq $false)) {
    Write-Output "Installing $($service.name)"
    Add-WindowsFeature $service.name | Out-Null
    }
    }
    }
    else {
    Write-Output "All SNMP Services are already installed"
    }

    ReplyDelete
    Replies
    1. HI Alan,
      Could you help how to configure the community stringg and SNMP server IP using Powershell for Win 2012 OS.
      Also if we use the above script will start the SNMP service also automatically?
      Thanks for the help in advance!!

      Delete
  3. Try using group policy preferences to set the startup type and start the service.

    ReplyDelete