Public/get-pwnedpassword.ps1

#Requires -Version 3
function Get-PwnedPassword 
{
    <#
            .SYNOPSIS
            Report if an password has been found via the https://haveibeenpwned.com API service.
  
            .DESCRIPTION
            Report if an passsword has been found via the https://haveibeenpwned.com API service.
 
            This function queries the https://haveibeenpwned.com API service created by Troy Hunt (@troyhunt)
            and reports whether the specified password has been found (pwned). The password can be in
            clear text, a SHA1 hash, or a secure string.
             
            Note that if a secure string is used it has to be retrieved and then passed in the body
            of the https request. Use this if you don't want to type a password in clear text at the CLI.
 
            .EXAMPLE
            Get-PwnedPassword -Password monkey
            Identifies if the password has been found.
 
            .EXAMPLE
            Get-PwnedPassword -SHA1 AB87D24BDC7452E55738DEB5F868E1F16DEA5ACE
            Identifies if the SHA1 hash of the password has been found.
 
            .EXAMPLE
            $Password = Read-host -AsSecureString
            Get-PwnedPassword -SecureString $Password
            Identifies if the password, in the SecureString variable $Password, has been found
 
            .EXAMPLE
            $password = ConvertTo-SecureString "monkey" -asplaintext -force
            get-pwnedpassword -SecureString $password
            Identifies if the password, in the SecureString variable $Password, has been found
             
            .INPUTS
            None
  
            .NOTES
            Author: Mark Ukotic
            Website: http://blog.ukotic.net
            Twitter: @originaluko
            GitHub: https://github.com/originaluko/
 
            .LINK
            https://github.com/originaluko/haveibeenpwned
 
    #>

    
    [CmdletBinding()]
    [OutputType([object])]
    param (
        [Parameter(Mandatory, ParameterSetName = 'Password')]
        [string]$Password,
        
        [Parameter(Mandatory, ParameterSetName = 'SecureString')]
        [SecureString]$SecureString,
        
        [Parameter(Mandatory, ParameterSetName = 'SHA1')]
        [ValidatePattern('^[0-9A-F]{40}$')]
        [string]$SHA1
    )


    Begin
    {

        [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
        $baseuri = "https://api.pwnedpasswords.com/range/"
        function Hash($textToHash)
        {      
            $hasher = new-object -TypeName "System.Security.Cryptography.SHA1CryptoServiceProvider"
            $toHash = [System.Text.Encoding]::UTF8.GetBytes($textToHash)
            $bytes = $hasher.ComputeHash($toHash)
            $res = ($bytes|ForEach-Object ToString X2) -join ''
            $res
        }
      
    }
    Process
    {

        Switch ($PSCmdlet.ParameterSetName) {
            'Password' {
                $SHA1 = Hash($Password)
                write-host $SHA1                
                break
            }
            'SecureString' {
                $Password = (New-Object PSCredential "user", $SecureString).GetNetworkCredential().Password
                $SHA1 = Hash($Password)
                break
            }
            'SHA1' {
                break
            }
        }
        $URI = $baseuri + $SHA1.SubString(0,5)
        try
        {
            $Request = Invoke-RestMethod -Uri $URI
            $suffix = $SHA1.SubString(5,35) + ":"
            $found = $request.split() | select-string "$suffix" | out-string
            if ($found) {
                $cnt = (($found.split(':'))[1]).trim()
                Write-Warning  "Password pwned $cnt times!"
            } else {
                Write-Output  'Password not found.'
            }
        }
         catch [System.Net.WebException] {
            Switch ($_.Exception.Message) {
                'The remote server returned an error: (400) Bad Request.' {
                    Write-Error -Message 'Bad Request - the account does not comply with an acceptable format.'
                }
                'The remote server returned an error: (403) Forbidden.' {
                    Write-Error -Message 'Forbidden - no user agent has been specified in the request.'
                }
                'The remote server returned an error: (404) Not Found.' {
                    Write-Output  'Password not found.'
                }
                'The remote server returned an error: (429) Too Many Requests.' {
                    Write-Error -Message 'Too many requests - the rate limit has been exceeded.'
                }
            }
            break
        }
    }
}