Dynamically Deploying ConfigMgr Site Roles using Scripts
Getting Started
At Microsoft IT, we are beginning the process of running our ConfigMgr infrastructure on Hyper-V (virtualized) and we are starting to invest some energy in architecting our future data center in a way to ensure we are cost effective yet performance conscious.
In this blog post, I wanted to share some of the cornerstones of how the dynamic provisioning takes place for our ConfigMgr site roles. In particular, I’m going to focus my attention on ConfigMgr 2007 Distribution Points.
Deploying Distribution Points Process
As many are aware, deployment of site roles in ConfigMgr is a one-time “tax” that most system managers do manually. Besides, how often is one actually deploying new distribution points?
This is a very valid question but the game changes in the world of virtualization whereby the process for acquiring hardware resources is eliminated. With this barrier broken down, a system manager can move well beyond the manual and really start to think “dynamically” in the space of deployment & provisioning.
Thus, deploying Distribution Points (DP) is still a push methodology yet one that now is initiated by the system rather than a human being.
Script: Deploying Distribution Points
In the following script, we dynamically will advise the site server (in this case, our primary site) that we would like to deploy the DP role on the target system. This is done through our dynamic use of System Center Virtual Machine Manager 2008 (a future post) but just assume the OS is laid down and the server is already provisioned with IP stack, required roles\features (e.g. IIS, BITS, and WebDAV) & the domain membership is complete. With this out of the way, we move to deployment of the role -
Site Name: MMS
Site Server: CM01
Code Snippet
<
'********************************************************************
' Main routine
'********************************************************************
On Error Resume Next
' Set variables (site code, system to configure, domain).
strSiteCode = "{ConfigMgr Site Code}"
strComputerName = "{Distribution Point Server Name}"
strDomainName = "{DP Domain Name}"
strSiteServer = "{DP Site Server Name}"
strSmsAdmin = "{ConfigMgr Admin\Service Account}"
strSmsAdminPwd = "{ConfigMgr Admin\Service Account Password}"
' Connect to the Configuration Manager server.
Set objConnection = ConnectToSMS(strSiteCode)
' Load the the site control file.
Set objContext = CreateObject("WbemScripting.SWbemNamedValueSet")
objContext.Add "SessionHandle", objConnection.ExecMethod("SMS_SiteControlFile", "GetSessionHandle").SessionHandle
' Enable site system.
EnableSiteRole objConnection, objContext, "SMS Site System", strComputerName, strSiteCode, strDomainName
' Enable site role(s).
' Uncomment site roles to install.
' ---------------------------------
EnableSiteRole objConnection, objContext, "SMS Distribution Point", strComputerName, strSiteCode, strDomainName
' Release the site control file
objConnection.Get("SMS_SiteControlFile").ReleaseSessionHandle objContext.Item("SessionHandle").Value
' Cleanup
Set strSiteCode = Nothing
Set strComputerName = Nothing
Set strDomainName = Nothing
Set objConnection = Nothing
Set objContext = Nothing
'**********************************************************************
' Function: ConnectToSMS
' Description: This routine makes a connection to the specified site code.
'**********************************************************************
Function ConnectToSMS(strSiteCode)
Dim objLocator
Dim objConnection
' Initialization
Set objLocator = CreateObject("WbemScripting.SWbemLocator")
' Find the provider server
Set objConnection = objLocator.ConnectServer(strSiteServer, "root\sms\site_" & strSiteCode, strSmsAdmin, strSmsAdminPwd )
' Return the connection object
Set ConnectToSMS = objConnection
End Function
'**********************************************************************
' Function: Enable DP Site SiteRole
' Description: This enables the specified DP site system role.
'**********************************************************************
Function EnableSiteRole(objConnection, objContext, strSiteRole, strComputerName, strSiteCode, strDomainName)
Dim objRole
Dim objProp
Dim objPropLists
Dim objComponents
Dim objComponent
Dim objComponentProps
Dim strTempSiteRole
' Refresh our copy of the site control file.
objConnection.ExecMethod "SMS_SiteControlFile.Filetype=1,Sitecode='" & strSiteCode & "'", "RefreshSCF", , , objContext
' Note: There is no separate site role for a Branch Distribution Point, instead the IsPeerDP property is enabled
' on a SMS Distribution Point role.
' Workaround: Set variable to SMS Distribution Point, if the site role is a Branch Distribution Point.
If strSiteRole = "SMS Branch Distribution Point" Then
strTempSiteRole = "SMS Distribution Point"
Else
strTempSiteRole = strSiteRole
End If
'Retrieve the site control object.
On Error Resume Next
Set objRole = objConnection.Get("SMS_SCI_SysResUse.FileType=2,ItemName=" & Chr(34) & _
"[\" & Chr(34) & "Display=\\\\" & strComputerName & "\\\" & Chr(34) & "]MSWNET:[\" & Chr(34) & "SMS_SITE=" & _
strSiteCode & "\" & Chr(34) & "]\\\\" & strComputerName & "\\," & strTempSiteRole & Chr(34) & ",ItemType=" & Chr(34) & _
"System Resource Usage" & Chr(34) & ",SiteCode=" & Chr(34) & strSiteCode & Chr(34), , objContext)
' If the site role already exists, then get the current properties.
If Err.Number = 0 then
objProp = objRole.Props
wscript.echo strTempSiteRole & " already exists. "
wscript.echo "Attempting to enable the site role."
' If the site role is not found, then create it.
ElseIf CStr(Hex(Err.Number)) = "80041002" then
Set objRole = objConnection.Get("SMS_SCI_SysResUse").SpawnInstance_
objRole.NALPath = "[" & Chr(34) & "Display=\\" & strComputerName & "\" & Chr(34) & "]MSWNET:[" & Chr(34) & "SMS_SITE=" & strSiteCode & Chr(34) & "]\\" & strComputerName & "\"
objRole.NALType = "Windows NT Server"
objRole.RoleName = strTempSiteRole
objRole.Sitecode = strSiteCode
objProp = Array()
wscript.echo strTempSiteRole & " doesn't exist. "
wscript.echo "Attempting to create the site role."
' On any other error, fail and exit the function.
Else
EnableSiteRole = False
wscript.echo "Unexpected error: 0x" & Hex(Err.Number) & " - " & Err.Description
wscript.echo "Not attempting to enable the site role."
Exit Function
End If
On Error GoTo 0
objPropLists = objRole.PropLists
If IsNull(objPropLists) then
objPropLists = Array()
End if
' Set the appropriate properties for the specified role.
Select Case strSiteRole
Case "SMS Distribution Point"
SetProperty objConnection, objProp, "Site Info", 0, strComputerName, strSiteCode
SetProperty objConnection, objProp, "BITS download", 1, "", ""
SetProperty objConnection, objProp, "Is protected", 0, "", ""
SetProperty objConnection, objProp, "IsAnonymousEnabled", 1, "", ""
SetProperty objConnection, objProp, "Server Remote Name",0, strComputerName & "." & strDomainName, ""
Case "SMS Site System"
SetProperty objConnection, objProp, "Server Remote Name",0, strComputerName & "." & strDomainName, ""
SetProperty objConnection, objProp, "IsProtected",0, "", ""
SetProperty objConnection, objProp, "Server Remote Public Name",0, "", ""
SetProperty objConnection, objProp, "FDMOperation",0, "", ""
Case Else
wscript.echo " Invalid role specified: " & strSiteRole
EnableSiteRole = False
Exit Function
End Select
' Save the (possibly) updated properties.
objRole.Props = objProp
objRole.PropLists = objPropLists
' Store the new role instance.
On Error Resume Next
objRole.Put_ , objContext
If Err Then
wscript.echo " Error assigning role " & strSiteRole & " to " & strComputerName & ": " & Err.Description
Err.Clear
Else
wscript.echo " Setting " & strComputerName & " to an " & strSiteRole
End If
On Error GoTo 0
' Commit the changes to the Site Control file.
Set InParams = objConnection.Get("SMS_SiteControlFile").Methods_("CommitSCF").InParameters.SpawnInstance_
InParams.SiteCode = strSiteCode
objConnection.ExecMethod "SMS_SiteControlFile", "CommitSCF", InParams, , objContext
' Cleanup
Set objRole = Nothing
Set objProp = Nothing
Set objPropLists = Nothing
Set objComponents = Nothing
Set objComponent = Nothing
Set objComponentProps = Nothing
End Function
'**********************************************************************
' Function: SetProperty
' Description: This is used to set or create entries in a site control property array.
'**********************************************************************
Function SetProperty(objConnection, objProp, strPropertyName, intValue, strValue1, strValue2)
Dim index
Dim bFoundProperty
Dim objNewProp
bFoundProperty = False
' Loop through properties until a match is found and then set the properties using the values passed in.
For index = 0 to UBound(objProp)
If objProp(index).PropertyName = strPropertyName then
bFoundProperty = TRUE
objProp(index).Value = intValue
objProp(index).Value1 = strValue1
objProp(index).Value2 = strValue2
Exit For
End if
Next
' If the property doesn't exist, then create it and set the property values using the values passed in.
If not bFoundProperty then
Set objNewProp = objConnection.Get("SMS_EmbeddedProperty").SpawnInstance_
objNewProp.PropertyName = strPropertyName
objNewProp.Value = intValue
objNewProp.Value1 = strValue1
objNewProp.Value2 = strValue2
ReDim Preserve objProp(UBound(objProp) + 1)
Set objProp(UBound(objProp)) = objNewProp
End if
' Cleanup
Set index = Nothing
Set bFoundProperty = Nothing
Set objNewProp = Nothing
End Function
'**********************************************************************
' Function: SetPropertyList
' Description: This is used to set or create entries in a site control property list array.
'**********************************************************************
Function SetPropertyList(objConnection, objPropLists, strPropertyListName, arrList)
Dim index
Dim bFoundProperty
Dim objNewProp
bFoundProperty = False
' If the Property List Name already exists, set the values using the arrList variable passed in.
For index = 0 to UBound(objPropLists)
If objPropLists(index).PropertyListName = strPropertyListName then
bFoundProperty = TRUE
objPropLists(index).Values = arrList
Exit For
End if
Next
' If the Property List Name does not exist, create it and set values using the arrList variable passed in.
If not bFoundProperty then
Set objNewProp = objConnection.Get("SMS_EmbeddedPropertyList").SpawnInstance_
objNewProp.PropertyListName = strPropertyListName
objNewProp.Values = arrList
' Resize the property list and add the new Property List Name.
ReDim Preserve objPropLists(UBound(objPropLists) + 1)
Set objPropLists(UBound(objPropLists)) = objNewProp
End if
' Cleanup
Set index = Nothing
Set bFoundProperty = Nothing
Set objNewProp = Nothing
End Function
Quick Summary
To quickly pull this altogether, this script is just another method to deploy a site role and really becomes a reality when you start to virtualize your data center. Enjoy!