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