Don't wait for WSUS: Deploy updates immediately with PDQ Deploy & Inventory

Brock Bingham candid headshot
Brock Bingham|Updated July 13, 2021
WSUS Main
WSUS Main

WSUS is one of the more divisive topics that I see routinely brought up among IT folks.  Some people love it and swear by it.  Others have a deep loathing for the updating solution and either begrudgingly use it or look for alternatives to replace it.  Personally, I fall somewhere in the middle.  It does what it's supposed to do for the most part, but I also feel like it could do it so much better.  So instead of going into who's right and who's wrong (though I'm definitely right), let's instead find out how PDQ Inventory and PDQ Deploy can take away some of the pain points of using WSUS and make all our techy lives that much sweeter.

What Is WSUS

WSUS (Windows Server Update Services) is Microsoft's solution for managing and distributing Microsoft product updates.  WSUS has been around for years, allowing sysadmins to patch their environments from a centralized system.  Despite its longevity, one of the complaints often brought up against WSUS is its lack of innovation over the years.  While there have been minor changes and improvements here and there, I think Microsoft's philosophy with WSUS is, "if it's not broken, don't improve it."

Administrators configure WSUS to download updates for the Microsoft operating systems and products they support in their environments.  The core WSUS workflow is essentially approving or denying updates for specific computer groups.  Client workstations will eventually detect, download, and install approved updates (eventually being the keyword).  Most client/server interactions can be configured using group policy, which does provide an okay level of granularity but doesn't offer complete control over the installation process.

I like to compare WSUS to my kids.  If I ask my kids to clean their rooms, I know it'll get done; I just don't know if it'll get down today, tomorrow, or a week from now.  Similarly, I know WSUS will eventually get those approved updates pushed out; I just don't know exactly when.  Sure, I can configure an aggressive detection frequency and installation schedule, but that can get pretty taxing and inconvenient for clients.

For most updates, this behavior is acceptable.  In fact, installing non-critical updates a week or two after coming out is pretty standard practice.  You don't want to be Microsoft's guinea pig after all.  However, when a critical update needs to be pushed out to your environment immediately, many users will find WSUS inadequate and not the right tool for the job.

The Right Tools For The Job

Instead of struggling with WSUS when you need to get those critical updates pushed out, we can use PDQ Inventory and PDQ Deploy to ensure the job gets done immediately.  PDQ Inventory specializes in collecting information from the computers in your environment.  We can also use it to scan for available Windows updates from WSUS, allowing us to use that data to build reports and dynamic collections.  With PDQ Deploy, we can create packages for Windows updates and push them out to our entire environment in minutes.

If you don't already have PDQ Inventory and PDQ Deploy and you want to follow along with this guide, we've got you covered.  You can download a free 14-day trial of Inventory and Deploy to try it out for yourself.

Using A PowerShell Scanner To Check For Available WSUS Updates

The first thing we'll want to do is to scan our computers to see what updates they have available to them from WSUS.  We can accomplish this with a PowerShell scanner.  If you haven't already checked out our PowerShell Scanner repository on GitHub, I highly recommend it.  It has tons of great PowerShell scanners that add to the already fantastic functionality of PDQ Inventory.  Make sure to look over the README file, which will guide you through using Git to clone the GitHub repository.

If you choose to clone the repository with Git, the PowerShell scanner you'll want to use is the scanner called Get Available Windows Updates.  You'll also need to modify one line of the PowerShell script because, in its current form, it checks online for available windows updates instead of WSUS.

Change line 5 from:

$GWU = Get-WindowsUpdate

to

$GWU = Get-WindowsUpdate -WindowsUpdate

After making that change, the only thing you need to do is import the XML file into PDQ Inventory.

  • In PDQ Inventory, click File > Import

  • Browse to the Get Available Windows Update folder and select the Scan Profile.xml file and click Open

You'll receive a message letting you know the import completed, after which you should find your new scan profile in the Scan Profiles window.

wsus1

If GitHub isn't your thing, I'll guide you through creating this PowerShell scanner from scratch.  Here is the code you'll need for the scanner.  You can either copy it and save it as a PowerShell file and point to it from the PowerShell scanner or paste the code directly into the PowerShell scanner.

$ModuleName = "PSWindowsUpdate" # Install the module if it is not already installed, then load it. Try { $null = Get-InstalledModule $ModuleName -ErrorAction Stop } Catch { if ( -not ( Get-PackageProvider -ListAvailable | Where-Object Name -eq "Nuget" ) ) { $null = Install-PackageProvider "Nuget" -Force } $null = Install-Module $ModuleName -Force } $null = Import-Module $ModuleName -Force # The Collection object this cmdlet emits is really weird. # We have to assign it to a variable to get it to work properly in a pipeline. # The "-WindowsUpdate" parameters checks local intranet sources (WSUS) for available updates instead of online $GWU = Get-WindowsUpdate -WindowsUpdate If ($null -ne $GWU) { $GWU | ForEach-Object { [PSCustomObject]@{ "KB" = $_.KB "Title" = $_.Title "Size" = $_.Size #"Status" = $_.Status #"RebootRequired" = $_.RebootRequired # Indicates whether the update is flagged to be automatically selected by Windows Update. #"AutoSelectOnWebSites" = $_.AutoSelectOnWebSites #"CanRequireSource" = $_.CanRequireSource #"Deadline" = $_.Deadline #"DeltaCompressedContentAvailable" = $_.DeltaCompressedContentAvailable #"DeltaCompressedContentPreferred" = $_.DeltaCompressedContentPreferred #"EulaAccepted" = $_.EulaAccepted #"IsBeta" = $_.IsBeta #"IsDownloaded" = $_.IsDownloaded #"IsHidden" = $_.IsHidden #"IsInstalled" = $_.IsInstalled #"IsMandatory" = $_.IsMandatory #"IsPresent" = $_.IsPresent #"IsUninstallable" = $_.IsUninstallable #"UninstallationNotes" = $_.UninstallationNotes #"LastDeploymentChangeTime" = $_.LastDeploymentChangeTime # Convert Decimal to 64-bit Integer #"MaxDownloadSize" = [UInt64]$_.MaxDownloadSize #"MinDownloadSize" = [UInt64]$_.MinDownloadSize "MsrcSeverity" = $_.MsrcSeverity # MHz #"RecommendedCpuSpeed" = $_.RecommendedCpuSpeed # https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdate-get_recommendedharddiskspace #"RecommendedHardDiskSpace" = [UInt64]($_.RecommendedHardDiskSpace * 1MB) # https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdate-get_recommendedmemory #"RecommendedMemorySize" = [UInt64]($_.RecommendedMemory * 1MB) #"ReleaseNotes" = $_.ReleaseNotes "SupportUrl" = $_.SupportUrl # https://docs.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-updatetype "Type" = switch ($_.Type) { 1 { "Software" } 2 { "Driver" } Default { "Unknown" } } "Description" = $_.Description #"DeploymentAction" = $_.DeploymentAction #"DownloadPriority" = $_.DownloadPriority # Indicates whether an update can be discovered only by browsing through the available updates. #"BrowseOnly" = $_.BrowseOnly #"PerUser" = $_.PerUser #"AutoSelection" = $_.AutoSelection #"AutoDownload" = $_.AutoDownload } } } else { [PSCustomObject]@{ "KB" = $null "Title" = $null "Size" = $null #"Status" = $null #"RebootRequired" = $null # Indicates whether the update is flagged to be automatically selected by Windows Update. #"AutoSelectOnWebSites" = $null #"CanRequireSource" = $null #"Deadline" = $null #"DeltaCompressedContentAvailable" = $null #"DeltaCompressedContentPreferred" = $null #"EulaAccepted" = $null #"IsBeta" = $null #"IsDownloaded" = $null #"IsHidden" = $null #"IsInstalled" = $null #"IsMandatory" = $null #"IsPresent" = $null #"IsUninstallable" = $null #"UninstallationNotes" = $null #"LastDeploymentChangeTime" = $null # Convert Decimal to 64-bit Integer #"MaxDownloadSize" = $null #"MinDownloadSize" = $null "MsrcSeverity" = $null # MHz #"RecommendedCpuSpeed" = $null # https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdate-get_recommendedharddiskspace #"RecommendedHardDiskSpace" = $null # https://docs.microsoft.com/en-us/windows/win32/api/wuapi/nf-wuapi-iupdate-get_recommendedmemory #"RecommendedMemorySize" = $null #"ReleaseNotes" = $null "SupportUrl" = $null # https://docs.microsoft.com/en-us/windows/win32/api/wuapi/ne-wuapi-updatetype "Type" = $null "Description" = $null #"DeploymentAction" = $null #"DownloadPriority" = $null # Indicates whether an update can be discovered only by browsing through the available updates. #"BrowseOnly" = $null #"PerUser" = $null #"AutoSelection" = $null #"AutoDownload" = $null } }

You'll notice that a lot of the properties in this script are commented out.  This object returns quite a few properties, many of which are probably useless to most people.  Feel free to uncomment any property you want to include in your results.  Just make sure to uncomment it from the top section as well as the null section.

To create the PowerShell scanner in PDQ Inventory:

  • Click Scan Profiles

    wsus2
  • Click New

  • Give the scan profile a name

  • Click Add > PowerShell

  • Provide a scanner name (it can be given the same name as the scan profile)

  • If you saved the script to a .ps1 file, use the ellipsis button to point to the file.  Otherwise, select Script and paste the script into the given field

  • Click OK

    wsus3
  • If you want to have this scanner run on a schedule, click the Triggers tab. Otherwise, click OK to close the Scan Profile

With the scan profile created, we can now run it against computers.  If some computers in your environment use WSUS and some use Microsoft online for updates, you'll want to create a collection for just the computers using WSUS to target.

To run the scan profile against all computers in PDQ Inventory:

  • Right-click on All Computers

  • Click Scan Collection > (Your Scan Profile Name)

  • You'll see the scan status of your computers change to indicate that the scan has started

    wsus4
  • Once the scan is complete, double-click on a computer to open the computer details window

  • Click the PowerShell menu option

  • Change the drop-down menu to the correct PowerShell scanner

    wsus5
  • You should now be able to see the results of the scan

    wsus6

With all this information now in Inventory, not only is it easier to review and digest than WSUS, but we can also use it to build collections and reports.

Build Dynamic Collections From PowerShell Scanner Data

If you have an update that needs to get pushed out immediately, the first step is to identify the computers that need the update installed.  We can accomplish this pretty easily by building a dynamic collection of computers that require the update.  One thing to note is that you need to ensure you are only grouping computers with the same OS versions.  Otherwise, you may deploy an incorrect update to a computer which will fail.  

  • In PDQ Inventory, click New Dynamic Collection

  • Give the collection a name

  • Change the first filter to the name of the WSUS PowerShell scanner

  • For the Column, select KB

  • Choose Contains for the comparison

  • Enter the KB number into the value field

  • Add a new filter by clicking the Add Value Filter button

  • For the filter choose Computer

  • For the column, choose SP / Release

  • In the comparison column, select Equals

  • In the value, enter the OS version you are targeting

  • Click OK to finish making the collection

Once you've finished, the collection should look similar to this.

wsus7

The collection should automatically populate with the computers that meet the criteria.  In my case, it should populate with computers that need KB4577586 installed and are on version 2004. Of course, you can further filter out information as you need, such as architecture, but this is all I need for my environment.

wsus8

Building Reports From Dynamic Collections

One of the best things about dynamic collections is that you can use them to easily build reports.  

  • In PDQ Inventory, right-click on the dynamic collection you just created

  • Click New > Report From Collection

    wsus9
  • The Report Builder window should open

  • By default, the filters from the dynamic collection are already added.  You can customize the report further, or you can add additional Columns to the report to include more information

  • When you are finished, click Save and Run Report

wsus10

Deploying Updates Using PDQ Deploy

Okay, we've got our data and our dynamic collection; now it's time to get the update deployed.  The easiest way to obtain the update is to download it from the Microsoft Update Catalog.  Enter the KB number you need, and you'll be given a list of updates to download with that KB number for different operating systems.  Make sure you download the correct update for the operating system you are targeting.  In my case, I'm looking for KB4577586 for Win 10 x64 version 2004.

wsus11

This particular update says it's available for version 1903 and later.  Click the download button to download the update and save it to your PDQ Deploy repository.

With the update downloaded, open PDQ Deploy and we'll go through building a custom package.

  • Click New Package

  • Give the package a name

  • Click New Step > Install

  • Point the update file by clicking the ellipsis button

    wsus12
  • Click Save to finish building the package

With our package built, it's just a matter of deploying it out to the dynamic collection we created earlier.

  • Select the package you just created

  • Select Deploy > Depoy Once

  • Click Choose Targets > PDQ Inventory > Collection

  • Select the collection we created earlier.

  • If everything looks okay, click Deploy Now

wsus13

Congratulations, you've successfully deployed that critical Windows update to your systems and didn't have to wait around for WSUS to do it!  If you want to make sure everything deployed correctly, you can scan your systems with the PowerShell scanner again, which will re-check to see which updates are available.  When the scan completes, the computers in the dynamic collections should automatically be removed from the collection.

wsus14

Wrapping Up

As I mentioned earlier, WSUS is pretty good at making sure your systems are up to date.  However, it does have a few shortcomings, especially when it comes to getting an update pushed out immediately.  With PDQ Inventory and PDQ Deploy, you'll never have to worry about sitting around for hours waiting for an update to get installed, it'll be installed exactly when you want it to be installed.  Now, if I could just find a tool that would get my kids to clean their rooms when I ask them to clean their rooms.

Brock Bingham candid headshot
Brock Bingham

Born in the '80s and raised by his NES, Brock quickly fell in love with everything tech. With over 15 years of IT experience, Brock now enjoys the life of luxury as a renowned tech blogger and receiver of many Dundie Awards. In his free time, Brock enjoys adventuring with his wife, kids, and dogs, while dreaming of retirement.

Related articles