Import BlueKeep Scan Results into PDQ Inventory – Part 1

Hello there! BlueKeep (CVE-2019-0708) is a dangerous vulnerability in Microsoft’s Remote Desktop Protocol (RDP). It is wormable (it can spread autonomously from computer to computer), so you should patch it ASAP. I wrote a PowerShell script to help you find the computers you need to patch.

The PowerShell Script

My script runs rdpscan, parses the results, then feeds those into two Custom Fields in PDQ Inventory. Once the results are in Inventory you can create Collections and Reports to see which of your computers are vulnerable, then patch those vulnerable computers with PDQ Deploy (cumulative updates are great). In this post, I’ll show you how to run my script, and in Part 2 I’ll go into more detail about some of the things I had to do to get this script working.

Disclaimer: This script is a work in progress. Since it’s functional, I’m releasing it. Although I do have a list of things I want to change/add, I don’t want to delay this blog any longer. Also, since it is on GitHub I highly encourage you to submit pull requests if you have any ideas for improvements.


  • -RDPScanEXE (Required)
  • -Collections (Semi-required)
  • -Computers (Semi-required)
    • A list of computer names. You must provide this parameter or -Collections.
  • -MaxJobs (Optional)
    • The number of instances of rdpscan.exe that will be executed simultaneously. This defaults to the number of CPU threads in your system times four. Increasing this number will use more RAM and could cause weird issues.
  • -FailSafeMax (Optional)
  • -CustomFieldNameStatus (Optional)
    • The name of the Custom Field that will store the status (SAFE, VULNERABLE, UNKNOWN). Defaults to “BlueKeep Status”.
  • -CustomFieldNameNotes (Optional)
    • The name of the Custom Field that will store the notes (CredSSP/NLA required, got appid, name resolution failed, etc.). Defaults to “BlueKeep Notes”.
  • -Randomize (Optional)
    • Randomizes the order of the target list. Defaults to $false.
  • -Verbose (Optional)
    • Shows informational messages that are hidden by default.


  • Download the latest version of rdpscan from the releases page and unzip it.
  • Copy and paste my script into your favorite text editor (such as VS Code), then save it as a PS1 file (Find-BlueKeepVulnerableComputers.ps1). If you have git installed you can clone my repository instead.
  • PDQ Inventory must be installed on the computer you are running my script from, and it must have an Enterprise License. This script should work with all three modes, Enterprise Local, Server, and Client.
  • Open a PowerShell window as admin.
  • Navigate to my script.
    • cd “C:\Users\Fred\Downloads\Scripts”
  • Execute my script with the required parameters and any optional parameters that you desire.
    • The minimum required to run this script:
      .\Find-BlueKeepVulnerableComputers.ps1 -RDPScanEXE 
      “C:\Users\Fred\Downloads\rdpscan-windows\rdpscan.exe” -Collections “Atlanta 
      Desktops”, “Seattle Desktops”
    • A more advanced example:
      $Params = @{
            Collections = “All Computers”
            CustomFieldNameStatus = “BK_Status”
            CustomFieldNameNotes = “BK_Notes”
            FailSafeMax = 2400
            RDPScanEXE =
                  Randomize = $true
                  Verbose = $true
      .\Find-BlueKeepVulnerableComputers.ps1 @Params

Sit back and Relax

Sit back, relax, and wait for the scans to finish. It could take a while depending on your environment. On my system, it usually takes around four to five minutes to scan ~650 targets. Once it finishes you should open a computer in Inventory and check its Custom Fields page. Make sure BlueKeep Status and BlueKeep Notes are there and contain sensible looking data. If everything is hunky-dory you can start creating reports and collections.

To create a Basic Report you simply need to add BlueKeep Status and BlueKeep Notes (under the Computer table) and any other fields you’d like. I created a Basic Report with a few fields to get you started.

Once you run the report I recommend grouping it by BlueKeep Status so you can quickly drill down to the computers that need your attention.

I suggest creating five Collections, an empty Static Collection to act like a folder and four Dynamic Collections beneath it based on BlueKeep Status. Here’s my set of Collections if you want a head start. I went with “Not Scanned”, “Safe”, “Unknown”, and “Vulnerable”. They all start with “Computer | BlueKeep Status | Equals”, then each one has a different Value. For “Not Scanned” just leave Value empty.

And that’s it! Hopefully, this helps you find and track vulnerable computers in your environment so you can start remediation efforts. I highly recommend patching your computers as soon as you can. If you have any questions you can ask them in the comments below, or open an issue on my GitHub repository with the `question` label. Your feedback will help shape Part 2.


16 responses

  • Hi Colby.
    This script is nice.

    Thanks. I am sure I can modify the concept for other tasks in the future too.

    Can we create a PDQ Deploy task to run the script regular against the “Unknown” collection?


  • @SDLTom:
    Yes, it should be possible to create a Package that calls this script and tie it to a Schedule. I would recommend an Install Step.

  • If I wanted to specify a different port for rdpscan.exe, is there anywhere in your script or the parameters to specify -p for the port?

  • Thanks for the script. Im getting this when I run it though: C:\RDPScan\Find-BlueKeepVulnerableComputers.ps1 : Cannot process argument transformation on parameter ‘MaxJobs’. Cannot convert the “System.Object[]” value of type “System.Object[]” to type “System.Int32”.
    At line:1 char:1

    Any suggestions?

    • This is just a guess, but are you trying to run the script with PowerShell 2.0 on Windows 7? I only tested it with PowerShell 5.1 on Windows 10, but I think it should be compatible with 3.0 and higher.

    • Huh, strange, it probably should have worked then 🙂

      I changed how the default value of MaxJobs is set yesterday. Please re-download the script and try again.

  • Ok, getting some progress. This is what I am getting now:

    Cannot convert the “System.Object[]” value of type “System.Object[]” to type “System.Int32”.
    At C:\RDPScan\Find-BlueKeepVulnerableComputers.ps1:46 char:5
    + $MaxJobs = $MaxJobsDefault
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidArgument: (:) [], RuntimeException
    + FullyQualifiedErrorId : ConvertToFinalInvalidCastException

    Get-Job : Cannot validate argument on parameter ‘Id’. The argument is null, empty, or an element of the argument collection contains a null value. Supply a collection that does not contain any null values and then try the command
    At C:\RDPScan\Find-BlueKeepVulnerableComputers.ps1:203 char:38
    + $CompletedJobs = Get-Job -Id $Global:JobIDs | Where-Object St …
    + ~~~~~~~~~~~~~~
    + CategoryInfo : InvalidData: (:) [Get-Job], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.GetJobCommand

    • Unfortunately, I don’t see a way to get the Inventory commands to return FQDNs. One way to get around this is to generate a Basic Report with the Host Name field, save that report as a CSV file, then use PowerShell to ingest that CSV file and feed it to the script.

      $ComputerList = ( Import-Csv "C:\Path\To\ComputerList.csv" )."Computer Host Name"
      .\Find-BlueKeepVulnerableComputers.ps1 -RDPScanEXE "C:\Path\To\rdpscan.exe" -Computers $ComputerList -Verbose

Your email address will not be published.

Your Name

This site uses Akismet to reduce spam. Learn how your comment data is processed.