I was asked if there is an easy way to check the complete Active Directory for systems that miss the WannaCry related Hotfixes are installed.

Yep! And it’s even easy to do.

Update:
Based upon several requests, I also published a small tool that could do the Job. You will find the tool (freeware) on GitHub.

Here is a (updated!!!Gist I created to do the job:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#requires -Version 2.0 -Modules ActiveDirectory

<#
		.SYNOPSIS
		Check if all systems have the WannaCry related Hotfixes installed
	
		.DESCRIPTION
		Check if all systems have the WannaCry related Hotfixes installed.
		Checks given Computers, or all server systems found in the Active Directory (default)
	
		.PARAMETER ComputerList
		Name, or list of computers to check
	
		.EXAMPLE
		# Check if WindowsServer1 have all WannaCry related hotfixes installed
		PS C:\> .\who_needs_wannacry_patches.ps1 -ComputerList 'WindowsServer1'

		.EXAMPLE
		# Check if WindowsServer1 and WinDC01 have all WannaCry related hotfixes installed
		# In this example the Server WinDC01 is unreachable.
		PS C:\> .\who_needs_wannacry_patches.ps1 -ComputerList 'WindowsServer1','WinDC01'

		WARNING: WinDC01 is offline or unreachable.

		.EXAMPLE
		# Check all systems found in the Active Directory have all WannaCry related hotfixes installed
		# In this example the System ZRHW10VM01 is missing some of the WannaCry hotfixes
		PS C:\> .\who_needs_wannacry_patches.ps1

		WARNING: ZRHW10VM01 is missing WannaCry hotfix
	
		.NOTES
		Advice:
		You need to review and tweak the Filter in Line 76
		Please note, that the WannaCry problem doesn't apply to Windows 10 (Just in case you change the filter to clients)

		History:
		2017-05-15 - Add the following KB4015549, KB4015552, KB4015553, and KB4019264
		2017-05-15 - Another tweak to the Filter (Line 76) to avoid Windows 10 but covers all other Windows OSes
		2017-05-15 - The newer version contains a fixed KB List / Removed the Signature
		2017-05-12 - Inital Version WannaCry

		License:
		Public Domain

		General:
		The code is provided 'as is,' with all possible faults, defects or errors, and without warranty of any kind.

		.LINKS
		https://technet.microsoft.com/en-us/library/security/ms17-010.aspx
		https://hochwald.net/check-wannacry-related-hotfixes-installed/
#>
param
(
	[Parameter(ValueFromPipeline = $true,
			ValueFromPipelineByPropertyName = $true,
	Position = 1)]
	[string[]]
	$ComputerList
)

begin {
	# List of fixes we search for, in this case all fixes relates to WannaCry
	# Source List: https://technet.microsoft.com/en-us/library/security/ms17-010.aspx and feedback
	$hotfixes = 'KB4012212', 'KB4012213', 'KB4012214', 'KB4012215', 'KB4012216', 'KB4012217', 'KB4012598', 'KB4012606', 'KB4013198', 'KB4013429', 'KB4015217', 'KB4015438', 'KB4015549', 'KB4015550', 'KB4015551', 'KB4015552', 'KB4015553', 'KB4016635', 'KB4019215', 'KB4019216', 'KB4019264', 'KB4019472'
}

process {

	if (-not ($ComputerList))
	{
		try 
		{
			# Filter for all Windows Systems, ignore our Mac's an Windows 10
			$ComputerList = Get-ADComputer -Filter {
				(OperatingSystem  -Like 'Windows*') -and (OperatingSystem -notlike '*Windows 10*')
			} | Select-Object -ExpandProperty 'Name'
		}
		catch 
		{
			Write-Error -Message 'Unable to get the List of computers from the Active Directory' -ErrorAction Stop
		}
	}

	# Loop over the List of computers
	foreach($computer in $ComputerList) 
	{
		if(-not(Test-Connection -ComputerName $computer -Count 1 -Quiet)) 
		{
			Write-Verbose "$computer is possibly offline or unreachable (Try anyway)."
		}

		try 
		{
			$hotfix = Get-HotFix -ComputerName $computer | 
			Where-Object -FilterScript {
				$hotfixes -contains $_.HotfixID
			} | 
			Select-Object -ExpandProperty 'HotFixID'

			if($hotfix) 
			{
				Write-Verbose -Message "$computer has hotfix $hotfix installed"
			}
			else 
			{
				Write-Warning -Message "$computer is missing WannaCry hotfix"
				continue
			}
		}
		catch 
		{
			Write-Warning -Message "Unable to get Hostfix Info from $computer"
			continue
		}
	}
}

<#
		I removed the signature to make it easier for others to adopt it (e.g. Tweak or changes)
		If you need a signed version, just drop me a line and I can sign one for you.

		NOTE: If you change something, upload it as Gist to GitHub and send me the link.

		And yes, I'll sign the script for free! Why not? (Before you ask!)
#>

This is script is based on an existing script that I use to and filter infos from the Active directory.
You might also want to review and/or tweak the filter option (Line 6974) and/or the Hotfix List (Line 4663). Normally the script returns a list of systems with systems that are not complaint. I changed this to a Warning (Write-Warning in Line 107105 and 111) for this use-Case!

I also added some examples to show the usage.

Even if all Hotfixes are applied, you should remove the SMBv1 functions whenever possible!

Please note:
If you change the script in any kind, the signature isn’t working and everything after line 112 should be removed.

Update:
Like Kaleb noted: The Script doesn’t work on all systems. The Application logic about the OS is missing. That was a quick hack and I will implement something soon. Something that uses a WMI call to get the OS information and then compare only the part of the Hotfix Array that applies.
The Script is now updated and it should fit.