Manage WSUS with Powershell

Many of you probably use WSUS as your enterprise patching solution.  For those of you who are unfamiliar with WSUS, please check out this link for more information. With WSUS 3.0, you are now able to download and install the WSUS Console to your client machine and with this, you can now make use of the API’s on your own machine instead of working on the server to perform WSUS related tasks via PowerShell. I am currently working on a WSUS module and will post it once completed. Right now I mostly have reporting functions with a couple functions that allow for setting email notifications, starting a sync and configuring the update scope.  I still have a little ways to go in building functions that will allow you to approve updates and some other things.

Once you have installed the console, you can then take advantage of the assemblies. For this posting, I will show you how to connect to the WSUS server and perform a couple simple queries for a list of all computers reporting to WSUS and also how to perform a sync and view the progress of a sync via PowerShell.

First off, you will need to add the assemblies that so you can make the connection to WSUS. Once you have done that, you can access the .NET namespaces, listed here. Then you can connect to the WSUS server using the code snippet below.  Since I am not making a secure connection (443), I set the second value to $False.

$wsusserver = "dc1"
#Load required assemblies
[void][reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration")
$wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer($wsusserver,$False)

Looking at the $wsus variable, you can see some information regarding the server such as the version and port number.

Untitled

You can also use the Get-Member cmdlet to list all of the available methods you can use for various actions against the WSUS server.

$wsus | gm

Untitled

There are too many of these to go into here, but the first one I am going to show is the GetComputerTargets() method. This method will allow you to query the WSUS server for all clients that are reporting to the server. You can use this to find out when the last check-in time was for each client, the last sync time and if the sync was successful.

For instance, if you want to find out just the last time each client has reported status, you could use something like this:

$wsus.GetComputerTargets() | Select FullDomainName, LastReportedStatusTime

Untitled

Here is a script that will perform the task for you:

function Get-WSUSClientCheckIn {
<#
.SYNOPSIS
    Retrieves the last check-in times of clients on WSUS.
.DESCRIPTION
    Retrieves the last check-in times of clients on WSUS. You will need to run this on a machine that
    has the WSUS Administrator console installed.
.PARAMETER wsusserver
    Name of WSUS server to query against.
.PARAMETER secure
    Determines if a secure connection will be used to connect to the WSUS server. If not used, then a non-secure
    connection will be used.
.NOTES
    Name: Get-LastCheckIn
    Author: Boe Prox
    DateCreated: 24SEPT2010

.LINK
    https://boeprox.wordpress.org
.EXAMPLE

#>
[cmdletbinding(
	DefaultParameterSetName = 'wsus',
	ConfirmImpact = 'low'
)]
    Param(
        [Parameter(
            Mandatory = $True,
            Position = 0,
            ParameterSetName = 'wsus',
            ValueFromPipeline = $True)]
            [string]$wsusserver,
        [Parameter(
            Mandatory = $False,
            Position = 1,
            ParameterSetName = 'wsus',
            ValueFromPipeline = $False)]
            [switch]$secure
            )
#Load required assemblies
[void][reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration")
#Connect to WSUS server
$wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer($wsusserver,$False)
#Gather all computers in WSUS
$computers = $wsus.GetComputerTargets()
#Iterate through computers to gather last check-in time
ForEach ($computer in $computers) {
   New-Object PSObject -Property @{
   Computer = $computer.FullDomainName
   LastCheckin = $computer.LastReportedStatusTime
        }
    }
}

Starting a WSUS synchronization is a little more hidden.  You have to first use the GetSubscription() method and then call the StartSynchronization() method.

$sub = $wsus.GetSubscription()
$sub.StartSynchronization()

This will kick off the sync process on the remote WSUS server. You can also monitor the sync status either from the console or even through PowerShell using the GetSynchronizationProgress() method.

Untitled

You could setup a background job to monitor the progress and then send a pop-up alert when the sync has been completed.

That is all for now, next time I will take a look at viewing the updates and target groups on the WSUS server and hopefully will have my module at least in a Beta stage to show and make available for a download to gather feedback on it.

This entry was posted in powershell, WSUS and tagged , , , . Bookmark the permalink.

9 Responses to Manage WSUS with Powershell

  1. TB says:

    Disregard my previous post. I figured it out. In case anyone else has the same question, here is the answer.
    $wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer($WindowsUpdateServer,$False,”8530″)

  2. TB says:

    What if you use port 8530? How do you set your $wsus variable then?

  3. Ozk4r says:

    Hi, Great Post, but i have one question..
    Is run this script possible without install WSUS 3.0 console on the client?

    I want to give a reduced interface to the support guy and not the full wsus console install.

  4. Pingback: Powershell: WSUS réaliser un inventaire de conformité

  5. jkavanagh58 says:

    Great post. I have used Powershell for lots of WSUS server activities but always have to result back to vbscript for managing the client.

  6. Pingback: Episode 129 – Security Ninja Dave Kennedy « PowerScripting Podcast

  7. Pingback: WSUS: Viewing Updates with PowerShell | Learn Powershell | Achieve More

Leave a comment