Jump to content

Mass redistribute failed packages to DPs

Recommended Posts


This is a script I did ages go to fix problems when you have a lot of DPs on ConfigMgr 2012 and some of the packages are in a stuck or failed state. It's a massive pain to try and fix it manually.

' ****************************************************************************
' Purpose:   Checks all packages assigned to a DP and redistributes any with errors.
' Usage:     cscript.exe CM2012_DP_Redist.vbs
' Version:   1.0.0
' History:
' 1.0.0 20-Nov-2013 - Jonathan Bennett 
'       First version.
' ****************************************************************************

' ****************************************************************************
' Global constant and variable declarations
' ****************************************************************************

Option Explicit


' The name of the CAS/Primary site server
Public Const CASServerName = "CASSERVERNAME"

' Which DP to refresh packages for - leave this blank to check ALL DPs
Public Const DPServerName = "DPSERVERNAME"


Public Const wbemFlagReturnImmediately = 16
Public Const wbemFlagForwardOnly = 32

Dim oSWbemServices

' ****************************************************************************
' End declarations
' ****************************************************************************

' ****************************************************************************
' Main routine
' ****************************************************************************

' Connect to CM 2012 (CAS)
If ConnectServer(CASServerName) = False Then
    WScript.Echo "Unable to connect to server."
    WScript.Quit 1
End If

' Find all packages with a bad status
Dim queryString
Dim dpStatuses, dpStatus, serverName, packageID, packageDPs, packageDP, nalPath

If DPServerName = "" Then
    queryString = "SELECT Name,PackageID,MessageState FROM SMS_DistributionDPStatus WHERE MessageState > 2"
    queryString = "SELECT Name,PackageID,MessageState FROM SMS_DistributionDPStatus WHERE Name LIKE '%" & DPServerName & "%' AND MessageState > 2"
End If

Set dpStatuses = oSWbemServices.ExecQuery(queryString,, wbemFlagForwardOnly+wbemFlagReturnImmediately)
For Each dpStatus in dpStatuses
    serverName = UCase(dpStatus.Name)
    packageID = dpStatus.PackageID

    queryString = "SELECT * FROM SMS_DistributionPoint WHERE PackageID = '" & packageID & "'"
    Set packageDPs = oSWbemServices.ExecQuery(queryString,, wbemFlagForwardOnly+wbemFlagReturnImmediately)
    For Each packageDP in packageDPs
        nalPath = UCase(packageDP.ServerNalPath)

        If InStr(1, nalPath, serverName) > 0 Then
            WScript.Echo "Redistributing " & packageID & " on " & serverName & "..."
            packageDP.RefreshNow = True
            On Error Resume Next
            On Error Goto 0
        End If


WScript.Quit 0

' ****************************************************************************
' Functions
' ****************************************************************************

Function ConnectServer(ByVal serverName)
    If serverName = "" Then serverName = "."
    Dim oSWbemLocator : Set oSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
    On Error Resume Next
    Set oSWbemServices = oSWbemLocator.ConnectServer(serverName, "root\sms")
    If Err.Number <> 0 Then
        ConnectServer = False
        Exit Function
    End If
    On Error Goto 0
    Dim ProviderLoc : Set ProviderLoc = oSWbemServices.ExecQuery("Select * FROM SMS_ProviderLocation WHERE ProviderForLocalSite='True'")

    Dim Location
    For Each Location In ProviderLoc
        Set oSWbemServices = oSWbemLocator.ConnectServer(Location.Machine, "root\sms\site_" + Location.SiteCode)
        Exit For
    ConnectServer = True
End Function


More details on this blog post: https://www.autoitconsulting.com/site/deployment/mass-redistribute-packages-configmgr-2012/ 

  • Like 1

Share this post

Link to post
Share on other sites

maybe not the right place for this, but a resent sccm2012 R2 SP1 CU? version requires a patch to servers & sccm consoles to prevent a driver bloat issue. Importing 600Mb package grows to 18Gb in size. This will waist space and cause un-need strain on the DPs (possibly failures).

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • jdegraff
      By jdegraff
      I'm trying to add a bit of functionality to the FastStone File Rename dialog. I can access every control that I need to except the one that contains the files to be renamed. If I do some exploring in a vbScript shell I get
      :c  = "TTntTreeView.UnicodeClass1"
      You can see that the treeview control reports having five items, which is the number displayed. If I manually select (mouse) item #3 I can see the result by
      But I do not know how to get the text for the selected item. If "#3" is the item reference then I should be able to
      if I go strictly by the help file, but it returns nothing.
      So it appears that item 3 exists, but
      does not have any text???
      and it also appears item 9 exists (it does not)
      causes the first item to be selected, as does
      Here is the output from the Window Info tool
      >>>> Window <<<<
      Title:  Batch Image Convert / Rename
      Class:  TBatchConvert
      Position:   501, 83
      Size:   760, 520
      Style:  0x16CD0000
      ExStyle:    0x00010100
      Handle: 0x0000000001950796
      >>>> Control <<<<
      Class:  TTntTreeView.UnicodeClass
      Instance:   1
      ClassnameNN:    TTntTreeView.UnicodeClass1
      Advanced (Class):   [CLASS:TTntTreeView.UnicodeClass; INSTANCE:1]
      ID: 37030040
      Position:   354, 79
      Size:   378, 188
      ControlClick Coords:    108, 86
      Style:  0x54010039
      ExStyle:    0x00000200
      Handle: 0x0000000002350898
      >>>> Mouse <<<<
      Position:   970, 279
      Cursor ID:  0
      Color:  0xE1E1E1
      >>>> StatusBar <<<<
      >>>> ToolsBar <<<<
      >>>> Visible Text <<<<
      Batch Rename
      Images + Videos (*.jpg;*.jpe;*.jpeg;*.bmp;*.gif;*.tif;*.tiff;*.cur;*.ico;*.png;*.pcx;*.jp2;*.j2k;*.tga;*.ppm;*.wmf;*.psd;*.crw;*.nef;*.cr2;*.orf;*.raf;*.dng;*.mrw;*.pef;*.srf;*.arw;*.rw2;*.x3f;*.sr2;*.srw;*.nrw;*.rwl;*.eps;*.avi;*.mpeg;*.mpg;*.wmv;*.mov;*.mp4;*.mts;*.mkv;*.m4v)
      Search and Replace
      Use Filename Template
      No Sort
      Add All
      No Change

    • vyperhand
      By vyperhand
      I'm struggling to launch a VBS file via autoit using RunWait.  Due to the nature of the deployment tool I am using for said script, I only know that the .vbs files will be in the same directory as my AutoIt-generated .exe, but not what that path will be.  The path will look something like this:
      This is generated during deployment and I have no way of predicting the path - therefore, I am not sure how to call back to "same directory" in order to successfully launch the .vbs.
      This line is as close as I have gotten - this fires off the cmd window, but it closes immediately with out information, and the .vbs is not launched.
      RunWait (@ComSpec & " /c" & 'cscript.exe WORKPLEASE.vbs ALL /Q /NoCancel') I thought /c might be the problem, but leaving out the /c element causes me not to even see the momentary CMD window flash by.  Any help will be greatly appreciated, and thanks in advance.
    • ur
      By ur
      I am maintaining all the reusable code in a separate file as library.au3.
      In that file I have referenced some dependent files using fileinstall, so that they will be extracted when necessary.
      Problem is, if I use a function in the library.au3 in another script which doesn't require this dependent file, as I am including the whole file using include tag, it is embedding that file also.
      Is there any way to exclude that.
    • GTAVLover
      By GTAVLover
      I recently tried to use ControlClick method to send a mouse click command to a button in a application, but I noticed that it is not working when I give first parameter as a window handle (HWND). But, when I give class name or window title, it works fine. I used AutoItX3 and VBScript. 
      Following are the commands I tried in VBScript:
      Dim WINAPI: Set WINAPI = WScript.CreateObject("WinAPIWrapper.WINAPI") Dim AutoItX3: Set AutoItX3 = WScript.CreateObject("AutoItX3.Control") Dim WindowHandle: WindowHandle = WINAPI.WinAPI_FindWindow("my window title", "my window class") 'Window handle obtains fine by my wrapper function 'Above window handle is obtained as a hexadecimal string. (I.E. - 0x00000000) I tried it like: WScript.Echo CStr(AutoItX3.ControlClick(WindowHandle, "", "[CLASS:Button; INSTANCE:1]")) // DOES NOT WORK WScript.Echo CStr(AutoItX3.ControlClick(CLng("&h" + Replace(WindowHandle, "0x", "")), "", "[CLASS:Button; INSTANCE:1]")) // DOES NOT WORK WScript.Echo CStr(AutoItX3.ControlClick(000000, "", "[CLASS:Button; INSTANCE:1]")) // DOES NOT WORK WScript.Echo CStr(AutoItX3.ControlClick(0x00000000, "", "[CLASS:Button; INSTANCE:1]")) // DOES NOT WORK Only following commands work: WScript.Echo CStr(AutoItX3.ControlClick("[CLASS:my window class]", "", "[CLASS:Button; INSTANCE:1]")) // WORKS FINE WScript.Echo CStr(AutoItX3.ControlClick("My window title", "", "[CLASS:Button; INSTANCE:1]")) // WORKS FINE  
      If any of your suggestions don't work, I will have to write a wrapper function myself to send mouse click commands. I chosen AutoIt V3 because it is good specially when comes to send keystrokes to applications. Please tell me why this won't work when I give window handle as first parameter.
      Thanks in advance.
    • lattey
      By lattey
      i have a vbscript that called an autoit exe file and autoit exe file will return value to vbscript.
      vbscriptto call the exe and create array:
      Set objShell = CreateObject("WScript.Shell") objShell.Run ( "C:\Datalog\test.exe") Dim intCtr: intCtr=-1 Dim tempArr() Set UID = CreateObject("System.Collections.ArrayList") CurLot = "" For Each filelog in FileList LogFile = Split(filelog, "~")(1) Set otf = fso.OpenTextFile("C:\Datalog\" & LogFile, 1) intCtr=intCtr+1 sFile = Split(LogFile, "_") CurStep = sFile(4) Redim preserve tempArr(intCtr) tempArr(intCtr)=CurStep next autoit:
      #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> #include <ButtonConstants.au3> #include <Array.au3> Global $Count = 10 Global $CheckBox[$Count] global $array1[1] $hGUI = GUICreate("Test", 500, 500) Global $array_Pstep[10] = ["P1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "A10"] $Spacing = 24 For $i = 0 To UBound($array_Pstep) - 1 $CheckBox[$i] = GUICtrlCreateCheckbox($array_Pstep[$i], 80, $Spacing + (20 * $i), 65, 17) Next $submit = GUICtrlCreateButton("submit",10, 300, 80, 30) GUISetState() While 1 $Msg = GUIGetMsg() Switch $Msg case $submit _ArrayDisplay($array1) Case Else For $i = 0 To $Count - 1 If $CheckBox[$i] = $Msg Then MsgBox("", "Pressed", $i) _ArrayAdd($array1, $array_Pstep[$i]) ExitLoop EndIf Next EndSwitch WEnd i need to compare the array in vbscript and array return by autoit. but i dont know how to pass the value of array in autoit to vbscript. Please help.