Your company's ad could live here and reach over 50,000 people a month!

Share This Post

Monitor SCCM OSD Multicast with Powershell

During a project to migrate to Windows 7 we enabled the Multicast role on the distribution points. I quickly realized that there was no easy way to get a good overview how the actual multicast session was progressing. Of course there was the option to physically go to the computers being deployed and looking at the screen to check the progress but that really didn’t feel like best way to monitor a “zero touch” installation.

After some searching on the net I found the following discussion on technet:
http://social.technet.microsoft.com/forums/en-US/winserversetup/thread/77650cb0-d22d-4050-9736-0ace84271da6
One post stated that the following command could be used find the “Master Client” (that is the slowest client in the stream and that is the computer that sets the speed for the whole multicast stream):
wdsutil /get-allmulticasttransmissions /show:clients

I did not get that command to work, I only got an error stating:
An error occurred while trying to execute the command.
Error Code: 0xC1030104
Error Description: The Deployment Server role service for Windows Deployment Services has not been configured on the server.

Ok so that don’t seem to work if you are using WDS Multicast together with SCCM OSD. Exploring the wdsutil a little bit more I found that the following command did work when using SCCM:
wdsutil /get-allnamespaces /details:Clients

The output from that command isn’t very user friendly though:
wdsutiloutput

Imagine you have 100 clients in the stream then the above output would be hard to read.

Ok, so what now? Well I though maybe PowerShell could be used to get the output from the WDS server. This turned out to be harder than I though. First of all WDS did not present anything in WMI, after searching the net I found a post that stated that WDS was a COM Object and it explained how to load it into PowerShell but not much more. Ok but at least the COM Object must be well documented on TechNet? Wrong, I couldn’t find one single piece of documentation in this area. Ok I like a good challenge so from there it were some frustrating hours of trial and error.

The result was a small PowerShell script that lists all clients connected to a specific stream in a GUI Gridview. (Using the Out-Gridview built into PowerShell)

WDSOutGrid

Much nicer than the wdsutil output right? Blinkar

To use the script simply run it on the server that holds the multicast role since the WDS COM Object only exists there and is needed for the code to work.

When the script is run it will first output all valid streams it finds and show how many clients connected to each stream:
WDSStreams
And then it will prompt you to select the stream you wish to monitor (if the stream shows Clients(0) there is really no point in selecting it):
WDSSelect

After that it will enumerate all the clients in the stream, check which one is the master client and present it in the Out-GridView shown above.

For those interested in the code here it is, I have tried to comment what I did in the code.

[sourcecode language='powershell'  collapse='true']
#=========================================================================
# PowerShell Source File -- WDSMulticastMonitor.ps1
#
# AUTHOR: 	Mattias Benninge
# MODIFIED BY:
# COMPANY:
# DATE: 2012-03-26
# VERSION: 01
# SCRIPT LANGUAGE: PowerShell
# LAST UPDATE:
# KEYWORDS: PowerShell, WDS
# DESCRIPTION: Output list of all multicast sessions on a Windows Deployment
#				Server used for multicast by SCCM
#
# KNOWN ISSUES: WDS transport role must be installed on the server so that
#				the COM Object exist.
#
# COMMENT: This script has only been tested on Windows 2008 R2 with Multicast
#			enabled as a SCCM DP Role
#
#=========================================================================

#Create the WDS Com Object
$wdsObject = New-Object -ComObject WdsMgmt.WdsManager
$wdsServer = $wdsObject.GetWdsServer("Localhost")

#Connect to the Transport server
$wdsTrans = $wdsServer.TransportServer

#Retrive all available Namespaces
$wdsNmSpcs = $wdsTrans.NamespaceManager.RetrieveNamespaces("","",$false)

#Create a Hashtable to hold the diffrent streams that the user can choose from
[hashtable]$NSChoice = $null

$Count = $wdsNmSpcs.Count
for ($i=1; $i -lt ($Count + 1); $i++){
    $ns = $wdsNmSpcs.Item($i)
    $ContentsColl = $wdsNmSpcs.Item($i).RetrieveContents()
		#Check for valid streams and add them to $NSChoice
        if ($ContentsColl.Count -ne 0){
        # Assume the $ContentsColl only contains 1 Item when using WDS with SCCM
        $content = $ContentsColl.Item(1)
        $sessioncoll = $content.RetrieveSessions()
        # Assume the $sessioncoll only contains 1 Item when using WDS with SCCM
        $session = $sessioncoll.Item(1)
        $ClientColl = $session.RetrieveClients()

            if ($NSChoice -eq $null)
            {
                $NSChoice = @{"$i" = "$($ns.Name) Clients($($ClientColl.Count))"}
            }
            else
            {
                $NSChoice.Add("$i", "$($ns.Name) Clients($($ClientColl.Count))")
            }
        }
}

#Output all valid streams
$NSChoice.GetEnumerator() | Sort-Object Name

#Prompt for user to select which stream to list clients for
    Do {
        $NSChoiceInput = Read-Host "Select a number to connect to stream or 'q' to quit"
        #Find out if user selected to quit, otherwise answer is an integer
        If ($NSChoiceInput -NotLike "q*") {
            $NSChoiceInput = $NSChoiceInput -as [int]
            }
        }
    #Make sure the choice is valid, if not prompt again until valid or q is entered
    Until ($NSChoice.ContainsKey($NSChoiceInput.ToString()) -OR $NSChoiceInput -Like "q*")
    If ($NSChoiceInput -Like "q*") {
        Break
        } 

	#Create an array to hold all Clients in the stream
   [array]$Clients = $null

   #Create a Hashtable to format the list for Out-Gridview used later
   $CliFormat = @{Label="Master Client";Expression={($_.Id -eq $session.MasterClientId)}},
   @{Label="Name";Expression={$_.Name}},
   @{Label="MacAddress";Expression={$_.MacAddress}},
   @{Label="IpAddress";Expression={$_.IpAddress}},
   @{Label="PercentCompletion";Expression={$_.PercentCompletion}},
   @{Label="JoinDuration";Expression={$_.JoinDuration}},
   @{Label="CpuUtilization";Expression={$_.CpuUtilization}},
   @{Label="MemoryUtilization";Expression={$_.MemoryUtilization}},
   @{Label="NetworkUtilization";Expression={$_.NetworkUtilization}}

   #Connect to the stream choosen by the user
   $ContentsColl = $wdsNmSpcs.Item($NSChoiceInput).RetrieveContents()

        #Make sure the stream is valid and has clients connected
        if ($ContentsColl.Count -ne 0){
        # Assume the $ContentsColl only contains 1 Item when using WDS with SCCM
        $content = $ContentsColl.Item(1)
        $sessioncoll = $content.RetrieveSessions()

        # Assume the $sessioncoll only contains 1 Item when using WDS with SCCM
        $session = $sessioncoll.Item(1)
        $ClientColl = $session.RetrieveClients()

            #Make sure there are clients connected to the stream
            If ($ClientColl.Count -ne 0)
            {
                $Count = $ClientColl.Count
                for ($i=1; $i -lt ($Count + 1); $i++){

                    if ($Clients -eq $null)
                    {
                        $Clients = $ClientColl.Item($i)
                    }
                    else
                    {
                        $Clients = $Clients + $ClientColl.Item($i)
                    }
                }
                # Output the result using a custom formated Out-GridView
                $Clients | Select-Object -property $CliFormat | Out-GridView -Title "WDS Multicast Monitor for SCCM OSD Deployments by Mattias Benninge"
            }
            else
            {
                write-host "This stream doesnt have any clients currently connected"
            }

        }
[/sourcecode]

Download:

WDSMulticastMonitor.zip

Share This Post

5 Comments

  1. Too bad Microsoft couldn’t have integrated this into the monitoring portion of the ConfigMgr 2012 console. Good work!

    • Thanks! And yes i agree, even though you can use the webreports they only provide info when the task starts and after it is complete, the hours between you’re pretty much left in the dark by SCCM.

  2. Sir just want to ask what i need to do to also output the transfer speed i try to add “TransferRate” but it does no show any transfer speed

  3. Hi Marius!

    I have uploaded a updated version of the script to my codeplex site, try that and see if it works better for you:
    http://mbtools.codeplex.com/releases/view/98794

    I have had some issues with transport speed not showing though. But that seems to be related to the WDS service not showing anything. If you dont get anything (or just 0) with wdsutil then my script wont show anything either:
    wdsutil /get-allnamespaces /details:Clients

    Hope it helps!
    /Matt

  4. Hello,

    I applied this patch to my SCCM to fix a poor multicast speed issue and now your tool doesnt seem to pick up any transmissions. Any ideas to what might be the problem?

    http://support.microsoft.com/kb/2905002/en-us

    Thanks

Leave a Reply