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.