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
  1. <
  2. '********************************************************************
  3. ' Main routine
  4. '********************************************************************
  5.     On Error Resume Next
  6.     ' Set variables (site code, system to configure, domain).  
  7.     strSiteCode     = "{ConfigMgr Site Code}"
  8.     strComputerName = "{Distribution Point Server Name}"
  9.     strDomainName   = "{DP Domain Name}"
  10.     strSiteServer = "{DP Site Server Name}"
  11.     strSmsAdmin    = "{ConfigMgr Admin\Service Account}"
  12.     strSmsAdminPwd = "{ConfigMgr Admin\Service Account Password}"
  13.     
  14.     ' Connect to the Configuration Manager server.
  15.     Set objConnection = ConnectToSMS(strSiteCode)
  16.     
  17.     ' Load the the site control file.
  18.     Set objContext = CreateObject("WbemScripting.SWbemNamedValueSet")
  19.     objContext.Add "SessionHandle", objConnection.ExecMethod("SMS_SiteControlFile", "GetSessionHandle").SessionHandle
  20.     
  21.     ' Enable site system.
  22.     EnableSiteRole objConnection, objContext, "SMS Site System", strComputerName, strSiteCode, strDomainName
  23.     ' Enable site role(s).
  24.     ' Uncomment site roles to install.
  25.     ' ---------------------------------
  26.     EnableSiteRole objConnection, objContext, "SMS Distribution Point", strComputerName, strSiteCode, strDomainName    
  27.     
  28.     ' Release the site control file
  29.     objConnection.Get("SMS_SiteControlFile").ReleaseSessionHandle objContext.Item("SessionHandle").Value
  30.     ' Cleanup
  31.     Set strSiteCode     = Nothing
  32.     Set strComputerName = Nothing
  33.     Set strDomainName   = Nothing
  34.     Set objConnection   = Nothing
  35.     Set objContext      = Nothing
  36.     
  37. '**********************************************************************
  38. ' Function: ConnectToSMS
  39. ' Description: This routine makes a connection to the specified site code.
  40. '**********************************************************************
  41. Function ConnectToSMS(strSiteCode)
  42.     Dim objLocator
  43.     Dim objConnection
  44.     ' Initialization
  45.     Set objLocator = CreateObject("WbemScripting.SWbemLocator")
  46.     ' Find the provider server
  47.     
  48.     Set objConnection = objLocator.ConnectServer(strSiteServer, "root\sms\site_" & strSiteCode, strSmsAdmin, strSmsAdminPwd )
  49.     ' Return the connection object
  50.     Set ConnectToSMS = objConnection
  51. End Function
  52. '**********************************************************************
  53. ' Function:    Enable DP Site SiteRole
  54. ' Description: This enables the specified DP site system role.
  55. '**********************************************************************
  56. Function EnableSiteRole(objConnection, objContext, strSiteRole, strComputerName, strSiteCode, strDomainName)
  57.     Dim objRole
  58.     Dim objProp
  59.     Dim objPropLists
  60.     Dim objComponents
  61.     Dim objComponent
  62.     Dim objComponentProps
  63.     Dim strTempSiteRole
  64.     ' Refresh our copy of the site control file.
  65.     objConnection.ExecMethod "SMS_SiteControlFile.Filetype=1,Sitecode='" & strSiteCode & "'", "RefreshSCF", , , objContext
  66.     
  67.     ' Note: There is no separate site role for a Branch Distribution Point, instead the IsPeerDP property is enabled
  68.     '       on a SMS Distribution Point role.  
  69.     ' Workaround: Set variable to SMS Distribution Point, if the site role is a Branch Distribution Point.
  70.     If strSiteRole = "SMS Branch Distribution Point" Then
  71.         strTempSiteRole = "SMS Distribution Point"
  72.     Else
  73.         strTempSiteRole = strSiteRole
  74.     End If
  75.     
  76.     'Retrieve the site control object.
  77.     On Error Resume Next
  78.     Set objRole = objConnection.Get("SMS_SCI_SysResUse.FileType=2,ItemName=" & Chr(34) & _
  79.         "[\" & Chr(34) & "Display=\\\\" &  strComputerName & "\\\" & Chr(34) & "]MSWNET:[\" & Chr(34) & "SMS_SITE=" & _
  80.         strSiteCode & "\" & Chr(34) & "]\\\\" & strComputerName & "\\," & strTempSiteRole & Chr(34) & ",ItemType=" & Chr(34) & _
  81.         "System Resource Usage" & Chr(34) & ",SiteCode=" & Chr(34) & strSiteCode & Chr(34), , objContext)
  82.         
  83.     ' If the site role already exists, then get the current properties.
  84.     If Err.Number = 0 then  
  85.         objProp = objRole.Props
  86.         wscript.echo strTempSiteRole & " already exists. "
  87.         wscript.echo "Attempting to enable the site role."
  88.     ' If the site role is not found, then create it.
  89.     ElseIf CStr(Hex(Err.Number)) = "80041002" then  
  90.         Set objRole = objConnection.Get("SMS_SCI_SysResUse").SpawnInstance_
  91.         objRole.NALPath  = "[" & Chr(34) & "Display=\\" &  strComputerName & "\" & Chr(34) & "]MSWNET:[" & Chr(34) & "SMS_SITE=" & strSiteCode & Chr(34) & "]\\" & strComputerName & "\"
  92.         objRole.NALType  = "Windows NT Server"
  93.         objRole.RoleName = strTempSiteRole
  94.         objRole.Sitecode = strSiteCode
  95.         objProp = Array()
  96.         wscript.echo strTempSiteRole & " doesn't exist. "
  97.         wscript.echo "Attempting to create the site role."
  98.         
  99.     ' On any other error, fail and exit the function.
  100.     Else
  101.         EnableSiteRole = False  
  102.         wscript.echo "Unexpected error: 0x" & Hex(Err.Number) & " - " & Err.Description
  103.         wscript.echo "Not attempting to enable the site role."  
  104.         Exit Function
  105.         
  106.     End If
  107.     On Error GoTo 0
  108.     
  109.     objPropLists = objRole.PropLists
  110.     If IsNull(objPropLists) then
  111.         objPropLists = Array()
  112.     End if
  113.     ' Set the appropriate properties for the specified role.
  114.     Select Case strSiteRole
  115.                     
  116.         Case "SMS Distribution Point"
  117.             SetProperty objConnection, objProp, "Site Info", 0, strComputerName, strSiteCode
  118.             SetProperty objConnection, objProp, "BITS download", 1, "", ""
  119.             SetProperty objConnection, objProp, "Is protected", 0, "", ""
  120.             SetProperty objConnection, objProp, "IsAnonymousEnabled", 1, "", ""
  121.             SetProperty objConnection, objProp, "Server Remote Name",0, strComputerName & "." & strDomainName, ""
  122.         Case "SMS Site System"
  123.             SetProperty objConnection, objProp, "Server Remote Name",0, strComputerName & "." & strDomainName, ""
  124.             SetProperty objConnection, objProp, "IsProtected",0, "", ""
  125.             SetProperty objConnection, objProp, "Server Remote Public Name",0, "", ""
  126.             SetProperty objConnection, objProp, "FDMOperation",0, "", ""            
  127.                                                     
  128.         Case Else
  129.             wscript.echo " Invalid role specified: " & strSiteRole
  130.             EnableSiteRole = False
  131.             Exit Function
  132.     End Select
  133.     ' Save the (possibly) updated properties.
  134.     objRole.Props = objProp
  135.     objRole.PropLists = objPropLists
  136.     ' Store the new role instance.
  137.     On Error Resume Next
  138.     objRole.Put_ , objContext
  139.     If Err Then
  140.         wscript.echo " Error assigning role " & strSiteRole & " to " & strComputerName & ": " & Err.Description
  141.         Err.Clear
  142.     Else
  143.         wscript.echo " Setting " & strComputerName & " to an " & strSiteRole
  144.     End If
  145.     On Error GoTo 0
  146.     
  147.     ' Commit the changes to the Site Control file.
  148.     Set InParams = objConnection.Get("SMS_SiteControlFile").Methods_("CommitSCF").InParameters.SpawnInstance_
  149.     InParams.SiteCode = strSiteCode
  150.     objConnection.ExecMethod "SMS_SiteControlFile", "CommitSCF", InParams, , objContext
  151.     
  152.     ' Cleanup
  153.     Set objRole            = Nothing
  154.     Set objProp            = Nothing
  155.     Set objPropLists       = Nothing
  156.     Set objComponents      = Nothing
  157.     Set objComponent       = Nothing
  158.     Set objComponentProps  = Nothing
  159.     
  160. End Function
  161. '**********************************************************************
  162. ' Function:    SetProperty
  163. ' Description: This is used to set or create entries in a site control property array.
  164. '**********************************************************************
  165. Function SetProperty(objConnection, objProp, strPropertyName, intValue, strValue1, strValue2)
  166.     Dim index
  167.     Dim bFoundProperty
  168.     Dim objNewProp
  169.         bFoundProperty = False
  170.         ' Loop through properties until a match is found and then set the properties using the values passed in.
  171.         For index = 0 to UBound(objProp)
  172.             If objProp(index).PropertyName = strPropertyName then
  173.                     
  174.                 bFoundProperty = TRUE
  175.                 objProp(index).Value = intValue
  176.                 objProp(index).Value1 = strValue1
  177.                 objProp(index).Value2 = strValue2
  178.                 Exit For
  179.             End if
  180.         Next
  181.     ' If the property doesn't exist, then create it and set the property values using the values passed in.    
  182.     If not bFoundProperty then
  183.     
  184.         Set objNewProp = objConnection.Get("SMS_EmbeddedProperty").SpawnInstance_
  185.         objNewProp.PropertyName = strPropertyName
  186.         objNewProp.Value = intValue
  187.         objNewProp.Value1 = strValue1
  188.         objNewProp.Value2 = strValue2
  189.         ReDim Preserve objProp(UBound(objProp) + 1)
  190.         Set objProp(UBound(objProp)) = objNewProp
  191.         
  192.     End if
  193.     ' Cleanup
  194.     Set index           = Nothing
  195.     Set bFoundProperty  = Nothing
  196.     Set objNewProp      = Nothing
  197.       
  198. End Function
  199. '**********************************************************************
  200. ' Function:    SetPropertyList
  201. ' Description: This is used to set or create entries in a site control property list array.
  202. '**********************************************************************
  203. Function SetPropertyList(objConnection, objPropLists, strPropertyListName, arrList)
  204.     Dim index
  205.     Dim bFoundProperty
  206.     Dim objNewProp
  207.     bFoundProperty = False
  208.     
  209.     ' If the Property List Name already exists, set the values using the arrList variable passed in.
  210.     For index = 0 to UBound(objPropLists)
  211.         If objPropLists(index).PropertyListName = strPropertyListName then
  212.             bFoundProperty = TRUE
  213.             objPropLists(index).Values = arrList
  214.             Exit For
  215.         End if
  216.     Next
  217.     ' If the Property List Name does not exist, create it and set values using the arrList variable passed in.
  218.     If not bFoundProperty then
  219.         Set objNewProp = objConnection.Get("SMS_EmbeddedPropertyList").SpawnInstance_
  220.         objNewProp.PropertyListName = strPropertyListName
  221.         objNewProp.Values = arrList
  222.         ' Resize the property list and add the new Property List Name.
  223.         ReDim Preserve objPropLists(UBound(objPropLists) + 1)
  224.         Set objPropLists(UBound(objPropLists)) = objNewProp
  225.     End if
  226.     ' Cleanup
  227.     Set index           = Nothing
  228.     Set bFoundProperty  = Nothing
  229.     Set objNewProp      = Nothing
  230.     
  231. 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!

Digg This