What’s new in R2? PowerShell and Client Notification!

Howdy everyone.  This post is continuing the series of PowerShell improvements in System Center Configuration Manager 2012 R2.  In my past few posts (Here, Here, and Here) we’ve looked at individual cmdlets available.  This post is keeping with that tradition and will focus on notifying clients using the client notification channel introduced in Service Pack 1 and a new PowerShell cmdlet to start client notification!

Now, you may be asking yourself “Heath, client notification has been around for a while, why is it relevant now?”.  Great question!  This post comes straight from work I was doing with a customer this week where we were trying to take make clients evaluate policy in an automation scenario.  Sure, we have always been able to use WMI to start a machine policy polling cycle, but here’s the thing:  that method has always required us to have all of the ports open to each individual client device.  There was no throttling, no mechanism to track the status, and overall, it worked. But it was lacking.

Enter Fast Channel Notification and Client Notification.  I won’t jump into all the details, as the Configuration Manager Team blog has a great write up (Here), but the key takeaways are that client notification removes the need for huge network access and permissions on the remote box.  Instead, Configuration Manager Fast Notification (Client Notification) use either port 10231 or port 80 to notify clients that new Machine Policy, User Policy, or System Center Endpoint Protection actions need to be taken.

Another really cool, but unknown, feature of Client Notification is we maintain a current state for all clients in the hierarchy.  What does this mean to you?  Well, if we haven’t seen a client online in the past 20 minutes, we mark it as offline so we can definitively know the status of our PCs. So, as we are automating, we can intelligently handle clients that are offline.  That’s pretty cool!

Using Client Notification via the console is a pretty easy task, though overlooked by many folks I talk with.  We’d simply grab a collection of devices or a single device, right click, select Client Notification and then select Download Computer Policy:

image

One new feature you’ll see is that in R2, we also have the ability to notify a device that we want it to grab user policy.  This is pretty handy in workstation scenarios, as we push to user-centric software deployment, we may want to tell the PC to check for new apps deployed to that user.

So, let’s jump to R2 PowerShell lab and take a peek! One of the new features in PowerShell for R2 is the ability to interact with client operations, starting with the Invoke-ClientNotification cmdlet.  As usual, let’s start by getting help on the cmdlet in question:

 Get-Help Invoke-CMClientNotification

image

 

Easy enough, looks like we really just need to specify two things:  (1) Which collection or device we want to notify and (2) the action we want to take.  In my lab, I’ve created a collection with one member, so we’ll use my “Client Notification Test” collection.  Let’s give it a try:

 Invoke-CMClientNotification -NotificationType RequestMachinePolicyNow -DeviceCollection (Get-CMDeviceCollection -Name "Client Notification Test")

Awesome, with any luck, we should be able to watch for a couple of things to happen.  First, on the site server, we can watch BGBServer.log and we can see a new Client Notification request.  We could also watch for activity in the CCMClientNotification.log on clients.  On the server side, you’ll see traffic like this in BGBServer.log indicating the push was started:

image

Now, that is great – we’ve notified clients in a notification that they need to fetch policy and start doing stuff.  We can track it through the console in the Monitoring workspace, under “Client Operations”:

image

 

The console is great, but what happens if we are wanting to automate this?  We’ll need to use Powershell, and luckily the product team has made it easy for us with a Get-ClientOperations cmdlet.  We’ll start by getting help:

 Get-Help Get-CMClientOperations

Looks like we don’t get a lot of options, but we’ll fix that up in a bit. 

For now, let’s just see what we get from Get-CMClientOperations: 

 Get-CMClientOperations

image

Hmm.  Interesting, I pushed it to a collection with 5 clients, but I don’t see any client counts yet.  Why’s that?

Well, the data we pull from behind the scenes, SMS_ClientOperationStatus, isn’t real time.  The data we see above is from a summarized task that takes place.  So, we need to invoke the summarization task.  We do track the summarization status, and if you’ll notice above, LastSummaryTime is blank.  How can we summarize that data?  We can do it through the console, but lucky for us, there’s a new cmdlet that does it for us:  Invoke-CMClientOperationSummarization:

 Invoke-CMClientOperationSummarization
 
Get-CMClientOperations
 

Ah, much better – I am seeing accurate statistics on my recent client operation:

image

 

Now, you’re probably saying – but Heath, in my automation example, I want to wait for all online clients notified before I take the next step and clean it up afterwards.  Let’s string together everything we’ve learned in this post into a nice bit of PowerShell to do exactly that!

  #Define the Collection we'll use for notification 
 $DeviceCollection = "Client Notification Test"
 
 #Invoke the Client Notification process against my designated collection 
 Invoke-CMClientNotification -NotificationType RequestMachinePolicyNow -DeviceCollection (Get-CMDeviceCollection -Name $DeviceCollection)
 
 #Summarize data, wait for summarization to complete, then get latest stats and wait some more. 
 Do 
 { 
 Invoke-CMClientOperationSummarization 
 Start-Sleep -seconds 30 
 $ClientOps = Get-CMClientOperations | where TargetCollectionName -eq $DeviceCollection 
 If ($ClientOps.CompletedClients + $ClientOps.OfflineClients -ne $ClientOps.TotalClients) 
 { 
 $AllClientsAccountedFor = $True 
 Write-Host (Get-Date).ToString("HH:mm") - $ClientOps.TotalClients clients notified. 
 Break 
 } 
 Write-Host (Get-Date).ToString("HH:mm") - Waiting for $ClientOps.FailedClients clients to complete notification. 
 }
 
 While ($AllClientsAccountedFor -eq $False)
 
 #Once we're complete, clean up our client operation 
 Remove-CMClientOperation -id $ClientOps.ID -force
 
 #Let everyone know we're complete 
 Write-Host (Get-Date).ToString("HH:mm") - Removed Client Operation $ClientOps.ID for $ClientOps.TotalClients clients within collection $ClientOps.TargetCollectionName
 

This very basic example will invoke a client notification task, and then repeatedly summarize and monitor it until we’ve accounted for all clients, and finally, delete the resulting Client Operation.  Pretty handy!  

As a recap, client notification is a huge improvement over previous methods, especially as we look to integrate Configuration Manager into automated data center operations.  Maybe you want to wrap this up into your own PowerShell function, maybe you want to use it in an Orchestrator Runbook, the automating client notifications brings a near real-time capability to Configuration Manager.

I hope this blog post gave you a good intro into what is required to programmatically start, summarize, monitor and delete Client Notification operations with PowerShell.  Do you have planned uses for Client Notification or are you currently using Client Notification for automation tasks?  I’d love to hear about it or any other feedback in the comments below!

Thanks!