Get-EternalBlueVulnerabilityStatistics.ps1

<#PSScriptInfo
 
.Version
    1.1
.Guid
    038a1c05-b1da-48c9-893d-4084b99f831b
.Author
    Thomas J. Malkewitz @dotps1
.Tags
    WannaCry, WannaCrypt, EternalBlue, SMB1, Malware
.ProjectUri
    https://github.com/dotps1/PSFunctions
.ExternalModuleDependencies
    NetTCPIP
.ReleaseNotes
    Missed the -ErrorAction Stop in the Test-WSMan call, this is needed to fall back to DCOM.
 
#>


<#
 
.Synopsis
    Gets EternalBlue vulnerability information.
.Description
    Test for applicable patches to prevent the WannaCry/WannaCrypt malware. Tests for the SMB1 protocol and component.
.Inputs
    System.String
    Microsoft.Management.Infrastructure.CimSession
.Outputs
    System.Management.Automation.PSCustomObject
.Parameter ComputerName
    System.String
    ComputerName to gather information from.
.Parameter Credential
    System.Management.Automation.PSCredential
    Credential used to establish a connection.
.Parameter CimSession
    Microsoft.Management.Infrastructure.CimSession
    Pre established CimSession used to connect.
.Example
    PS C:\> Get-EternalBlueVulnerabilityStatistics
 
    PSComputerName : my-win7-rig
    OperatingSystemCaption : Microsoft Windows 7 Professional
    OperatingSystemVersion : 6.1.7601
    LastBootUpTime : 5/14/2017 3:38:38 PM
    AppliedHotFixID : KB4012212;KB4015546;KB4015549
    SMB1FeatureEnabled : False
    SMB1ProtocolEnabled : False
    Port139Enabled : True
    Port445Enabled : True
.Example
    PS C:\> Get-ADComputer -Identity domain-win7-rig | Get-EternalBlueVulnerabilityStatistics
 
    PSComputerName : domain-win7-rig
    OperatingSystemCaption : Microsoft Windows 7 Professional
    OperatingSystemVersion : 6.1.7601
    LastBootUpTime : 3/14/2017 3:38:38 PM
    AppliedHotFixID :
    SMB1FeatureEnabled : False
    SMB1ProtocolEnabled : True
    Port139Enabled : True
    Port445Enabled : True
.Notes
    WannaCry/WannaCrypt (EternalBlue) vulnerability is only applicable to Microsoft Windows 10 1607 and prior, 1702 was not affected.
.Link
    https://technet.microsoft.com/en-us/library/security/ms17-010.aspx
.Link
    https://support.microsoft.com/en-us/help/2696547/how-to-enable-and-disable-smbv1,-smbv2,-and-smbv3-in-windows-vista,-windows-server-2008,-windows-7,-windows-server-2008-r2,-windows-8,-and-windows-server-2012
.Link
    https://dotps1.github.io
.Link
    https://www.powershellgallery.com/packages/Get-EternalBlueVulnerabiltyInforamtion
.Link
    https://grposh.github.io
 
#>



#requires -Module NetTCPIP

[CmdletBinding(
    DefaultParameterSetName = "ByComputerName"
)]
[OutputType(
    [PSCustomObject]
)]

param (
    [Parameter(
        ParameterSetName = "ByComputerName",
        ValueFromPipeline = $true,
        ValueFromPipelineByPropertyName = $true
    )]
    [ValidateScript({
        if (Test-Connection -ComputerName $_ -Count 1 -Quiet) {
            return $true
        } else {
            throw "Failed to contact '$_'."
        }
    })]
    [Alias(
        "ComputerName"    
    )]
    [String[]]
    $Name = $env:COMPUTERNAME,

    [Parameter(
        ParameterSetName = "ByComputerName"
    )]
    [System.Management.Automation.PSCredential]
    $Credential = [PSCredential]::Empty,

    [Parameter(
        ParameterSetName = "ByCimSession",
        ValueFromPipeline = $true,
        ValueFromPipelineByPropertyName = $true
    )]
    [Microsoft.Management.Infrastructure.CimSession[]]
    $CimSession
)

begin {
    $hotFixIDs = @(
        "KB3205409", 
        "KB3210720", 
        "KB3210721", 
        "KB3212646", 
        "KB3213986", 
        "KB4012212", 
        "KB4012213", 
        "KB4012214", 
        "KB4012215", 
        "KB4012216", 
        "KB4012217", 
        "KB4012218", 
        "KB4012220", 
        "KB4012598", 
        "KB4012606", 
        "KB4013198", 
        "KB4013389", 
        "KB4013429",
        "KB4015217", 
        "KB4015438", 
        "KB4015546", 
        "KB4015547", 
        "KB4015548", 
        "KB4015549",
        "KB4015550",
        "KB4015551",
        "KB4016635",
        "KB4019215",
        "KB4019216",
        "KB4019472"
    )

    function Get-Data ([Microsoft.Management.Infrastructure.CimSession]$CimSession, [Array]$HotfixIDs) {
        # Operating System Data
        Write-Progress -Activity "Gathering EternalBlue vulnerability information from '$nameValue'" -CurrentOperation "Retrieve operating system information" -PercentComplete 20
        $osInformation = Get-CimInstance -CimSession $CimSession -ClassName Win32_OperatingSystem -Property Caption, LastBootUpTime, Version

        # Hotfix Data
        Write-Progress -Activity "Gathering EternalBlue vulnerability information from '$nameValue'" -CurrentOperation "Retrieve operating hotfix id" -PercentComplete 40
        $appliedHotFixID = (Get-CimInstance -CimSession $CimSession -ClassName Win32_QuickFixEngineering).Where({
            $_.HotFixID -in $HotfixIDs
        }).HotFixID

        # SMB1Feature Data
        Write-Progress -Activity "Gathering EternalBlue vulnerability information from '$nameValue'" -CurrentOperation "Retrieve SMB1 feature state" -PercentComplete 60
        $smb1Feature = (Get-CimInstance -CimSession $CimSession -ClassName Win32_OptionalFeature -Property InstallState -Filter "Name = 'SMB1Protocol'").InstallState
        if ($smb1Feature -eq 1) {
            $smb1FeatureEnabled = $true
        } else {
            $smb1FeatureEnabled = $false
        }

        # SMB1Protocol Data
        Write-Progress -Activity "Gathering EternalBlue vulnerability information from '$nameValue'" -CurrentOperation "Retrieve SMB1 protocol state" -PercentComplete 80
        $smb1Protocol = (Invoke-CimMethod -CimSession $CimSession -ClassName StdRegProv -MethodName GetDwordValue -Arguments @{ hDefKey = [uint32]2147483650; sSubKeyName = "SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters"; sValueName = "SMB1" }).uValue
        if ($smb1Protocol -eq 0) {
            $smb1ProtocolEnabled = $false
        } else {
            $smb1ProtocolEnabled = $true
        }

        # SMB1Port Data
        Write-Progress -Activity "Gathering EternalBlue vulnerability information from '$nameValue'" -CurrentOperation "Retrieve SMB port state" -PercentComplete 100
        $port139TestConnection = (Test-NetConnection -ComputerName $CimSession.ComputerName -Port 139).TcpTestSucceeded
        $port445TestConnection = (Test-NetConnection -ComputerName $CimSession.ComputerName -Port 445).TcpTestSucceeded

        return [PSCustomObject]@{
            PSComputerName = $CimSession.ComputerName
            OperatingSystemCaption = $osInformation.Caption
            OperatingSystemVersion = $osInformation.Version
            LastBootUpTime = $osInformation.LastBootUpTime
            AppliedHotFixID = $appliedHotFixID -join ";"
            SMB1FeatureEnabled = $smb1FeatureEnabled
            SMB1ProtocolEnabled = $smb1ProtocolEnabled
            Port139Enabled = $port139TestConnection
            Port445Enabled = $port445TestConnection
        }
    }
}

process {
    switch ($PSCmdlet.ParameterSetName) {
        "ByComputerName" {
            foreach ($nameValue in $Name) {
                try {
                    $protocol = "WSMAN"
                    $protocolTest = Test-WSMan -ComputerName $name -ErrorAction Stop
                    if ($null -eq $protocolTest -or $protocol.ProductVersion -contains "Stack: 2.0") {
                        $protocol = "DCOM"
                    }
                } catch {
                    $protocol = "DCOM"
                }

                try {
                    $sessionParameters = @{
                        ComputerName = $nameValue
                        SessionOption = (New-CimSessionOption -Protocol $protocol)
                        ErrorAction = "Stop"
                    }

                    $credentialBoundParameter = $PSBoundParameters.ContainsKey(
                        "Credential"
                    )

                    if ($credentialBoundParameter) {
                        $sessionParameters.Add(
                            "Credential", $Credential
                        )
                    }

                    $session = New-CimSession @sessionParameters
                } catch {
                    Write-Error -Message $_.ToString()
                    continue
                }
                $output = Get-Data -CimSession $session -HotfixIDs $hotFixIDs

                Write-Output -InputObject $output

                Remove-CimSession -CimSession $session
            }
        }

        "ByCimSession" {
            foreach ($cimSessionValue in $CimSession) {
                $output = Get-Data -CimSession $cimSessionValue -HotfixIDs $hotFixIDs

                Write-Output -InputObject $output
            }
        }
    }
}