Search This Blog

Tuesday 4 June 2013

Using SCOM as a Basic Configuration Audit System – Part 2


As of 01/05/2017, this blog will not be updated or maintained

The first step for our compliance management pack is to develop the core checking script. This is not to say that this must be the approach for every MP, probably a better start would be the health model, nevertheless I want to immediately check if there’s any show stopper in the core stuff so I will address the health model in the following post.

To build the script we need to keep in mind that:

  • The output will be used to assess compliance on one side and to return data that can be used in reporting and in alerts to show what’s going on.
  • The script must be generic enough to work across different OS versions, this is why we’re using vbscript
  • The script will be targeted to a specific baseline
  • The patches list must not be hard coded since the whole list can change between OS versions and can be adjusted to address specific needs (via overrides)
  • The script will need to check for proper OS version, proper Windows Scripting Host version and proper patches

Given these requirements the script will take in input:

  • Desired OS version (for the given baseline, for example we can set that for Windows 2008 the minimum service pack supported is service pack 2)
  • Comma delimited list of required patches (IGNORE to skip the check)
  • Required Windows Script Host version (typically at least 5.7, IGNORE to skip the check)

The script will return a property bag with the following properties for generic assessment:

  • OS compliance
  • Patches compliance
  • WSH compliance

And the following properties for descriptive purposes:

  • OS version
  • WSH version
  • One entry for each patch listed telling if the patch is present or not
  • A description to be used in alerting with the reason for the missing compliance

The script logic is pretty simple:

  • Load all the required patches into a dictionary, the dictionary will tell if the patch is present or not and will be the base for building the patches part of the returned property bag
  • Check for OS version using Win32_OperatingSystem wmi class
  • Check for windows scripting host version, id the parameter is set to IGNORE then it is assumed wsh is compliant
  • Check for the presence of the required patches using the Win32_QuickFixEngineering wmi class. As stated in the comments, I will first check for an exact match and if not successful I will check for patches version using the – vb postfix
  • Finally using the results gathered the script builds the property bag and a descriptive property to be used in alerting

!Note! The following code will miss all the error checking stuff. Before you put anything in production I strongly suggest a strong parameters checking and some WMI error management. I left the error checking code out of the picture to make the script shorter and more readable.


Option Explicit
SetLocale ("en-us")

'Globals
Dim g_API, g_oXML
Dim g_StdErr
Dim P_TraceLevel, P_OSVer, P_QFEList, P_WSHVersion

'On Error Resume Next

Dim dtStart, oArgs
Dim dicQFEs, qfe, oQFEs
Dim i, oWMI, oWMIOS, OSVersion, Keys
Dim oBag, bOSCompliance, os, bQFECompliance, bWshCompliance

      dtStart = Now

    Globals

    Set oArgs = WScript.Arguments


    P_OSVer = oArgs(0)
    if UCASE(TRIM(oArgs(1)))="IGNORE" Then
        P_QFEList = Split("", ",")
    else
        P_QFEList = Split(oArgs(1),",")
    end if
    P_WSHVersion = oArgs(2)
    Set dicQFEs = CreateObject("Scripting.Dictionary")
    dicQFEs.CompareMode=vbTextCompare

    for I=0 to ubound(P_QFEList)
        dicQFEs.Add P_QFEList(i), false
    next

    'Now get the info we need via WMI
    Set oWMI = GetObject("winmgmts:\\.\root\cimv2") 
    Set oWMIOS = oWMI.ExecQuery("Select Version from Win32_OperatingSystem") 
    for each os in oWMIOS
        OSVersion = os.Version
    next
    bOSCompliance = (OSVersion >= P_OSVer)
    bWshCompliance = (WScript.Version >= P_WSHVersion or UCASE(P_WSHVersion)="IGNORE")
    Set oQFEs = oWMI.ExecQuery("Select * from Win32_QuickFixEngineering")
    

    for each qfe in oQFEs
    'sadly I cannot use an exact match to take into account the KB123456-v? fix naming
        if (dicQFEs.Exists(qfe.HotFixID)) Then
            dicQFEs(qfe.HotFixID) = true
        else
    'if I have not an exact match then check for patch versioning
          keys = dicQFEs.Keys
          for I=0 to dicQFEs.count -1
            if UCASE(keys(I) & "-v") = UCASE(Left(qfe.HotFixID, Len(keys(I)&"-v"))) then
              dicQFEs(keys(I)) = true
              exit for
            end if
          next        
        end if
    next


    'Now prepare the data to return
    Dim sMessage
        If Not bOSCompliance Then
            sMessage = sMessage & "OS is not compliant required version: " & P_OSVer & " Detected Version: " & OSVersion & vbCrLf
        end if
        If Not bWshCompliance Then
            sMessage = sMessage & "WSH is not compliant required version: " & P_WSHVersion & " Detected Version: " & WScript.Version & vbCrLf
        end if
        Set oBag = g_API.CreateTypedPropertyBag(StateDataType)
        call oBag.AddValue("OSVersion", OSVersion)
        call oBag.AddValue("OSCompliant", bOSCompliance)
        bQFECompliance = True
        for each qfe in dicQFEs.Keys
            if false = dicQFEs(qfe) Then 
                bQFECompliance = false
                sMessage = sMessage & qfe & " is missing" & vbCrLf
            end if
            call oBag.AddValue(qfe, dicQFEs(qfe))            
        next
        call oBag.AddValue("QFECompliant", bQFECompliance)
        call oBag.AddValue("WSHCompliant", bWSHCompliance)
        call oBag.AddValue("Message", sMessage)
        'finally resturn the property bag
        g_API.AddItem oBag    
        Call g_API.ReturnItems


    
    ClearGlobals


'**********************************************
'**** HELPER FUNCTIONS SCOM sempre necessarie
'**********************************************

Sub Globals
    P_TraceLevel = TRACE_VERBOSE
    Set g_API = CreateObject("MOM.ScriptAPI")
    Set g_oXML = CreateObject("MSXML.DOMDocument")  
    Set g_StdErr = WScript.StdErr
end Sub


Sub ClearGlobals
    Set g_API = Nothing
    Set g_oXML = Nothing
End Sub

Hope that this post was helpful.

No comments:

Post a Comment

Note: only a member of this blog may post a comment.