Adding a new DP to all existing packages

I was recently asked if I had a script to add a new DP to all existing packages in a hierarchy. I wrote something last year that does this. This is a very rough script that was written to actually troubleshoot a specific problem but it might be useful for scenarios like this. It should be noted that this script does need to be cleaned up a bit, error checking added, etc...

The script reads a CSV file that contains a list of primary site servers, child site codes, and package IDs. The script then connects to each primary site server, gets a list of child site codes, gets a list of DPs for the site code listed, and adds every DP at that child site to the package listed.

Here is an example csv file
myCentralSiteServer,CEN,CEN00001
myCentralSiteServer,SEC,CEN00001
myPrimarySiteServer,PRI,CEN00001
myPrimarySiteServer,PRS,PRI00001

So if you ran the script against this CSV file the following would happen:
- Read the CSV file, put this information into an array
- Connect to myCentralSiteServer via WMI
- Get a list of DPs for CEN
- Add all DPs in CEN to CEN00001
- Add all DPs in SEC to CEN00001
- Connect to myPrimarySiteServer via WMI
- Get a list of DPs for PRI
- Add all DPs in PRI to CEN00001
- Add all DPs in PRS to PRI00001

The interesting thing about this script is that it can be used to spread the load of package distribution over your child primary sites instead of distributing all packages from the central site.

Syntax of script: cscript.exe smsdpadd.vbs myCSVfile.csv

 
 

'Rslaten 04/2005

On Error Resume Next
Dim SMSSites(), ConnTest, SysResList(), AsyncResQuery, AsyncSiteQuery, SiteList(), DPAddArr()
Dim sysrescounter, sitecounter
WScript.Echo "SMS DP Add v1.0"
WScript.Echo ""
GetDPList
StartProcessingLoop

Sub StartProcessingLoop
 On Error Resume Next
   Dim refWMI, SMSNameSpace, refDistPoint
   For i = LBound(SMSSites) to UBound(SMSSites)
     DPInfo = Split(SMSSites(i),",")
     If ConnTest <> DPInfo(0)&",Success" Then
            ConnTestInfo = Split(ConnTest,",")
          If ConnTestInfo(1) <> "Failed" Then
             retval = ConnectToNameSpace(DPInfo(0))
              ConnTest = DPInfo(0)&","&retval
             If ConnTest = DPInfo(0)&",Success" Then
                   AsyncResQuery = ""
                  AsyncSiteQuery = ""
                 GetSysResList(DPInfo(0))
                    Do While AsyncResQuery <> "Completed" or AsyncSiteQuery <> "Completed"
                        WScript.Sleep 100
                   Loop
                   CombineArrays
                   Set refWMI = GetObject("winMgmts:\\" &DPInfo(0)&"\root\sms")
                   Set colNameSpaceQuery = refWMI.ExecQuery("select * from SMS_ProviderLocation")
                 For Each refitem in colNameSpaceQuery
                     SMSNameSpace = refitem.NamespacePath
                    Next
                   Set refWMI = Nothing
                  Set refWMI = GetObject("winMgmts:" &SMSNameSpace)
                  Set refDistPoint = refWMI.Get("SMS_DistributionPoint").SpawnInstance_
               End If
         End If
      End If
       If ConnTest = DPInfo(0)&",Success" Then
           Search = Filter(DPAddArr,"SMS_SITE="&Ucase(DPInfo(1)),TRUE,vbBinaryCompare)
            For y = LBound(Search) to UBound(Search)
             NewVars = Split(Search(y),",")
              refDistPoint.PackageID = DPInfo(2)
              refDistPoint.SiteCode = NewVars(2)
              refDistPoint.ServerNALPath = NewVars(1)
             refDistPoint.SiteName = NewVars(3)
              refDistPoint.Put_()
             WScript.Echo NOW &" - Added DP:" &NewVars(0)& " for Site:" &NewVars(2)&" to Package:"_
              &DPInfo(2)& " at Primary Site:" &DPInfo(0)
          Next
        End If
 Next
End Sub

Sub CombineArrays
    On Error Resume Next
   WScript.Echo "Combining data from arrays"
   ReDim DPAddArr(i)
  For i = 0 to UBound(DPAddArr)
     DPAddArr(i) = ""
    Next
   For i = LBound(SysResList) to UBound(SysResList)
     DP = Split(SysResList(i),",")
       Search = Filter(SiteList,DP(2),TRUE,vbBinaryCompare)
       SiteVars = Split(Search(0),",")
     ReDim Preserve DPAddArr(i)
     DPAddArr(i) = DP(0)&","&DP(1)&","&DP(2)&","&SiteVars(0)
 Next
   WScript.Echo "Done combining data"
End Sub

Sub GetSysResList(server)
    On Error Resume Next
   WScript.Echo "****************************************************"
 WScript.Echo "SMS Primary Site = " &UCase(server)
   WScript.Echo ""
 Dim colSysResQuery, sink, sink2, colSiteQuery, sQuery
  sysrescounter = 0
   sitelistcounter = 0
 Redim SysResList(sysrescounter)
    Redim SiteList(sitelistcounter)
    For i = 0 to UBound(SysResList)
       SysResList(i) = ""
  Next
       For i = 0 to UBound(SiteList)
     SiteList(i) = ""
    Next
   Set refWMI = GetObject("winMgmts:\\" &Server&"\root\sms")
  Set colNameSpaceQuery = refWMI.ExecQuery("select * from SMS_ProviderLocation")
 For Each refitem in colNameSpaceQuery
     SMSNameSpace = refitem.NamespacePath
    Next
   Set refWMI = Nothing
  Set refWMI = GetObject("winMgmts:" &SMSNameSpace)
  WScript.Echo "Querying SMS Database for SysResList data on " &server
    Set sink = wscript.CreateObject("WbemScripting.SWbemSink","SINK_")
 Set sink2 = wscript.CreateObject("WbemScripting.SWbemSink","SINK2_")
   sQuery = "select * from SMS_SystemResourceList WHERE RoleName='SMS Distribution Point'"
 colSysResQuery = refWMI.ExecQueryAsync(sink,sQuery)
 WScript.Echo "Querying SMS Database for Site data on " &server
  colSiteQuery = refWMI.ExecQueryAsync(sink2,"select * from SMS_Site")
End Sub
Sub SINK_OnObjectReady(objObject, objAsyncContext)
    On Error Resume Next
   ReDim Preserve SysResList(sysrescounter)
    SysResList(sysrescounter) = objObject.ServerName& "," &objObject.NALPath& ","_
  &objObject.SiteCode
 sysrescounter = sysrescounter + 1
End Sub
Sub SINK_OnCompleted(iHResult, objErrorObject, objAsyncContext)
  On Error Resume Next
    AsyncResQuery = "Completed"
 WScript.Echo "Done with SysResList data query"
End Sub
Sub SINK2_OnObjectReady(objObject, objAsyncContext)
  On Error Resume Next
   ReDim Preserve SiteList(Sitecounter)
 SiteList(Sitecounter) = objObject.SiteName& "," &objObject.SiteCode
 Sitecounter = Sitecounter + 1
End Sub
Sub SINK2_OnCompleted(iHResult, objErrorObject, objAsyncContext)
 On Error Resume Next
   AsyncSiteQuery = "Completed"
    WScript.Echo "Done with Site data query"
End Sub

Function ConnectToNameSpace(server)
    On Error Resume Next
   Set refWMI = GetObject("winMgmts:\\" & Server & "\root\cimv2")
   If err <> 0 Then
        WScript.Echo "Failed to connect to cimv2 Namespace on " &server
     WScript.Echo "ERROR = " &Err.Description
        ConnectToNameSpace = "Failed"
   Else
       Set refWMI = Nothing
       ConnectToNameSpace = "Success"
   End If
End Function

Sub GetDPList
    On Error Resume Next
   TXTPATH = WScript.Arguments(0)
  WScript.Echo "Getting list of DP's from " &TXTPATH
  Set txtFSO = CreateObject("Scripting.FileSystemObject")
    Set WSHShell = WScript.CreateObject("Wscript.Shell")
   WScript.Echo "****************************************************"
 strdir = WshShell.CurrentDirectory & "\" &TXTPATH
   Set WSHSHell = Nothing
    TXTPATH = strdir
    Set txtInputFile = txtFSO.OpenTextFile(TXTPATH)
    If Err <> 0 Then
        WScript.Echo "Couldn't find " &TXTPATH
      WScript.Echo "Usage: cscript.exe smsdpadd.vbs "
       WScript.Quit
    Else
       While Not txtInputFile.AtEndOfStream
           FullLine = txtInputFile.ReadLine()
          ReDim Preserve SMSSites(SiteCounter)
           SMSSites(SiteCounter) = FullLine
            szSMSSiteQuery = SiteCounter
            SiteCounter = SiteCounter + 1
       Wend
       WScript.Echo "Found " &szSMSSiteQuery + 1 & " sites"
        WScript.Echo "Done building array of Sites"
     WScript.Echo "****************************************************"
     WScript.Echo ""
 End If
End Sub

SMSDPAdd.zip