Summary: Learn how to use the computer target scope with Windows PowerShell to find WSUS client computers that are missing updates.
Microsoft Scripting Guy, Ed Wilson, is here. We are halfway through WSUS Week and some really good stuff from Boe Prox. You can see Boe’s biography in the Day 1 blog. In case you need to catch up with the series on Windows Software Update Services (WSUS), the following blogs will get you up to speed:
Day 1: Introduction to WSUS and PowerShell
Day 2: Use PowerShell to Perform Basic Administrative Tasks on WSUS
Day 3: Approve or Decline WSUS Updates by Using PowerShell
Now, here is Boe…
Over the past few days, I have been showing you some basic administration examples of what you can do by using Windows PowerShell to manage a WSUS server. During the course of some of these examples, I alluded to some methods that required a Computer Target Scope object. Well, today is the day that I get to show you how you can build a Computer Target Scope object and use that with some of the existing objects we have already created.
“What is the Computer Target Scope?” you ask? The Computer Target Scope is, as the name implies, a scope that that can be used to filter a list of clients. For more information about this class, see ComputerTargetScope Class on MSDN.
Creating the Computer Target Scope object
The first thing we need to do is create the scope object, which we can then use in some of the methods we have seen. To do this will require us to create the new object from the Microsoft.UpdateServices.Administration.ComputerTargetScope class.
$computerscope = New-Object Microsoft.UpdateServices.Administration.ComputerTargetScope
Simple enough to do, and we can choose to leave the default properties that are already set for this object if we want to.
So as a default object, this will reference all clients on the WSUS server. Fortunately, you can edit most of these properties to narrow down the clients that you want to use. Here is a list of the editable properties:
ExcludedInstallationStates
|
Gets or sets the installation states to exclude. |
FromLastReportedStatusTime
|
Gets or sets the earliest reported status time. |
FromLastSyncTime
|
Gets or sets the earliest last synchronization time to search for. |
IncludedInstallationStates
|
Gets or sets the update installation states to search for. |
IncludeDownstreamComputerTargets
|
Gets or sets whether or not clients of a downstream server, not clients of this server, should be included. |
IncludeSubgroups
|
Gets or sets whether the ComputerTargetGroups property should include descendant groups. |
NameIncludes
|
Gets or sets a name to search for. |
OSFamily
|
Gets or sets the operating system family for which to search. |
ToLastReportedStatusTime
|
Gets or sets the latest last reported status time to search for. |
ToLastSyncTime
|
Gets or sets the latest last synchronization time to search for. |
Working with the Computer Target Scope
Now, if you remember from the previous posts, there are some methods from the Update object (Microsoft.UpdateServices.Internal.BaseApi.Update) and from the WSUS object (Microsoft.UpdateServices.Internal.BaseApi.UpdateServer) that require a computer scope object to work.
Let’s take a look at some of these methods from the respective objects and see what we are able to pull.
[void][reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration")
#Connect to the WSUS Server and create the wsus object
$wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer('dc1',$False)
#Create a computer scope object
$computerscope = New-Object Microsoft.UpdateServices.Administration.ComputerTargetScope
#Find all clients using the computer target scope
$wsus.GetComputerTargets($computerscope)
By leaving the default properties, we will pull every client from the WSUS server.
Another method that we can use, which provides a report on the computers that match the scope filter is GetComputerStatus(). This method requires that you have a computer scope object and that you define a Microsoft.UpdateServices.Administration.UpdateSources object, which consists of All, Microsoft Update, or Other. Let’s give it a look.
$Wsus.GetComputerStatus($computerscope,[ Microsoft.UpdateServices.Administration.UpdateSources]::All)
You might be wondering why we are seeing mostly 0s here. If you look closely, you can see that only the areas where it mentions the computer targets are populated. This is by design for this object’s method because we only specified to get the status of the computers that match the scope filter.
Now, looking at the update object’s method, I can see a couple of methods that are available and require the computer scope.
GetSummary()
This will give us a summary of whether the clients that are specified in the scope require the update.
$updates = $wsus.SearchUpdates('Update for Windows Server 2003 (KB938759)')
$update = $updates[0]
$update.GetSummary($computerscope)
UnknownCount : 0
NotApplicableCount : 2
NotInstalledCount : 0
DownloadedCount : 1
InstalledCount : 0
InstalledPendingRebootCount : 0
FailedCount : 0
IsSummedAcrossAllUpdates : False
UpdateId : c2cdd066-7a03-4e7f-976c-139b5de943ed
ComputerTargetGroupId : 00000000-0000-0000-0000-000000000000
ComputerTargetId :
LastUpdated : 12/10/2011 7:08:29 AM
By looking at the data provided, I can see that only 1 client out of the 3 require this update and that it has already been downloaded to that client. This is a nice way of providing a report of a specific update’s status for clients. But the problem is…which client requires the update? I will show you how to use the GetUpdateInstallationInfoPerComputerTarget() method on the Update object.
$update.GetUpdateInstallationInfoPerComputerTarget($ComputerScope)
Although it does tell you which client ID requires the update, it’s not what I would call “humanly readable” by any means. But this is Windows PowerShell, after all, and we can certainly make this better for us to read.
$update.GetUpdateInstallationInfoPerComputerTarget($ComputerScope) |
Select @{L='Client';E={$wsus.GetComputerTarget(([guid]$_.ComputerTargetId)).FulldomainName}},
@{L='TargetGroup';E={$wsus.GetComputerTargetGroup(([guid]$_.UpdateApprovalTargetGroupId)).Name}},
@{L='Update';E={$wsus.GetUpdate(([guid]$_.UpdateId)).Title}},
UpdateInstallationState,UpdateApprovalAction
Much better! Now we have something that not only tells us which client, but actually gives us the name of the client without giving us a GUID to try to guess with. I also translated the Target Group ID and the Update ID so that everything is much easier to read.
Well, that wraps it up for today. Tomorrow I will jump into working with the Update Scope object and performing queries that use that object.
~Boe
Boe, thank you for another great blog about using the WSUS object model. WSUS Week will continue tomorrow.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy