'**************************************************************************** ' ' Module: secRMMSCCMDeleteByMessageText.vbs ' ' Purpose: Delete secRMM events in the SCCM DB based on the message text. ' ' Requirements: ' 1. Run on computer with SCCM agent on it or ' directly on the SCCM site server. ' 2. Run on computer with secRMM installed. ' 3. secRMM SCCMConnection must be defined. ' ' Suggested use: ' Use the system Task Schedular to invoke this script on a ' periodic basis. Since this is a vbscript, you invoke it ' like: ' cscript secRMMSCCMDeleteByMessageText.vbs ' ' Setup: ' Modify the Array named ArrayOfStringsToMatchForDelete below. ' By default, it deletes events with the text: ' "secRMM: SCCM Compliance Setting check." ' ' Copyright (c) 2016 Squadra Technologies ' '**************************************************************************** Dim objFSO Dim objShell Dim objScriptFile Dim strLoggingFolder Dim strLoggingFileName Dim boolLog Dim objSCCMRemoteConnect Dim objSCCMRemoteConnection Dim boolValidConnectionToSCCM Dim boolStaleCacheEntry Dim strSecRMM ArrayOfStringsToMatchForDelete = _ Array("secRMM: SCCM Compliance Setting check.", _ "put the text you want to delete in these array entries but be very careful - 1", _ "put the text you want to delete in these array entries but be very careful - 2") Set objFSO = Nothing Set objShell = Nothing boolValidConnectionToSCCM = False boolLog = ShouldLog strSecRMM = "secRMM" On Error Resume Next Err.Clear Set objSCCMRemoteConnect = CreateObject("secRMMSCCMRemoteConnect.dll") Set objSCCMRemoteConnection = objSCCMRemoteConnect.Connect() If Err.Number=0 Then For i = LBound(ArrayOfStringsToMatchForDelete) to _ UBound(ArrayOfStringsToMatchForDelete) Call GetMessagesToDelete(objSCCMRemoteConnection, _ ArrayOfStringsToMatchForDelete(i)) Next Else WScript.Echo "The SCCM connection failed: " & _ CStr(Err.Number) & " " & _ Err.Description End If objSCCMRemoteConnection = Nothing objSCCMRemoteConnect = Nothing '============================================================================= Sub GetMessagesToDelete(objSCCMRemoteConnection_in, _ strStringToMatchForDelete_in) Dim queryWQL Dim message Dim messageSet Dim statusMessage Dim insertionString Dim attributes Dim l_objDictionaryMessages Set l_objDictionaryMessages = CreateObject("Scripting.Dictionary") queryWQL = "SELECT b.Time, b.RecordID, b.MachineName, b.MessageID, " & _ " c.InsStrIndex, c.InsStrValue, c.RecordID " & _ "FROM SMS_StatusMessage b " & _ "JOIN SMS_StatMsgInsStrings c ON b.RecordID = c.RecordID " & _ "WHERE b.Component = 'secRMM'" 'and MessageId = '400' Set messageSet = objSCCMRemoteConnection_in.ExecQuery(queryWQL) For Each message in messageSet statusMessage = message.Properties_.Item("b") insertionString = message.Properties_.Item("c") If (l_objDictionaryMessages.Exists(statusMessage.Properties_.Item("RecordId").Value)=False) Then Set l_objDictionaryMessageProperties = CreateObject("Scripting.Dictionary") l_objDictionaryMessageProperties.Add "Time", statusMessage.Properties_.Item("Time").Value l_objDictionaryMessageProperties.Add "Computer", statusMessage.Properties_.Item("MachineName").Value l_objDictionaryMessageProperties.Add "MessageID", CStr(statusMessage.Properties_.Item("MessageID").Value) l_objDictionaryMessageProperties.Add "RecordID", CStr(statusMessage.Properties_.Item("RecordID").Value) Set l_objDictionaryMessageText = CreateObject("Scripting.Dictionary") l_objDictionaryMessageText.Add insertionString.Properties_.Item("InsStrIndex").Value, _ insertionString.Properties_.Item("InsStrValue").Value l_objDictionaryMessageProperties.Add "MessageText", l_objDictionaryMessageText l_objDictionaryMessages.Add statusMessage.Properties_.Item("RecordId").Value, l_objDictionaryMessageProperties Else l_objDictionaryMessages.Item(statusMessage.Properties_.Item("RecordId").Value).Item("MessageText").Add _ insertionString.Properties_.Item("InsStrIndex").Value, _ insertionString.Properties_.Item("InsStrValue").Value End If Next Set l_objArrayListRecordIDs = CreateObject("System.Collections.ArrayList") l_ArrayMessagesKeys = l_objDictionaryMessages.Keys For Each strKey1 in l_ArrayMessagesKeys l_strMessage = "" l_ArrayMessagesProperties = l_objDictionaryMessages.Item(strKey1).Keys For Each strKey2 in l_ArrayMessagesProperties If (strKey2 = "MessageText") Then l_ArrayMessageTextValues = l_objDictionaryMessages.Item(strKey1).Item(strKey2).Items For Each strMessageText in l_ArrayMessageTextValues l_strMessage = l_strMessage & strMessageText Next End If Next If (Len(l_strMessage) <> 0) Then If (InStr(l_strMessage, strStringToMatchForDelete_in) <> 0) Then l_objArrayListRecordIDs.Add _ l_objDictionaryMessages.Item(strKey1).Item("RecordID") End If End If Next If (l_objArrayListRecordIDs.Count <> 0) Then intIndexStart = 0 'It is more efficient to only give SCCM 100 record ids 'at a time While (intIndexStart < l_objArrayListRecordIDs.Count) intIndexCount = l_objArrayListRecordIDs.Count - intIndexStart If (intIndexCount > 100) Then intIndexCount = 100 End If Set l_objSubsetArrayListRecordIDs = _ l_objArrayListRecordIDs.GetRange(intIndexStart, intIndexCount) l_ArrayOfRecordIDs = _ Split(Join(l_objSubsetArrayListRecordIDs.ToArray(), "~"), "~") Call DeleteSecRMMStatusMessages(objSCCMRemoteConnection_in, _ l_ArrayOfRecordIDs) intIndexStart = intIndexStart + intIndexCount Wend End If End Sub '============================================================================= Sub DeleteSecRMMStatusMessages(objSCCMRemoteConnection_in, _ ArrayOfRecordIDs_in) Dim inParams Dim outParams Dim statusMessageClass Dim statusMessageClassName Dim statusMessageMethod On Error Resume Next statusMessageClassName = "SMS_StatusMessage" statusMessageMethod = "DeleteByID" ' Obtain the class definition object of a SMS_StatusMessage object. Set statusMessageClass = objSCCMRemoteConnection_in.Get(statusMessageClassName) If Err.Number<>0 Then Wscript.Echo "Couldn't get status message class: " & statusMessageClassName Exit Sub End If ' Set up the in parameter. Set inParams = statusMessageClass.Methods_(statusMessageMethod).InParameters.SpawnInstance_ inParams.RecordIDs = ArrayOfRecordIDs_in If Err.Number<>0 Then Wscript.Echo "Couldn't get parameters object for " & statusMessageClassName & "." & statusMessageMethod Exit Sub End If ' Call the method. Set outParams = _ objSCCMRemoteConnection_in.ExecMethod( statusMessageClassName, statusMessageMethod, inParams) If Err.Number<>0 Then Wscript.Echo "Couldn't run WMI method " & statusMessageClassName & "." & statusMessageMethod Exit Sub End If WScript.Echo CStr(outParams.ReturnValue) + " record(s) deleted" End Sub '============================================================================= Function ShouldLog() Dim l_objWMI Dim l_strPropertyName Dim l_strPropertyValue On Error Resume Next Set l_objWMI = _ GetObject("winmgmts://./root/CIMV2/secRMM:secRMMWMIProvider") l_strPropertyName = "DebugSecRMM" l_strPropertyValue = _ l_objWMI.GetProperty(l_strPropertyName, "") If (Not(IsNull(l_strPropertyValue))) Then ShouldLog = True Else ShouldLog = False End If Err.Clear End Function '============================================================================= Function Log(strData) Dim objLogFile If (boolLog = True) Then On Error Resume Next Const ForAppending = 8 If (objFSO is nothing) Then Set objFSO = CreateObject("Scripting.FileSystemObject") End If If (objScriptFile is nothing) Then Set objScriptFile = objFSO.GetFile(WScript.ScriptFullName) End If If (strLoggingFolder is nothing) Then strLoggingFolder = objFSO.GetParentFolderName(objScriptFile) End If If (strLoggingFileName is nothing) Then strLoggingFileName = strLoggingFolder & "\secRMMSCCMInterface.log" End If Set objLogFile = objFSO.OpenTextFile(strLoggingFileName, ForAppending, True) objLogFile.WriteLine(Now() & ": " & strData) objLogFile.Close 'Set shell = CreateObject("WScript.Shell") 'shell.LogEvent 1, strData End If End Function