Removing a retired DP from all your packages

When you remove an SMS 2003 Distribution Point (DP) from a site, and existing packages have been distributed to this DP, those packages may not be removed. If you look at that package in the admin console you will notice that the the type has changed from "Server" to "Unknown". The Package Status will also show a type of nothing instead of "Server".

To properly remove these you can use the Manage Distribution Points Wizard to uncheck the DP before removing it as a site system. This can be a tedious task if you have hundreds or thousands of packages. An alternative to doing this manually is to use the SDK. I have attached a script that automates this task. Note, the script does validate whether your DP still exists. If you have already removed the DP as a site system and want to clean it up then you will have to remove the call to ValidDP(). Take note that if you do this then Distribution Manager will attempt to remove the package files from the DP so if it doesn't exist on the network then you will get errors in the distmgr.log and Distribution Manager component.

 'Rslaten 03/2005

On Error Resume Next

WScript.Echo ""
WScript.Echo "SMSDPClean v1.3"
WScript.Echo "Usage: cscript.exe SMSDPClean <CenSiteServerName> <NameOfDP>"
WScript.Echo "Example: cscript.exe SMSDPClean.vbs myCentralSiteServer myDistributionPoint"
WScript.Echo ""

Dim SMSSiteServer, SMSNameSpace, oLocator, oServices, bDone

'Get Args, add error checking here if needed
SMSSiteServer = WScript.Arguments(0)
DP = WScript.Arguments(1)

'Get SMS namespace
SMSNameSpace = GetSMSNameSpace(SMSSiteServer)

'Connect to SMS namespace
Set oLocator = CreateObject("WbemScripting.SWbemLocator")
Set oServices = oLocator.ConnectServer(SMSSiteServer, SMSNameSpace,,,,,128)
If Err.number <> 0 Then
    WScript.Echo "Error connecting to " &SMSNameSpace& " on " &SMSSiteServer& ": " &Err.Number
    Set oLocator = Nothing
    Set oServices = Nothing
    WScript.Quit
End If

'Call main procedure
PackageLoop

'Loop until async task is done
Do While not bDone
    WScript.Sleep 1000
Loop

Set oLocator = Nothing
Set oServices = Nothing
WScript.Quit


'Functions
'''''''''''''''''''''''''''''''''''''''''
'
'GetSMSNameSpace Function
'
'''''''''''''''''''''''''''''''''''''''''
Function GetSMSNameSpace(SiteServer)
    On Error Resume Next
    Dim colNameSpaceQuery, refitem, refWMI
    Set refWMI = GetObject("winMgmts:\\" &SiteServer&"\root\sms")
    If Err.number <> 0 Then
        WScript.Echo "Error connecting to SMS namespace on " &SiteServer
        WScript.Quit
    End If
    Set colNameSpaceQuery = refWMI.ExecQuery("select * from SMS_ProviderLocation")
    For Each refitem in colNameSpaceQuery
        GetSMSNameSpace = refitem.NamespacePath
    Next
    Set colNameSpaceQuery = Nothing
    Set refitem = Nothing
    Set refWMI = Nothing
End Function

'''''''''''''''''''''''''''''''''''''''''
'
'ValidDP Function
'
'''''''''''''''''''''''''''''''''''''''''
Function ValidDP(DP, SiteCode)
    On Error Resume Next
    Dim SysRes, start, finish, tempDP
    ValidDP = False
    Set SysRes = oServices.ExecQuery("select * from sms_sci_sysresuse where SiteCode = '" &SiteCode& "'")
    For each res in SysRes
        start = InStr(res.NALPath,"=\\") + 3
        finish = InStr(res.NALPath,"]MSWNET") - 2
        tempDP = mid(res.NALPath,start,finish-start)
        If (UCase(tempDP) = UCase(DP)) and (res.RoleName = "SMS Distribution Point") Then
            Set SysRes = Nothing
            ValidDP = True
            Exit Function
        End If
    Next
    Set SysRes = Nothing
End Function

'''''''''''''''''''''''''''''''''''''''''
'
'PackageLoop SubRoutine
'
'''''''''''''''''''''''''''''''''''''''''
Sub PackageLoop
    On Error Resume Next
    Dim sinkcol, retValuecol
    bDone = False
    Set sinkcol = wscript.CreateObject("WbemScripting.SWbemSink","SINKCOL_")
    retValuecol = oServices.ExecQueryAsync(sinkcol,"SELECT * FROM SMS_DistributionPoint")
    If Err.Number <> 0 Then
        WScript.Echo "Error running query:" &err.description
        WScript.Quit
    End If
End Sub
Sub SINKCOL_OnObjectReady(objDP, objAsyncContext)
    On Error Resume Next
    Dim start, finish, tempDP
    start = InStr(objDP.ServerNALPath,"=\\") + 3
    finish = InStr(objDP.ServerNALPath,"]MSWNET") - 2
    tempDP = mid(objDP.ServerNALPath,start,finish-start)
    If UCase(tempDP) = UCase(DP) Then
        WScript.Echo "Found " &DP& " on "& objDP.SiteCode& " linked to package " &objDP.PackageID
        If ValidDP(DP, objDP.SiteCode) Then
            WScript.Echo "Validated " &DP& " for site " &objDP.SiteCode
            objDP.Delete_()
            If Err.number <> 0 Then
                WScript.Echo "Failed to delete " &DP& " from package " &objDP.PackageID& " on site " &objDP.SiteCode
                WScript.Echo "Error = " &Err.number& " - " &Err.Description
            Else
                WScript.Echo "Successfully deleted " &DP& " from package " &objDP.PackageID& " on site " &objDP.SiteCode
            End If
        Else
            WScript.Echo DP& " is not specified as a distribution point on site " &objDP.SiteCode
        End If
    End If
End Sub
Sub SINKCOL_OnCompleted(iHResult, objErrorObject, objAsyncContext)
    bDone = True
End Sub

DPClean.zip