<WriteActionModuleType ID="EDC.Base.SMSUpdateLocalMP.Script.WriteActionExt" Accessibility="Public" Batching="false">
<Configuration>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="Debug" type="xsd:boolean"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="DebugFileName" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="LogSuccessEvent" type="xsd:boolean"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ScriptGroupId" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="SiteCodeMPConfiguration" type="xsd:string"/>
<xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="TimeoutSeconds" type="xsd:int"/>
</Configuration>
<OverrideableParameters>
<OverrideableParameter ID="Debug" Selector="$Config/Debug$" ParameterType="bool"/>
<OverrideableParameter ID="DebugFileName" Selector="$Config/DebugFileName$" ParameterType="string"/>
<OverrideableParameter ID="LogSuccessEvent" Selector="$Config/LogSuccessEvent$" ParameterType="bool"/>
<OverrideableParameter ID="ScriptGroupId" Selector="$Config/ScriptGroupId$" ParameterType="string"/>
<OverrideableParameter ID="SiteCodeMPConfiguration" Selector="$Config/SiteCodeMPConfiguration$" ParameterType="string"/>
<OverrideableParameter ID="TimeoutSeconds" Selector="$Config/TimeoutSeconds$" ParameterType="int"/>
</OverrideableParameters>
<ModuleImplementation Isolation="Any">
<Composite>
<MemberModules>
<WriteAction ID="Script" TypeID="Windows!Microsoft.Windows.ScriptWriteAction">
<ScriptName>SMSUpdateLocalMP.vbs</ScriptName>
<Arguments>$Config/Debug$ "$Config/DebugFileName$" $Config/LogSuccessEvent$ "$Config/ScriptGroupId$" $Config/SiteCodeMPConfiguration$</Arguments>
<ScriptBody><Script>
Option Explicit
'************************************************************************************************************
' Disclaimer
'
' This sample script is not supported under any Microsoft standard support program or service. This sample
' script is provided AS IS without warranty of any kind. Microsoft further disclaims all implied warranties
' including, without limitation, any implied warranties of merchantability or of fitness for a particular
' purpose. The entire risk arising out of the use or performance of this sample script and documentation
' remains with you. In no event shall Microsoft, its authors, or anyone else involved in the creation,
' production, or delivery of this script be liable for any damages whatsoever (including, without limitation,
' damages for loss of business profits, business interruption, loss of business information, or other
' pecuniary loss) arising out of the use of or inability to use this sample script or documentation, even
' if Microsoft has been advised of the possibility of such damages.
'
'***********************************************************************************************************
'* SMSUpdateLocalMP.vbs 1.3
'*
'* This sample shows how to update the CurrentManagementPoint property of the CCM's SMS_Authority if necessary.
'* Works for SMS 2003 and Config Mgr 2007
'*
'* Usage:
'* cscript.exe SMSUpdateLocalMP.vbs <Debug> <DebugFileName> <LogSuccessEvent> <ScriptGroupIdentifier> _
'* <SMSSiteCode1> <MPNetBIOSName1> [<SMSSiteCode2> <MPNetBIOSName2> ... <SMSSiteCoden> <MPNetBIOSNamen>]
'* Example:
'* cscript.exe SMSUpdateLocalMP.vbs True "%WinDir%\Debug\MCSOM07\SMSUpdateLocalMP.log" True "WinSrvOSSupportTools" _
'* "ABC" "srv04" "CDE" "srv05" "FGH" "srv42"
'*
'* Version for Operations Manager 2007
'*
'* JM 2008, 2001
'***********************************************************************************************************
'Const SCRIPT_NAME = "SMSUpdateLocalMP.vbs"
Const SCRIPT_VERSION = "1.3"
Const EVENT_ID_SUCCESS = 1000 'Use IDs in the range 1 - 1000
Const EVENT_ID_SCRIPTERROR = 999 'Then you can use eventcreate.exe to test the MP
Const FOR_READING = 1 'Open a file for reading only. You can't write to this file.
Const FOR_WRITING = 2 'Open a file for writing.
Const FOR_APPENDING = 8 'Open a file and write to the end of the file.
Dim mblnLogSuccessEvent 'As Boolean
Dim mblnDebug 'As Boolean
Dim mstrDebugFileName 'As String
Dim mobjDebugLog 'As TextStream
Dim mstrIdentifier 'As String
Call Main
'*********************************************************************************************
' PROCEDURE: Main
' DESCRIPTION: Reads the script parameters and updates the SMS_LocalMP default instance
' within the WMI namespace root\ccm.
' Depending on the outcome success or error events are created,
' respectively.
' PARAMETERS: void
'*********************************************************************************************
Private Sub Main()
Dim objFSO 'As Scripting.FileSystemObject
Dim colMPConfig 'As Scripting.Dictionary
Dim strConfig 'As String
Dim objMomScriptAPI 'As MOM.ScriptAPI
Call SetLocale("en-us")
Set objMomScriptAPI = CreateObject("MOM.ScriptAPI")
If Not GetScriptParameters(colMPConfig) Then
' If the script is called without the required arguments,
' create an information event and then quit.
Call objMomScriptAPI.LogScriptEvent(mstrIdentifier & " -- " & WScript.ScriptName & " " & SCRIPT_VERSION, EVENT_ID_SCRIPTERROR, EVENT_TYPE_WARNING, _
"The script was called with fewer than 6 arguments or the arguments could not be parsed.")
WScript.Quit -1
End If
Set objFSO = CreateObject("Scripting.FileSystemObject")
Dim i 'As Long
Dim arrKeys 'As String
arrKeys = colMPConfig.Keys
For i = 0 To UBound(arrKeys)
strConfig = strConfig & arrKeys(i) & " = " & colMPConfig.Item(arrKeys(i)) & ", "
Next 'i
'Create debug log and write some informations
If mblnDebug Then
If Not objFSO.FolderExists(Left(mstrDebugFileName, InStrRev(mstrDebugFileName, "\") - 1)) Then Call MakeFolder(Left(mstrDebugFileName, InStrRev(mstrDebugFileName, "\") - 1), objFSO)
Set mobjDebugLog = objFSO.CreateTextFile(mstrDebugFileName, True)
Call mobjDebugLog.WriteLine("Script " & WScript.ScriptName & " " & SCRIPT_VERSION & " started -- " & Now & vbCrLf)
Call mobjDebugLog.WriteLine("Script parameters:" & vbCrLf & vbTab & DEBUG_PARAMETER_NAME & ": " & CStr(mblnDebug) & vbCrLf & _
vbTab & DEBUG_FILE_NAME_PARAMETER_NAME & ": " & mstrDebugFileName & vbCrLf & vbTab & _
LOG_SUCCESS_EVENT_PARAMETER_NAME & ": " & CStr(mblnLogSuccessEvent) & vbCrLf & vbTab & _
CONFIGURATION_PARAMETER_NAME & ": " & Left(strConfig, Len(strConfig) - 2) & vbCrLf)
End If
'Call main function
If UpdateCurrentMP(colMPConfig) Then
If mblnLogSuccessEvent Then Call objMomScriptAPI.LogScriptEvent(mstrIdentifier & " -- " & WScript.ScriptName & " " & SCRIPT_VERSION, EVENT_ID_SUCCESS, EVENT_TYPE_INFORMATION, _
"Script " & WScript.ScriptName & " " & SCRIPT_VERSION & " executed successfully.")
If mblnDebug Then Call mobjDebugLog.WriteLine("Script " & WScript.ScriptName & " " & SCRIPT_VERSION & " executed successfully.")
Else
Call objMomScriptAPI.LogScriptEvent(mstrIdentifier & " -- " & WScript.ScriptName & " " & SCRIPT_VERSION, EVENT_ID_SCRIPTERROR, EVENT_TYPE_WARNING, _
"An error occurred while running script " & WScript.ScriptName & " " & SCRIPT_VERSION)
If mblnDebug Then Call mobjDebugLog.WriteLine("An error occurred while running script " & WScript.ScriptName & " " & SCRIPT_VERSION)
End If
If mblnDebug Then
Call mobjDebugLog.WriteLine(vbCrLf & "Script finished -- " & Now)
Call mobjDebugLog.Close
End If
End Sub
'******************************************************************************
' FUNCTION: UpdateCurrentMP
' DESCRIPTION: Gets the SMS_LocalMP instance (singleton) and updates the
' properties Name, SiteCode and MasterSiteCode
' PARAMETERS: IN Object colMPConfig: initialised Scripting.Dictionary containing the
' given SMS site code and MP names as key/value pairs
' RETURNS: Boolean: True if successful
'******************************************************************************
Private Function UpdateCurrentMP(ByRef colMPConfig) 'As Boolean
Dim objSWbemServices 'As SWbemServices
Dim objSWbemObjectSet 'As SWbemObjectSet
Dim objSWbemObject 'As SWbemObject
Dim strCurrentLocalMP 'As String
Dim strCurrentSiteCode 'As String
Dim strSMSSiteCode 'As String
Dim objSWbemObjectPath 'As SWbemObjectPath
Dim blnContinue 'As Boolean
If mblnDebug Then Call mobjDebugLog.WriteLine("")
'Connect to WMI namespace \\.\root\ccm
If ConnectToWbemNS(".", CCM_WMI_NAME_SPACE, objSWbemServices) Then
'Check if the computer is really managed by the given SMS site.
'The name of the SMS_Authority must match "SMS:<given site code>", e.g. SMS:96S or SMS:STS
If mblnDebug Then Call mobjDebugLog.WriteLine("Connected!" & vbCrLf & "Retrieving instances of '" & SMS_AUTHORITY_WMI_PATH & "'.")
Set objSWbemObjectSet = objSWbemServices.Get(SMS_AUTHORITY_WMI_PATH).Instances_
'If WMI objectset cannot be retrieved exit function
If Not IsObject(objSWbemObjectSet) Then
If mblnDebug Then Call mobjDebugLog.WriteLine("Error! Could not retrieve any instance. Exiting.")
Exit Function
End If
If mblnDebug Then Call mobjDebugLog.WriteLine("Retrieved " & objSWbemObjectSet.Count & " instances of '" & SMS_AUTHORITY_WMI_PATH & "'.")
For Each objSWbemObject In objSWbemObjectSet
If mblnDebug Then Call mobjDebugLog.WriteLine("Instance name: " & Replace(UCase(objSWbemObject.Name), UCase(SMS_AUTHORITY_NAME_PREFIX), "") & vbCrLf & vbTab & _
"Comparing current value with the given site codes " & Join(colMPConfig.Keys, ", ") & "...")
If colMPConfig.Exists(Replace(UCase(objSWbemObject.Name), UCase(SMS_AUTHORITY_NAME_PREFIX), "")) Then
strSMSSiteCode = Replace(UCase(objSWbemObject.Name), UCase(SMS_AUTHORITY_NAME_PREFIX), "")
If mblnDebug Then Call mobjDebugLog.WriteLine(vbTab & "The configuraion contains " & strSMSSiteCode)
blnContinue = True
Exit For
Else
If mblnDebug Then Call mobjDebugLog.WriteLine(vbTab & "The configuraion does not contain " & Replace(UCase(objSWbemObject.Name), UCase(SMS_AUTHORITY_NAME_PREFIX), ""))
End If
Next
If Not blnContinue Then
If mblnDebug Then Call mobjDebugLog.WriteLine(vbCrLf & "The computer is not managed by a configured SCCM or SMS site. Do nothing and return True.")
UpdateCurrentMP = True
Exit Function
End If
If mblnDebug Then Call mobjDebugLog.WriteLine(vbCrLf & "The computer is managed by a configured SCCM or SMS site . Continue..." & vbCrLf & vbCrLf & _
"Retrieving WMI object '" & SMS_LOCAL_MP_WMI_PATH & "'.")
'Get default instance of SMS_LocalMP. (class is singleton)
Set objSWbemObject = objSWbemServices.Get(SMS_LOCAL_MP_WMI_PATH)
'If WMI cannot be retrieved exit function
If Not IsObject(objSWbemObject) Then
If mblnDebug Then Call mobjDebugLog.WriteLine("Error! Could not retrieve the WMI object. Exiting.")
Exit Function
End If
If mblnDebug Then Call mobjDebugLog.WriteLine("Retrieved '" & SMS_LOCAL_MP_WMI_PATH & "'." & vbCrLf & _
"Current values:" & vbCrLf & _
vbTab & "Master site code: " & objSWbemObject.MasterSiteCode & vbCrLf & _
vbTab & "Site code: " & objSWbemObject.SiteCode & vbCrLf & _
vbTab & "Local MP: " & objSWbemObject.Name & vbCrLf)
'Update property values
objSWbemObject.MasterSiteCode = strSMSSiteCode
objSWbemObject.SiteCode = strSMSSiteCode
objSWbemObject.Name = colMPConfig.Item(strSMSSiteCode)
'Save changes
Set objSWbemObjectPath = objSWbemObject.Put_
'Return true if save was successful
If IsObject(objSWbemObjectPath) Then
If mblnDebug Then Call mobjDebugLog.WriteLine("Updated values:" & vbCrLf & _
vbTab & "Master site code: " & objSWbemObject.MasterSiteCode & vbCrLf & _
vbTab & "Site code: " & objSWbemObject.SiteCode & vbCrLf & _
vbTab & "Local MP: " & objSWbemObject.Name & vbCrLf)
UpdateCurrentMP = True
End If
Else
'If WMI cannot be connected exit function
If mblnDebug Then Call mobjDebugLog.WriteLine("Error! Could not connect to WMI namespace. Terminating script!")
End If
End Function
'******************************************************************************
' FUNCTION: ConnectToWbemNS
' DESCRIPTION: Connnects to a WMI namespace
' PARAMETERS: IN String strServerName: host part of WMI namespace. If null the local computer will be used.
' IN String strNameSpace: path to namespace
' OUT Object objSWbemServices: SWbemServices object connected to the given namespace
' RETURNS: Boolean: True if successful
'******************************************************************************
Private Function ConnectToWbemNS(ByRef strServerName, ByRef strNameSpace, ByRef objSWbemServices) 'As Boolean
Dim objSWbemLocator 'as WbemScripting.SWbemLocator
Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
Set objSWbemServices = objSWbemLocator.ConnectServer(strServerName, strNameSpace)
If objSWbemServices Is Nothing Then
ConnectToWbemNS = False
Else
ConnectToWbemNS = True
End If
End Function
'******************************************************************************
' FUNCTION: GetScriptParameters
' DESCRIPTION: Reads the script's parameters
' and sets the global variables.
'
' PARAMETERS: OUT Object colMPConfig: Scripting.Dictionary containing the
' given SMS site code and MP names as
' key/value pairs
' RETURNS: Boolean: True if successful
'******************************************************************************
Private Function GetScriptParameters(ByRef colMPConfig) 'As Boolean
Dim objArguments 'As WScript.Arguments
Dim lngLastIndex 'As Long
Dim i 'As Long
On Error Resume Next
Set objArguments = WScript.Arguments
If objArguments.Count < 6 Then Exit Function
Set colMPConfig = CreateObject("Scripting.Dictionary")
'Get parameters and set global variables
mblnDebug = CBool(objArguments(0))
mstrDebugFileName = Replace(objArguments(1), Chr(34), "")
mblnLogSuccessEvent = CBool(objArguments(2))
mstrIdentifier = Replace(objArguments(3), Chr(34), "")
'Check if the remaining arguments are pairs, i.e. the number is even
'If not, cut the last argument
If ((objArguments.Count) - 4 / 2) = Round((objArguments.Count - 4) / 2) Then
lngLastIndex = objArguments.Count - 1
Else
lngLastIndex = objArguments.Count - 2
End If
'Loop through the remaining arguments and add to the dictionary
'SMSSiteCode1 MPNetBIOSName1 SMSSiteCode2 MPNetBIOSName2 ... SMSSiteCoden MPNetBIOSNamen
For i = 4 To lngLastIndex Step 2
If Not colMPConfig.Exists(UCase(Replace(objArguments(i), Chr(34), ""))) Then Call colMPConfig.Add(UCase(Replace(objArguments(i), Chr(34), "")), Replace(objArguments(i + 1), Chr(34), ""))
Next 'i
If colMPConfig.Count > 0 Then GetScriptParameters = True
End Function
'**************************************************************
' FUNCTION: MakeFolder
' DESCRIPTION: Creates a folder and all necessary parent
' folders.
' PARAMETERS: IN String strFolder: full path of the folder
' IN Object objFSO: Scripting.FileSystemObject object
' RETURNS: Boolean: True if successful
'**************************************************************
Private Function MakeFolder(ByRef strFolder, ByRef objFSO) 'As Boolean
Dim strParentFolder 'As String
On Error Resume Next
'Get parent folder of given folder
strParentFolder = Left(strFolder, InStrRev(strFolder, "\") - 1)
'If the parent folder does not exist create it. (recursive call)
If Not objFSO.FolderExists(strParentFolder) Then Call MakeFolder(strParentFolder, objFSO)
'Create folder
Call objFSO.CreateFolder(strFolder)
'If error no equals zero function is successful
If Err.Number = 0 Then MakeFolder = True
Call Err.Clear
End Function </Script></ScriptBody>
<TimeoutSeconds>$Config/TimeoutSeconds$</TimeoutSeconds>
</WriteAction>
</MemberModules>
<Composition>
<Node ID="Script"/>
</Composition>
</Composite>
</ModuleImplementation>
<InputType>System!System.BaseData</InputType>
</WriteActionModuleType>