<WriteActionModuleType ID="SMS_2003_Monitor_SMS_Status_Messages" Accessibility="Internal" Comment="{D0461B85-2AB1-4A6C-9B81-F73DEBA3AD4E}">
<Configuration>
<IncludeSchemaTypes>
<SchemaType>MomBackwardCompatibility!System.Mom.BackwardCompatibility.AlertGenerationSchema</SchemaType>
</IncludeSchemaTypes>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="AlertGeneration" type="AlertGenerationType"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="InvokerType" type="xsd:integer"/>
</Configuration>
<ModuleImplementation>
<Composite>
<MemberModules>
<WriteAction ID="RunScriptAction" TypeID="MomBackwardCompatibility!System.Mom.BackwardCompatibility.ScriptResponse">
<AlertGeneration>$Config/AlertGeneration$</AlertGeneration>
<InvokerType>$Config/InvokerType$</InvokerType>
<Body><Script>
'*******************************************************************************
' Script Name - SMS 2003 Monitor SMS Status Messages
'
' Purpose - Monitor specific SMS status messages and raise an event with an
' event ID that corresponds to the SMS status message ID.
'
' The following additional events can be raised:
'
' 1100 - An event used only for debugging or tracing.
' 1101 - Script executed successfully.
' 1102 - An error occurred in executing this script.
' 1105 - Accessed denied due to connection failure or permissions.
'
' Assumptions - This script will run on a system with the SMS SQL Monitor service
' installed. The system must therefore be an SMS Site Database
' Server.
'
' This script does not support agentless mode and will silently
' terminate. This is because of performance reasons and that it
' must proxying on behalf of computers other than the local
' computer it is running on.
'
' The agent will be enabled for proxying for other computers.
'
' Parameters - None
'
' Change Hist - Date Version Description
' -------- --------------- -----------
' 08/27/03 02.50.0102.0000 Added Change History and Patch
' Management messages.
' 09/09/03 02.50.0115.0000 Added Site Backup messages.
' 03/17/04 02.50.0169.0000 Added check for agentless mode.
' 05/17/04 05.0.2700.0000 Added event proxying.
' 09/08/04 05.0.2751.0000 Change to query the SMS Site DB
' directly and not through the SMS WMI
' Provider. Also improved filtering
' on the status message query.
' 10/01/04 05.0.2751.0000 Added status message
' SRVMSG_BACKUP_ERROR_FILESYSTEM_TASK_
' FAILED
' 03/11/05 05.0.2753.0000 Added "Set DATEFORMAT mdy" query
' before querying for SMS status
' messages with a three day filter.
' This resolves previous problem with
' querying on non-english systems.
' 02/19/07 05.0.3132.0000 Added calls to oSQLServer.Disconnect
' in Sub ProcessStatusMessages() to
' fix SQL DMO handle leak.
'
' (c) Copyright 2007, Microsoft Corp., All Rights Reserved
'*******************************************************************************
Dim g_oUtil ' Utility class for MOM events, logging and registry access.
Dim g_oDictionary ' Stores varset data. Note, only string data can be stored.
Sub Main()
Dim strError
On Error Resume Next
LogMessage DBG_TRACE, ScriptContext.Name & " script starting at local time: " & CStr(Time)
'This script does not support agentless monitoring.
'==================================================
If ScriptContext.IsTargetAgentless Then
LogMessage DBG_TRACE, "No action taken; agentless monitoring is not supported."
LogMessage DBG_TRACE, ScriptContext.Name & " script completed at local time: " & CStr(Time)
Exit Sub
End If
'Initialize utility object and set tracing leve for it.
'======================================================
Set g_oUtil = new Util
If IsEmpty(g_oUtil) Then
LogMessage DBG_TRACE, "Failed to instantiate Util object."
ScriptError "instantiate Util object."
LogMessage DBG_TRACE, ScriptContext.Name & " script completed at local time: " & CStr(Time)
Exit Sub
End If
g_oUtil.SetDebugLevel(g_oUtil.DBG_TRACE)
'Initialize the persistent var set this script uses.
'====================================================
OpenVarSet
If 0 <> Err.number Then
strError = GetErrorString(Err)
LogMessage DBG_ERROR, "Failed to load script variables." & strError
ScriptError "load script variables." & strError
Set g_oUtil = Nothing
LogMessage DBG_TRACE, ScriptContext.Name & " script completed at local time: " & CStr(Time)
Exit Sub
End If
'Process status messages found in the SQL SMS Site Databases on
'this machine.
'==============================================================
ProcessStatusMessages
If 0 <> Err.number Then
strError = GetErrorString(Err)
LogMessage DBG_ERROR, "Failed to process SMS status messages." & strError
ScriptError "process SMS status messages." & strError
End If
'Persist the var set this script uses.
'=====================================
SaveVarSet
If 0 <> Err.number Then
strError = GetErrorString(Err)
LogMessage DBG_ERROR, "Failed to save script variables." & strError
ScriptError "save script variables." & strError
End If
Set g_oUtil = Nothing
LogMessage DBG_TRACE, ScriptContext.Name & " script completed at local time: " & CStr(Time)
End Sub
'******************************************************************************
' Name: ProcessStatusMessages
'
' Purpose: Process status messages found in the SQL SMS site databases on
' this computer.
'
' Parameters: None
'
' Returns: Nothing
'
Sub ProcessStatusMessages()
Dim oSQLServer
Dim strDBName
Dim strComputer
Dim strSiteCode
Dim strSiteServer
Dim intRow
Dim oResults
On Error Resume Next
'Get the name of the local machine.
'==================================
strComputer = ScriptContext.TargetComputer
'Open a connection to the default SQL instance using the SQLDMO.
'===============================================================
Set oSQLServer = CreateObject("SQLDMO.SQLServer")
If Err Then
LogMessage DBG_ERROR, "Failed to create a SQLDMO.SQLServer object."
Set oSQLServer = Nothing
Exit Sub
End if
oSQLServer.LoginSecure = True 'use Windows Authentication Mode
oSQLServer.Connect strComputer
If Err Then
LogMessage DBG_ERROR, "Failed to open a connection using SQLDMO.SQLServer to '" & strComputer & "'."
oSQLServer.Disconnect
Set oSQLServer = Nothing
Exit Sub
End if
'Get a collection of all databases in the default SQL instance.
'==============================================================
Set oResults = oSQLServer.ExecuteWithResults("sp_databases")
If Err Then
LogMessage DBG_ERROR, "Failed to get a list of all databases in the default SQL instance."
oSQLServer.Disconnect
Set oSQLServer = Nothing
Exit Sub
End if
'Check each database to see if it is an SMS Site Database. If it is,
'it will be associated with an SMS Site and therefore have an SMS Site
'Code and Site Server. Verify that the database is active for that
'site before processing status messages in it.
'=====================================================================
If Err Then
LogMessage DBG_TRACE, "'" & strDBName & "' is not an SMS site database."
Err.Clear
Else
LogMessage DBG_TRACE, "'" & strDBName & "' is an SMS site database."
LogMessage DBG_TRACE, "Checking if this database is active in site '" & _
strSiteCode & "' for site server '" & strSiteServer & "'."
If IsSiteDatabaseActive(strComputer, strSiteCode, strSiteServer) Then
LogMessage DBG_TRACE, "The database is active."
LogMessage DBG_TRACE, "Processing status messages in the database."
ProcessStatusMessagesInSiteDatabase strComputer, strDBName
Else
LogMessage DBG_TRACE, "The database is not active."
End If
End If
Next
Set oResults = Nothing
oSQLServer.Disconnect
Set oSQLServer = Nothing
End Sub
'******************************************************************************
' Name: GetSMSData
'
' Purpose: Returns data from the specified SMS Site Database.
'
' Parameters: strComputer Fully qualified computer name for the SQL server.
' strDBName Name of the database to query.
' strSiteCode SMS Site Code returned from the specified database.
' strSiteServer SMS Site Server computer name returned from the
' specified database.
'
' Returns: strSiteCode, strSiteServer
'
Sub GetSMSData(strComputer, strDBName, strSiteCode, strSiteServer)
Dim cnADOConnection
Dim rsSMSData
Dim strParam
Dim strQuery
Dim intRecordCount
On Error Resume Next
'Open a connection to the SMS site database in the default SQL
'instance using the OLE DB provider.
'=============================================================
Set cnADOConnection = CreateObject("ADODB.Connection")
strParam = "Server=" & strComputer & ";Database=" & strDBName & ";Trusted_Connection=yes"
cnADOConnection.Open strParam
If Err Then
LogMessage DBG_ERROR, "Failed to connect to the database '" & strDBName & "'."
Set cnADOConnection = Nothing
Exit Sub
End If
'Check if the database is an SMS Site Database by querying the
'SMSData table.
'=============================================================
strQuery = "select * from SMSData"
Set rsSMSData = cnADOConnection.Execute(strQuery)
If Err Then
'LogMessage DBG_ERROR, "Failed to execute SMSData query."
cnADOConnection.Close
Set cnADOConnection = Nothing
Exit Sub
End If
'Get the SMS Site Code and SMS Site Server for the database. There
'should be only one row and therefore only one site code and site
'server in the SMSData table.
'==================================================================
If intRecordCount <> 1 Then
LogMessage DBG_ERROR, "The SMSData contains more than one row is therefore consider corrupted."
Err.Raise ERR_INVALID_TABLE
End If
'Close the connection to the database.
'=====================================
Set rsSMSData = Nothing
cnADOConnection.Close
Set cnADOConnection = Nothing
End Sub
'******************************************************************************
' Name: IsSiteDatabaseActive
'
' Purpose: Checks if there is an active SMS Site Database for the specified
' site and or site server.
'
' Parameters: strComputer Fully qualified computer name for the SQL server.
' strSiteCode SMS Site Code
' strSiteServer SMS Site Server computer name
'
' Returns: True, if an active database is present
' False, if an active database is not present
'
Function IsSiteDatabaseActive(strComputer, strSiteCode, strSiteServer)
Dim strQuery
Dim strNamespace
Dim strRegValue
Dim oService
On Error Resume Next
'Check input parameters.
'=======================
IsSiteDatabaseActive = False
If IsEmpty(strComputer) Or IsEmpty(strSiteCode) Or IsEmpty(strSiteServer) Then
LogMessage DBG_ERROR, "Invalid input parameter."
Exit Function
End If
'Check if the specified site is associated with the one and only
'active SMS Site Database by querying through WMI for the single
'instance of the SMS_SQL_MONITOR service. If the service exists,
'verify that the Operations Management site code for the SMS SQL
'Server is the same as the one specified.
'================================================================
strNamespace = "winmgmts:\\" & strComputer & "\root\cimv2"
strQuery = "select * from Win32_Service where Name='" & SVC_SMS_SQL_MONITOR & "'"
Set oService = WMIExecQuery(strNamespace, strQuery)
If Not Err Then
'Get the Operations Management site code for the SMS SQL Server
'and compare it to the specified site code. If they match, there
'is an active database for this site.
'================================================================
If IsEmpty(strRegValue) Then
Set oService = Nothing
Err.Clear
Exit Function
End If
If (strRegValue = strSiteCode) Then
IsSiteDatabaseActive = True
Set oService = Nothing
Exit Function
End If
Else
Err.Clear
End If
'There is more than one active SMS Site Database on this computer.
'Check if the specified site server is associated with one of them.
'Query through WMI for the instance of the SMS_SQL_MONITOR service
'supporting the SMS Site Server.
'==================================================================
strQuery = "select * from Win32_Service where Name='" & SVC_SMS_SQL_MONITOR & "_" & strSiteServer & "'"
Set oService = WMIExecQuery(strNamespace, strQuery)
If (Not Err) And (oService.Count = 1) Then
IsSiteDatabaseActive = True
End If
Set oService = Nothing
Err.Clear
End Function
'******************************************************************************
' Name: ProcessStatusMessagesInSiteDatabase
'
' Purpose: Process status messages found in the specified SMS Site Database.
'
' Parameters: strComputer Fully qualified computer name for the SQL server.
' strDBName Name of the SMS Site Database to query.
'
' Returns: Nothing
'
Sub ProcessStatusMessagesInSiteDatabase(strComputer, strDBName)
Dim cnADOConnection
Dim rsStatusMessage
Dim intRecordCount
Dim intLastRecordID
Dim bFilter
Dim bAscendingOrder
Dim bFirstRun
Dim strParam
Dim strQuery
Dim strLastRecordID
Dim bCreateEvents
On Error Resume Next
'Check input parameters.
'=======================
If IsEmpty(strComputer) Or IsEmpty(strDBName) Then
LogMessage DBG_ERROR, "Invalid input parameter."
Err.Raise ERR_INVALID_PARAMETER
Exit Sub
End If
'Get the RecordID for the last status message read from this database.
'If the RecordID is null, 0, this can be considered the first status
'message processing run. Only get and save the RecordID of the last
'message in the database.
'====================================================================
intLastRecordID = GetLastRecordID(strDBName)
If intLastRecordID = "" Then
strLastRecordID = "0"
bFilter = False
bAscendingOrder = False
bFirstRun = True
Else
strLastRecordID = intLastRecordID
bFilter = True
bAscendingOrder = True
bFirstRun = False
End If
LogMessage DBG_TRACE, "The record ID of the previous last status message processed was '" & intLastRecordID & "'."
'Open a connection to the SMS site database in the default SQL
'instance using the OLE DB provider.
'=============================================================
Set cnADOConnection = CreateObject("ADODB.Connection")
strParam = "Server=" & strComputer & ";Database=" & strDBName & ";Trusted_Connection=yes"
cnADOConnection.Open strParam
If Err Then
LogMessage DBG_ERROR, "Failed to connect to the SMS Site Database."
Set cnADOConnection = Nothing
Exit Sub
End If
'Set date format for the SMS Status Message query which contains a
'date time filter. The MOM Agent runs under the Locale ID 1033,
'English - United States. If the query is being made to a
'non-english SMS Site Database, we need to tell SQL what format the
'date is in.
'==================================================================
LogMessage DBG_TRACE, "Executing query at local time: " & CStr(Time)
Set rsStatusMessage = cnADOConnection.Execute(strQuery)
LogMessage DBG_TRACE, "Query completed at local time: " & CStr(Time)
If Err Then
LogMessage DBG_ERROR, "Failed to execute set DATEFORMAT query."
cnADOConnection.Close
Set cnADOConnection = Nothing
Exit Sub
End If
'Query for new status messages that are being monitored.
'=======================================================
strQuery = GetSMSStatusMessageQuery(strLastRecordID, bFilter, bAscendingOrder)
LogMessage DBG_TRACE, "SMS Status Message query: " & strQuery
LogMessage DBG_TRACE, "Executing query at local time: " & CStr(Time)
Set rsStatusMessage = cnADOConnection.Execute(strQuery)
LogMessage DBG_TRACE, "Query completed at local time: " & CStr(Time)
If Err Then
LogMessage DBG_ERROR, "Failed to execute status message query."
cnADOConnection.Close
Set cnADOConnection = Nothing
Exit Sub
End If
'Create an event for each returned status message.
'=================================================
intRecordCount = 0
Do While (Not rsStatusMessage.EOF)
'If this is the first processing run, get the RecordID of
'the last message and abort.
'========================================================
If bFirstRun Then
intLastRecordID = rsStatusMessage("RecordID").Value
Exit Do
End If
'If an error occurs while attempting to create the event
'for this SMS status message, stop processing. On the
'the next cycle, processing should resume with this same
'message. Note, if one event should fail to be created
'there is a high probability that all subsequent ones
'will also.
'=======================================================
CreateEvent rsStatusMessage
If Err Then
LogMessage DBG_ERROR, "Failed to create a MOM event for an SMS Status Message."
Exit Do
End If
'Close the connection to the SMS site database.
'==============================================
cnADOConnection.Close
Set cnADOConnection = Nothing
Set rsStatusMessage = Nothing
'Save the RecordID for the last status message read.
'===================================================
SetLastRecordID strDBName, intLastRecordID
If bFirstRun Then
LogMessage DBG_TRACE, "This is the first run against this database."
LogMessage DBG_TRACE, "Monitoring will start on the next run with status message record ID '" & intLastRecordID & "'."
Else
LogMessage DBG_TRACE, "The total number of status messages processed was '" & intRecordCount & "'."
LogMessage DBG_TRACE, "The record ID of the last status message processed was '" & intLastRecordID & "'."
End If
End Sub
'******************************************************************************
' Name: GetSMSStatusMessageQuery
'
' Purpose: Gets query string for monitored SMS Status Messages.
'
' Parameters: strLastRecordID ID of the last record processed. Returned
' query will specify records with a RecordID
' greater than this value.
' bFilter If TRUE, return query for only specific
' SMS 2003 messages. If FALSE, return query
' for all messages.
' bAscendingOrder If TRUE, return query for ascending order.
' If FALSE, return query for descending order.
'
' Returns: String, a query ordered by RecordID, ascending or descending
'
Function GetSMSStatusMessageQuery(strLastRecordID, bFilter, bAscendingOrder)
Dim strQuery
Dim strDateTimeUTC
'Construct select statement. If filtering, perform a join to filter
'out everything but SMS 2003 status messages. Only properties that
'will be used are specified. If not filtering, return everything.
'This will return the RecordID of the last status message.
'===================================================================
If bFilter Then
strQuery = "select " & _
"System.Netbios_Name0, " & _
"System.Resource_Domain_OR_Workgr0, " & _
"StatusMessage.Component, " & _
"StatusMessage.MessageID, " & _
"StatusMessage.ModuleName, " & _
"StatusMessage.RecordID, " & _
"StatusMessage.Severity, " & _
"StatusMessage.SiteCode, " & _
"StatusMessage.TopLevelSiteCode, " & _
"StatusMessage.Win32Error " & _
"from vStatusMessages AS StatusMessage " & _
"join System_DISC as System on StatusMessage.MachineName=System.Netbios_Name0 " & _
"join Sites as Site on StatusMessage.SiteCode=Site.SiteCode " & _
"where Site.Version like '2.5%' and " & _
"RecordID > " & strLastRecordID & ""
Else
strQuery = "select * from vStatusMessages where RecordID > " & strLastRecordID & ""
End If
'Add filter component if needed.
'===============================
If bFilter Then
'SMS Status Message IDs
'======================
strQuery = strQuery & " and StatusMessage.MessageID in " & _
"(" & _
GENMSG_ERROR_NETWORK_SERVER_IS_DOWN & ", " & _
GENMSG_ERROR_SQL_CONNECT & ", " & _
GENMSG_ERROR_REGISTRY_READ & ", " & _
SRVMSG_SITECOMP_ERROR_COMP_INSTALL_FAILED & ", " & _
SRVMSG_SITECOMP_ERROR_COMP_REINSTALL_FAILED & ", " & _
SRVMSG_SITECOMP_ERROR_COMP_DEINSTALL_FAILED_AND_ABORTED & ", " & _
SRVMSG_SITECOMP_ERROR_SERVER_INSTALL_FAILED & ", " & _
SRVMSG_SITECOMP_ERROR_SERVER_DEINSTALL_FAILED_AND_ABORTED & ", " & _
SRVMSG_SITECOMP_ERROR_SERVER_IS_DOWN & ", " & _
SRVMSG_SITECOMP_ERROR_SERVER_IN_USE_BY_OTHER_SITE & ", " & _
SRVMSG_SITECOMP_ERROR_SERVER_NO_NTFS_DRIVE & ", " & _
SRVMSG_SITECOMP_ERROR_SERVER_COULD_NOT_READ_CONNECT_ACCOUNT & ", " & _
SRVMSG_SITECOMP_ERROR_SERVER_COULD_NOT_WRITE_CONNECT_ACCOUNT & ", " & _
SRVMSG_SITECOMP_INFO_TRANSACTION_SERVICE_ACCT_CHANGED & ", " & _
SRVMSG_SITECOMP_INFO_TRANSACTION_DEINSTALL_SERVER & ", " & _
SRVMSG_SITECOMP_INFO_COMP_DEINSTALLED_THREAD & ", " & _
SRVMSG_SITECOMP_INFO_COMP_COULD_NOT_START_THREAD & ", " & _
SRVMSG_SMSEXEC_ERROR_AUTOSTART_THREAD_COMP_STOPPED & ", " & _
SRVMSG_SMSDBMON_WARNING_TASK_EXEC & ", " & _
SRVMSG_COLLEVAL_ERROR_ENUM_COLL & ", " & _
SRVMSG_COLLEVAL_ERROR_SETUP_TABLE & ", " & _
SRVMSG_DDM_ERROR_GET_DISC_SRC & ", " & _
SRVMSG_DATALDR_ERROR_STOPPING_MIF_PROC & ", " & _
SRVMSG_SITECTRL_INFO_DELTA_FROM_SDK_CLIENT_IS_OLD & ", " & _
SRVMSG_HMAN_ERROR_CONNECT_TO_SQL & ", " & _
SRVMSG_HMAN_INFO_PROCESSED_DB & ", " & _
SRVMSG_SCHED_ERROR_NO_ADDRESS_DEFINED & ", " & _
SRVMSG_SENDER_ERROR_LAN_CONNECTION & ", " & _
SRVMSG_SENDER_ERROR_RAS_CONNECTION & ", " & _
SRVMSG_SENDER_ERROR_LAN_CONNECTION2 & ", " & _
SRVMSG_INBOXMGR_ERROR_CONNECT_TO_SITE_SERVER & ", " & _
SRVMSG_SITECOMP_ERROR_SERVER_COMPONENTS_DEINSTALL_FAILED_AND_ABORTED & ", " & _
SRVMSG_SITECOMP_INFO_COMP_COULD_NOT_ADD_MACHINEACCOUNT & ", " & _
SRVMSG_SITECOMP_CANNOT_FIND_SMS_AD_CONTAINER & ", " & _
SRVMSG_SITECOMP_CANNOT_UPDATE_AD_OBJECT & ", " & _
SRVMSG_SITECOMP_CANNOT_CREATE_AD_OBJECT & ", " & _
SRVMSG_SITECOMP_CANNOT_UPDATE_MP_PERMISSIONS & ", " & _
SRVMSG_SITECOMP_SLP_CANNOT_CONNECT_TO_SQL & ", " & _
SRVMSG_SITECOMP_ERROR_COMP_BOOTSTRAP_MP_MSI_ERROR & ", " & _
SRVMSG_BACKUP_ERROR_CONTROL_FILE_OPEN & ", " & _
SRVMSG_BACKUP_ERROR_COULD_NOT_STOP_EXECUTABLE & ", " & _
SRVMSG_BACKUP_ERROR_COULD_NOT_START_EXECUTABLE & ", " & _
SRVMSG_BACKUP_ERROR_COULD_NOT_STOP_SERVICE & ", " & _
SRVMSG_BACKUP_ERROR_COULD_NOT_START_SERVICE & ", " & _
SRVMSG_BACKUP_ERROR_NO_BACKUP_DEST_DIR & ", " & _
SRVMSG_BACKUP_ERROR_INVALID_BACKUP_DEST_DIR & ", " & _
SRVMSG_BACKUP_ERROR_SYNTAX_ERRORS & ", " & _
SRVMSG_BACKUP_ERROR_REGISTRY_TASK_FAILED & ", " & _
SRVMSG_BACKUP_ERROR_DBBACKUP_TASK_FAILED & ", " & _
SRVMSG_BACKUP_INFO_COMPLETED_SUCCESSFULLY & ", " & _
SRVMSG_BACKUP_ERROR_FILESYSTEM_TASK_FAILED & ", " & _
MPMSG_FDM_ERROR_CONNECT_TO_SITE_SERVER & ", " & _
MPMSG_CANNOT_READ_MP_CONFIGURATION & ", " & _
MPMSG_CONNECT_DATABASE_FAILED & ", " & _
MPMSG_WINS_REGISTRATION_FAILED & ", " & _
MPMSG_WINS_UNREGISTRATION_FAILED & ", " & _
MPMSG_WRITE_TO_CCM_SETTINGS_FAILED & ", " & _
MPMSG_UPDATE_MP_SETTINGS_FAILED & ", " & _
MPMSG_START_ALL_MP_MANAGERS_FAILED & ", " & _
MPMSG_HTTP_REQUEST_NONRESPONSIVE & ", " & _
DMPMSG_ERROR_UNEXPECTED & ", " & _
DMPMSG_WARNING_LOW_MEMORY & ", " & _
DMPMSG_ERROR_BAD_DB_CONNECTION & ", " & _
CLIMSG_UPDATESSYNC_ERROR_NO_SITECODE & ", " & _
CLIMSG_UPDATESSYNC_ERROR_NO_PACKAGEID & ", " & _
CLIMSG_UPDATESSYNC_ERROR_NO_SITENAME & ", " & _
CLIMSG_UPDATESSYNC_ERROR_NO_TARGET & ", " & _
CLIMSG_UPDATESSYNC_ERROR_NO_WRITE_ACCESS & ", " & _
CLIMSG_UPDATESSYNC_ERROR_NO_READ_ACCESS & ", " & _
CLIMSG_UPDATESSYNC_ERROR_SYNC_FAILED & ", " & _
CLIMSG_UPDATESSYNC_ERROR_UPDATE_DP & _
")"
'SMS Server and Patch Management Component names
'===============================================
strQuery = strQuery & " and StatusMessage.Component in " & _
"(" & _
"'SMS_AD_SYSTEM_DISCOVERY_AGENT', " & _
"'SMS_AD_SYSTEM_GROUP_DISCOVERY_AGENT', " & _
"'SMS_AD_USER_DISCOVERY_AGENT', " & _
"'SMS_CLIENT_CONFIG_MANAGER', " & _
"'SMS_CLIENT_INSTALL_DATA_MGR', " & _
"'SMS_COLLECTION_EVALUATOR', " & _
"'SMS_COMPONENT_STATUS_SUMMARIZER', " & _
"'SMS_COURIER_SENDER_CONFIRMATION', " & _
"'SMS_DESPOOLER', " & _
"'SMS_DISCOVERY_DATA_MANAGER', " & _
"'SMS_DISTRIBUTION_MANAGER', " & _
"'SMS_EXECUTIVE', " & _
"'SMS_HIERARCHY_MANAGER', " & _
"'SMS_INBOX_MANAGER', " & _
"'SMS_INBOX_MANAGER_ASSISTANT', " & _
"'SMS_INVENTORY_DATA_LOADER', " & _
"'SMS_INVENTORY_PROCESSOR', " & _
"'SMS_LAN_SENDER', " & _
"'SMS_MP_CONTROL_MANAGER', " & _
"'SMS_MP_DEVICE_MANAGER', " & _
"'SMS_MP_FILE_DISPATCH_MANAGER', " & _
"'SMS_NETWORK_DISCOVERY', " & _
"'SMS_OFFER_MANAGER', " & _
"'SMS_OFFER_STATUS_SUMMARIZER', " & _
"'SMS_POLICY_PROVIDER', " & _
"'SMS_REPLICATION_MANAGER', " & _
"'SMS_REPORTING_POINT', " & _
"'SMS_SCHEDULER', " & _
"'SMS_SITE_BACKUP', " & _
"'SMS_SITE_COMPONENT_MANAGER', " & _
"'SMS_SITE_CONTROL_MANAGER', " & _
"'SMS_SITE_SYSTEM_STATUS_SUMMARIZER', " & _
"'SMS_SOFTWARE_INVENTORY_PROCESSOR', " & _
"'SMS_SOFTWARE_METERING_PROCESSOR', " & _
"'SMS_SQL_MONITOR', " & _
"'SMS_STATUS_MANAGER', " & _
"'SMS_WINNT_SERVER_DISCOVERY_AGENT', " & _
"'Software Updates Sync Tool'" & _
")"
'Date and time starting point
'============================
strDateTimeUTC = GetDateTimeUTCQueryFilter()
strQuery = strQuery & " and " & _
"StatusMessage.Time > '" & strDateTimeUTC & "'"
End If
'Add order by qualifier.
'=======================
strQuery = strQuery & " order by RecordID"
'Add asending or descending specifier for how the results will be
'ordered.
'================================================================
If bAscendingOrder Then
strQuery = strQuery & " asc"
Else
strQuery = strQuery & " desc"
End If
'Return the fully constructed query statement.
'=============================================
GetSMSStatusMessageQuery = strQuery
End Function
'******************************************************************************
' Name: GetDateTimeUTCQueryFilter
'
' Purpose: Gets the date and time in UTC format that is to be used to filter
' status messages.
'
' Parameters: None
'
' Returns: String, a date and time
'
Function GetDateTimeUTCQueryFilter()
Dim DateTimeUTC
On Error Resume Next
'Return a data and time in UTC format that is 3 days earlier than the
'current time.
'====================================================================
DateTimeUTC = DateAdd("d", -3, GetCurrentDateTimeUTC()) 'In days
'******************************************************************************
' Name: GetCurrentDateTimeUTC
'
' Purpose: Gets the current date and time in UTC format.
'
' Parameters: None
'
' Returns: Date, current date and time
'
Function GetCurrentDateTimeUTC()
Dim oTimeZone
Dim oTimeZoneSet
Dim CurrentDateTimeLocal
Dim intBias
On Error Resume Next
'Get the instances of this computer's time zone under the WMI CIMV2
'namespace. There will be only one for the current system. Convert
'the current local time to UTC time; UTC = local time + bias. The
'bias is obtained from the Win32_TimeZone class.
'===================================================================
Set oTimeZoneSet = GetObject("winmgmts:").InstancesOf("Win32_TimeZone")
If Err Then
Err.Clear
Exit Function
End If
If Not IsEmpty(oTimeZoneSet) Then
For Each oTimeZone In oTimeZoneSet
'Convert the current local time to UTC time.
'
'A negative time zone bias indicates that the local time is
'earlier than GMT time, a UTC time with zero bias or offset.
'A negative time zone bias must therefore be added to the
'local time. Likewise, a positive one subtracted. The
'daylight savings bias can be added directly though. Thus
'
'Bias = -TimeZoneBias + DaylightSavingsBias
'UTC = LocalTime + Bias. Bias is in minutes.
'===========================================================
CurrentDateTimeLocal = Now
intBias = -oTimeZone.Bias
If Not IsEmpty(oTimeZone.DaylightDay) Then
intBias = intBias + oTimeZone.DaylightBias
End If
'******************************************************************************
' Name: CreateEvent
'
' Purpose: To generate a MOM event for the specified SMS status message.
'
' Parameters: rsStatusMessage, ADO RecordSet object for an SMS Status Message.
'
Sub CreateEvent(rsStatusMessage)
'oEvent.SourceDomain = "DOMAIN" ' Domain of SourceComputer
'oEvent.SourceComputer = "MachineName" ' Must be a MOM Agent
oEvent.LoggingDomain = rsStatusMessage("Resource_Domain_OR_Workgr0").Value ' Domain of LoggingComputer
oEvent.LoggingComputer = rsStatusMessage("Netbios_Name0").Value ' Doesn't have to be a MOM Agent
oEvent.Message = "A new monitored SMS status message on machine " & rsStatusMessage("Netbios_Name0").Value & _
" from component " & rsStatusMessage("Component").Value & _
" with message ID " & rsStatusMessage("MessageID").Value & _
" was found in the site " & rsStatusMessage("SiteCode").Value & _
" database."
'Submit, raise, this event to MOM.
'=================================
ScriptContext.Submit oEvent
'Cleanup
'=======
Set oEvent = Nothing
End Sub
'******************************************************************************
' Name: GetErrorString
'
' Purpose: Attempts to find the description for an error if an error with
' no description is passed in.
'
' Parameters: oErr The error object
'
' Returns: String, the description for the error. (Includes the error code.)
'
Function GetErrorString(oErr)
Dim lErr
Dim strErr
lErr = oErr
strErr = oErr.Description
On Error Resume Next
If 0 >= Len(strErr) Then
'If we don't have an error description, then check to see if the
'error is a 0x8007xxxx error. If it is, then look it up.
'===============================================================
Const ErrorMask = &HFFFF0000
Const HiWord8007 = &H80070000
Const LoWordMask = 65535 ' This is equivalent to 0x0000FFFF
If (lErr And ErrorMask) = HiWord8007 Then
'Attempt to use 'net helpmsg' to get a description for the error.
'================================================================
Dim oShell
Set oShell = CreateObject("WScript.Shell")
If Err = 0 Then
Dim oExec
Set oExec = oShell.Exec("net helpmsg " & (lErr And LoWordMask))
Dim strMessage, i
Do
strMessage = oExec.stdout.ReadLine()
i = i + 1
Loop While (Len(strMessage) = 0) And (i < 5)
strErr = strMessage
End If
End If
End If
GetErrorString = vbCrLf & "The error returned was: '" & strErr & "' " & lErr & " (0x" & Hex(lErr) & ")"
End Function
'******************************************************************************
' Name: ScriptError
'
' Purpose: To generate a warning about a runtime script error.
'
' Parameters: strError The description of the error
'
' Returns: Nothing
'
Sub ScriptError(strError)
LogEvent EVENT_ID_SCRIPTERROR, EVENT_TYPE_WARNING, "encountered a runtime error." & vbCrLf & "Failed to " & strError
End Sub
'******************************************************************************
' Name: LogEvent
'
' Purpose: To generate a MOM event
'
' Parameters: lEventID The event code
' lEventType The severity of the event
' strMessage The message to include in the event
'
' Returns: Nothing
'
Sub LogEvent(lEventID, lEventType, strMessage)
Dim oEvent
On Error Resume Next
Set oEvent = ScriptContext.CreateEvent
oEvent.EventNumber = lEventID
oEvent.EventType = lEventType
oEvent.Message = "The script '" & ScriptContext.Name & "' running under processing rule '" & ScriptContext.ProcessingRule.Name & "' " & strMessage
ScriptContext.Submit oEvent
End Sub
'******************************************************************************
' Name: LogMessage
'
' Purpose: To log a message to ScriptContext and MOM's agent response log.
'
' Parameters: lLevel The debug level for this message i.e. trace,
' warning or error
' strMessage The message to write
'
' Returns: Nothing
'
Sub LogMessage(lLevel, strMessage)
If (lLevel < DBG_NONE) Then
If (lLevel = DBG_ERROR) Then
ScriptContext.Echo "[Error]: " + strMessage
ElseIf (lLevel = DBG_WARNING) Then
ScriptContext.Echo "[Warning]: " + strMessage
ElseIf (lLevel = DBG_TRACE) Then
ScriptContext.Echo "[Trace]:" + strMessage
End If
End If
End Sub
'******************************************************************************
' Name: OpenVarSet
'
' Purpose: Opens a varset file and reads the data from it, into g_oDictionary.
' Only one varset can be open at a single time. Opening a second
' varset will remove the first one. If the first one has not
' been saved then the changes will be lost.
'
' Parameters: None
'
' Returns: Nothing
'
Sub OpenVarSet()
Dim oFSO
Dim oTempFolder
Dim oFile
Set g_oDictionary = CreateObject("Scripting.Dictionary")
Set oFSO = CreateObject("Scripting.FileSystemObject")
If 0 <> Err Then
ScriptError "create Scripting.FileSystemObject." & GetErrorString(Err)
Else
Set oTempFolder = oFSO.GetSpecialFolder(2)
If 0 <> Err Then
ScriptError "find the Temp directory." & GetErrorString(Err)
Else
Set oFile = oFSO.OpenTextFile(oTempFolder.Path & "\" & ScriptContext.Name & ".VarSet", 1, True, -1)
If 0 <> Err Then
ScriptError "open the '" & ScriptContext.Name & ".VarSet' file in the Temp directory." & GetErrorString(Err)
Else
For lIndex = 0 to g_oDictionary.Count - 1
oFile.WriteLine aKeys(lIndex) & vbTab & aItems(lIndex)
Next
oFile.Close
End If
End If
End If
Set g_oDictionary = nothing
End Sub
'******************************************************************************
' Name: GetData
'
' Purpose: Retrieves data out of a varset. Uses the key to determine what
' data to retrieve.
'
' Parameters: strKey, the key of the data to retrieve
'
' Returns: String, the data to return or an empty string
'
Function GetData(strKey)
If g_oDictionary.Exists(strKey) Then
GetData = g_oDictionary.Item(strKey)
Else
GetData = Empty
End If
End Function
'******************************************************************************
' Name: SetData
'
' Purpose: To store data in a varset. If the key exists then the data
' associated with that key is replaced, otherwise the key/data
' combination is added to the varset.
'
' Parameters: strKey, the key of the line to replace
' Data, the data to associate with the key
'
' Returns: Nothing
'
Sub SetData(strKey, Data)
g_oDictionary.Item(strKey) = Data
End Sub
'******************************************************************************
' Name: GetLastRecordID
'
' Purpose: Retrieves previously saved status message RecordID, for the
' the specified site database, out of a varset.
'
' Parameters: strDBName Name of the queried SMS Site Database.
'
' Returns: String, the data to return or zero
'
Function GetLastRecordID(strDBName)
GetLastRecordID = GetData(VAR_LAST_RECORD_ID & "_" & strDBName)
End Function
'******************************************************************************
' Name: SetLastRecordID
'
' Purpose: Saves the specified Record ID, on a per-database basis, in a
' varset. If the key exists, the data associated with that key is
' replaced, otherwise the key/data combination is added to the
' varset.
'
' Parameters: strDBName Name of the queried SMS Site Database.
' intData The Record ID to save.
'
' Returns: Nothing
'
Sub SetLastRecordID(strDBName, intData)
SetData VAR_LAST_RECORD_ID & "_" & strDBName, intData
End Sub
'==========================================================================
' Class: Util
' Description: Wrapper around WMI.
'==========================================================================
Class Util
'---------------
' Constants (Initialized on constructor due to VBS behavior)
'---------------
'Used to indicate to LogMessage when/how to print the message.
Public DBG_NONE
Public DBG_ERROR
Public DBG_WARNING
Public DBG_TRACE
'Internal Debug Level
Private m_nDebugLevel
'Registry hive constants
Public HKEY_CLASSES_ROOT
Public HKEY_CURRENT_USER
Public HKEY_LOCAL_MACHINE
Public HKEY_USERS
Public HKEY_CURRENT_CONFIG
Public HKEY_DYN_CONFIG
'Registry access permissions
Public KEY_QUERY_VALUE
Public KEY_SET_VALUE
Public KEY_CREATE_SUB_KEY
Public KEY_ENUMERATE_SUB_KEYS
Public KEY_NOTIFY
Public KEY_CREATE_LINK
Public DELETE
Public READ_CONTROL
Public WRITE_DAC
Public WRITE_OWNER
'Registry path and key name constants
Public REG_PATH_SERVICES
Public REG_PATH_SERVICES_BASE
Public REG_PATH_SMS
Public REG_PATH_SMS_BASE
Public REG_PATH_SMS_SERVER
Public REG_PATH_SMS_SERVER_OPMGMT_SMS_SERVER_ROLE
Public REG_PATH_SMS_SERVER_OPMGMT_SMS_SERVER_ROLE_BASE
Public REG_PATH_SMS_SERVER_COMPONENTS
Public REG_PATH_SMS_SERVER_COMPONENTS_BASE
Public REG_PATH_SMS_SERVER_SMSEXEC_COMP_BASE
Public REG_PATH_SMS_SERVER_PROVIDERS
Public REG_PATH_SMS_SERVER_PROVIDERS_BASE
Public REG_KEY_SERVICES_CCMEXEC
Public REG_KEY_SERVICES_SMS_EXECUTIVE
Public REG_KEY_SERVICES_SMS_REPORTING_POINT
Public REG_KEY_SERVICES_SMS_SERVER_LOCATOR_POINT
Public REG_KEY_SMS_SERVER_IDENTIFICATION
Public REG_KEY_SMS_SERVER_OPERATIONS_MANAGEMENT
Public REG_KEY_SMS_SERVER_SETUP
Public REG_KEY_SMS_SERVER_OPMGMT_DISTRIBUTION_POINT
Public REG_KEY_SMS_SERVER_OPMGMT_SITE_SERVER
Public REG_KEY_SMS_SERVER_OPMGMT_SQL_SERVER
Public REG_KEY_SMS_SERVER_SMSEXEC_INBOX_MANAGER_ASSISTANT
Public REG_KEY_SMS_SERVER_SMSEXEC_SMS_LAN_SENDER
Public REG_KEY_SMS_SERVER_SMSEXEC_SMS_MP_CONTROL_MANAGER
Public REG_KEY_SMS_SERVER_SMSEXEC_SMS_MP_FILE_DISPATCH_MANAGER
Public REG_KEY_SMS_SERVER_PROVIDERS
'Registry key value name constants
Public REG_VALUE_SERVICES_DISPLAY_NAME
Public REG_VALUE_SMS_SERVER_VERSION
Public REG_VALUE_SMS_SERVER_FULL_VERSION
Public REG_VALUE_SMS_SERVER_SITE_CODE
Public REG_VALUE_SMS_SERVER_PARENT_SITE_CODE
Public REG_VALUE_SMS_SERVER_CENTRAL_SITE
Public REG_VALUE_SMS_SERVER_BINARY_DIRECTORY
Public REG_VALUE_SMS_SERVER_TYPE
'---------------
' Methods
'---------------
'=============
' Method: Class_Initialize
' Description: This is the constructor
' Parameters:
'=============
Private Sub Class_Initialize()
'=============
' Method: Class_Terminate
' Description: This is the destructor
' Parameters:
'=============
Private Sub Class_Terminate()
End Sub
'=============
' Method: SetDebugLevel
' Description: To change the debugging output level of information
' generated by this utility.
' Parameters:
' nLevel - Level, either DBG_NONE, DBG_TRACE,
' DBG_WARNING or DBG_ERROR
'=============
Public Sub SetDebugLevel(ByVal nLevel)
m_nDebugLevel = nLevel
End Sub
'=============
' Method: LogMessage
' Description: Log a debug message to ScriptContext
' Parameters:
' nLevel - Debug level for the message that we're logging.
' strMessage - The message to write to the trace.
'=============
Public Sub LogMessage(ByVal nLevel, ByVal strMessage)
If (nLevel <= m_nDebugLevel) Then
If (nLevel = DBG_ERROR) Then
ScriptContext.Echo "[Error]: " + strMessage
ElseIf (nLevel = DBG_WARNING) Then
ScriptContext.Echo "[Warning]: " + strMessage
ElseIf (nLevel = DBG_TRACE) Then
ScriptContext.Echo "[Trace]:" + strMessage
End If
End If
End Sub
'=============
' Method: ReadRegistryStringValue
' Description: Used to read strings from the registry
' Parameters:
' lHive - Registry hive or root i.e. HKEY_LOCAL_MACHINE
' strKeyPath - Key path for the Registry key to read
' (like "SOFTWARE\Microsoft\WindowsNT\CurrentVersion")
' strValueName - Name of the registry value to read (like "SoftwareType")
'
' Returns:
' The value of the registry key specified. "Nothing" if it fails.
' Callee needs to handle null value return.
'=============
Public Function ReadRegistryStringValue(ByVal lHive, ByVal strKeyPath, ByVal strValueName)
'Read from value from registry
if oReg.GetStringValue(lHive, strKeyPath, strValueName, strValueData) = 0 Then
Call LogMessage(DBG_TRACE, "Value of Registry Key: " + strKeyPath + "\" + strValueName + " = " + strValueData)
ReadRegistryStringValue = strValueData
Else
Call LogMessage(DBG_ERROR, "Reading Registry Key: " + strKeyPath + "\" + strValueName + " Failed!" )
ReadRegistryStringValue = Empty
End If
Set oReg = Nothing
End Function
'=============
' Method: ReadRegistryDWORDValue
' Description: Used to read DWORDs from the registry
' Parameters:
' lHive - Registry hive or root i.e. HKEY_LOCAL_MACHINE
' strKeyPath - Key path for the Registry key to read
' (like "SOFTWARE\Microsoft\WindowsNT\CurrentVersion")
' strValueName - Name of the registry value to read (like "SoftwareType")
'
' Returns:
' The value of the registry key specified. "Nothing" if it fails.
' Callee needs to handle null value return.
'=============
Public Function ReadRegistryDWORDValue(ByVal lHive, ByVal strKeyPath, ByVal strValueName)
'Read value from registry
if oReg.GetDWORDValue(lHive, strKeyPath, strValueName, lValueData) = 0 Then
Call LogMessage(DBG_TRACE, "Value of Registry Key: " + strKeyPath + "\" + strValueName + " = " & lValueData)
ReadRegistryDWORDValue = lValueData
Else
Call LogMessage(DBG_ERROR, "Reading Registry Key: " + strKeyPath + "\" + strValueName + " Failed!" )
ReadRegistryDWORDValue = Empty
End If
Set oReg = Nothing
End Function
'=============
' Method: EnumRegistryKeys
' Description: Used to enumerate registry keys under a given path
' Parameters:
' lHive - Registry hive or root i.e. HKEY_LOCAL_MACHINE
' strKeyPath - Key path for the Registry key to read
' (like "SOFTWARE\Microsoft\WindowsNT\CurrentVersion")
' Returns:
' The list of registry keys found under the path. "null" if the list is empty
'=============
Public Function EnumRegistryKeys(ByVal lHive, ByVal strKeyPath)
'Enumerate keys in registry
if oReg.EnumKey(lHive, strKeyPath, arrKeys) = 0 Then
Call LogMessage(DBG_TRACE, "Found [" + arrKeys(0) + "] key in path : " + strKeyPath )
EnumRegistryKeys = arrKeys
Else
Call LogMessage(DBG_ERROR, "Error enumerating Registry Keys under path : " + strKeyPath )
End If
Set oReg = Nothing
End Function
'=============
' Method: CheckRegistryKeyAccess
' Description: Used to check permissions access to a registry key
' Parameters:
' lHive - Registry hive or root i.e. HKEY_LOCAL_MACHINE
' strKeyPath - Key path for the Registry key to check access
' (like "SOFTWARE\Microsoft\WindowsNT\CurrentVersion")
' lAccess - required permissions i.e. KEY_QUERY_VALUE + KEY_SET_VALUE
' Returns:
' True if the specified permissions are present on the registry key else false.
'=============
Public Function CheckRegistryKeyAccess(ByVal lHive, ByVal strKeyPath, ByVal lAccess)
'Check access to the specified registry key
if oReg.CheckAccess(lHive, strKeyPath, lAccess, bGranted) = 0 Then
Call LogMessage(DBG_TRACE, "Required access present on registry key : " + strKeyPath )
CheckRegistryKeyAccess = bGranted
Else
Call LogMessage(DBG_ERROR, "Error checking access on registry keys : " + strKeyPath )
CheckRegistryKeyAccess = False
End If
Set oReg = Nothing
End Function
'=============
' Method: CheckRegistryKeyExists
' Description: Used to check existence of a registry key
' Parameters:
' lHive - Registry hive or root i.e. HKEY_LOCAL_MACHINE
' strKeyPath - Key path for the Registry key to check access
' (like "SOFTWARE\Microsoft\WindowsNT\CurrentVersion")
' Returns:
' True if the registry key exists else false.
'=============
Public Function CheckRegistryKeyExists(ByVal lHive, ByVal strKeyPath)
'=============
' Method: CheckRegistryKeyStringValueExists
' Description: Used to check existence of a registry key string value
' Parameters:
' lHive - Registry hive or root i.e. HKEY_LOCAL_MACHINE
' strKeyPath - Key path for the Registry key to check access
' (like "SOFTWARE\Microsoft\WindowsNT\CurrentVersion")
' Returns:
' True if the string value exists else false.
'=============
Public Function CheckRegistryKeyStringValueExists(ByVal lHive, ByVal strKeyPath, ByVal strValueName)
If IsEmpty(strValue) Then
CheckRegistryKeyStringValueExists = False
Else
CheckRegistryKeyStringValueExists = True
End If
End Function
'=============
' Method: CheckRegistryKeyDWORDValueExists
' Description: Used to check existence of a registry key DWORD value
' Parameters:
' lHive - Registry hive or root i.e. HKEY_LOCAL_MACHINE
' strKeyPath - Key path for the Registry key to check access
' (like "SOFTWARE\Microsoft\WindowsNT\CurrentVersion")
' Returns:
' True if the DWORD value exists else false.
'=============
Public Function CheckRegistryKeyDWORDValueExists(ByVal lHive, ByVal strKeyPath, ByVal strValueName)
If IsEmpty(lValue) Then
CheckRegistryKeyDWORDValueExists = False
Else
CheckRegistryKeyDWORDValueExists = True
End If
End Function
End Class
'=============
' Method: WMIGetObject
' Description: Returns an object of type SWbemObjectSet
' Parameters:
' sNamespace - A WMI Namespace (ex. winmgmts:\\COMPUTERNAME\ROOT\cimv2).
'=============
Function WMIGetObject(sNamespace)
Dim oWMI
Dim nErrNumber, sErrDescription
On Error Resume Next
Set oWMI = GetObject(sNamespace)
nErrNumber = Err.Number
sErrDescription = Err.Description
On Error Goto 0
If IsEmpty(oWMI) Or nErrNumber <> 0 Then
ScriptContext.Echo "Unable to open WMI Namespace " & sNamespace
Err.Raise 9100, GET_WMI_NO_NAMESPACE_SOURCE(sNamespace), GET_WMI_NO_NAMESPACE_DESCRIPTION(nErrNumber, sErrDescription)
End If
Set WMIGetObject = oWMI
Set oWMI = Nothing
End Function
'=============
' Method: WMIGetInstance
' Description: Returns an object of type SWbemObjectSet
' Parameters:
' sNamespace - A WMI Namespace (ex. winmgmts:\\COMPUTERNAME\ROOT\cimv2).
' sInstance - A WMI Namespace Instance (ex. Win32_OperatingSystem)
'=============
Function WMIGetInstance(sNamespace, sInstance)
Dim oWMI, oInstance
Dim nErrNumber, sErrDescription
On Error Resume Next
Set oWMI = GetObject(sNamespace)
nErrNumber = Err.Number
sErrDescription = Err.Description
On Error Goto 0
If IsEmpty(oWMI) Or nErrNumber <> 0 Then
ScriptContext.Echo "Unable to open WMI Namespace " & sNamespace
Err.Raise 9100, GET_WMI_NO_NAMESPACE_SOURCE(sNamespace), GET_WMI_NO_NAMESPACE_DESCRIPTION(nErrNumber, sErrDescription)
End If
On Error Resume Next
Set oInstance = oWMI.InstancesOf(sInstance)
nErrNumber = Err.Number
sErrDescription = Err.Description
On Error Goto 0
If IsEmpty(oInstance) Or nErrNumber <> 0 Then
ScriptContext.Echo "The class name '" & sInstance & "' returned no instances. Error:" & nErrNumber & ", " & sErrDescription & "."
Err.Raise 9100, GET_WMI_NO_INSTANCES_SOURCE(sInstance), GET_WMI_NO_INSTANCES_DESCRIPTION(nErrNumber, sErrDescription)
End If
'Determine if we queried a valid WMI class - Count will return 0 or empty
On Error Resume Next
Dim nInstanceCount
nInstanceCount = oInstance.Count
nErrNumber = Err.Number
sErrDescription = Err.Description
On Error Goto 0
If nErrNumber <> 0 Then
ScriptContext.Echo "The class name '" & sInstance & "' did not return any valid instances. Error:" & nErrNumber & ", " & sErrDescription & "."
Err.Raise 9100, GET_WMI_NO_VALID_INSTANCES_SOURCE(sInstance), GET_WMI_NO_VALID_INSTANCES_DESCRIPTION(nErrNumber, sErrDescription)
End If
Set WMIGetInstance = oInstance
Set oInstance = Nothing
Set oWMI = Nothing
End Function
'=============
' Method: WMIExecQuery
' Description: Returns an object of type SWbemObjectSet
' Parameters:
' sNamespace - A WMI Namespace (ex. winmgmts:\\COMPUTERNAME\ROOT\cimv2).
' sQuery - A SQL Query (ex. SELECT * FROM Win32_OperatingSystem)
'=============
Function WMIExecQuery(sNamespace, sQuery)
Dim oWMI, oQuery
Dim nErrNumber, sErrDescription
On Error Resume Next
Set oWMI = GetObject(sNamespace)
nErrNumber = Err.Number
sErrDescription = Err.Description
On Error Goto 0
If IsEmpty(oWMI) Or nErrNumber <> 0 Then
ScriptContext.Echo "Unable to open WMI Namespace " & sNamespace
Err.Raise 9100, GET_WMI_NO_NAMESPACE_SOURCE(sNamespace), GET_WMI_NO_NAMESPACE_DESCRIPTION(nErrNumber, sErrDescription)
End If
On Error Resume Next
Set oQuery = oWMI.ExecQuery(sQuery)
nErrNumber = Err.Number
sErrDescription = Err.Description
On Error Goto 0
If IsEmpty(oQuery) Or nErrNumber <> 0 Then
ScriptContext.Echo "The Query '" & sQuery & "' returned an invalid result set. Error:" & nErrNumber & ", " & sErrDescription & "."
Err.Raise 9100, GET_WMI_QUERY_NO_RESULTS_SOURCE(sQuery), GET_WMI_QUERY_NO_RESULTS_DESCRIPTION(nErrNumber, sErrDescription)
End If
'Determine if we queried a valid WMI class - Count will return 0 or empty
On Error Resume Next
Dim nInstanceCount
nInstanceCount = oQuery.Count
nErrNumber = Err.Number
sErrDescription = Err.Description
On Error Goto 0
If nErrNumber <> 0 Then
ScriptContext.Echo "The Query '" & sQuery & "' did not return any valid instances. Error:" & nErrNumber & ", " & sErrDescription & "."
Err.Raise 9100, GET_WMI_QUERY_NO_VALID_INSTANCES_SOURCE(sQuery), GET_WMI_QUERY_NO_VALID_INSTANCES_DESCRIPTION(nErrNumber, sErrDescription)
End If