Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Microsoft Identity Manager PowerShell Management Agent Password Script to check to see if users AD Passwords have been pwned. Supporting blog post is located here https://blog.darrenjrobinson.com/identifying-active-directory-users-with-pwned-passwords-using-microsoftforefront-identity-manager/
param
(
$Username,
$Password,
$Credentials,
$Action,
$OldPassword,
$NewPassword,
[switch] $UnlockAccount,
[switch] $ForceChangeAtLogOn,
[switch] $ValidatePassword
)
BEGIN
{
}
PROCESS
{
# Logging
$log = "C:\PROGRA~1\MICROS~4\2010\SYNCHR~1\EXTENS~2\PwnedPWD\Debug\PwnedPWD.log"
"=============================================================" | out-file $log -Append
$DisplayName = $_["displayName"].Value
$Accountname = $_["sAMAccountName"].Value
"Account Name: $Accountname" | Out-File $log -Append
"Display Name: $DisplayName" | Out-File $log -Append
"Action: $Action" | Out-File $log -Append
"Old pwd: $OldPassword" | Out-File $log -Append
"New pwd: $NewPassword" | Out-File $log -Append
"Unlock: $UnlockAccount" | Out-File $log -Append
"Force change: $ForceChangeAtLogOn" | Out-File $log -Append
"Validate: $ValidatePassword" | Out-File $log -Append
$responseCode = $null
# HaveIBeenPwnded uses TLS 1.2. PowerShell by default is 1.0. Set TLS to 1.2
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# Check password against the Pwned List
function PwnedPassword ($URI) {
try {
$Global:responseCode = (Invoke-webrequest -uri $URI -UseBasicParsing -TimeoutSec 20).statuscode
$Global:responseCode | Out-File $log -Append
return $Global:responseCode
}
catch [System.Net.WebException] {
# either we had a communnication failure, hit the rate limit or got a 404 indicating password isn't pwned
$Request = $_.Exception
$Global:responseCode = $Request.Response.StatusCode.'value__'
$Global:responseCode | Out-File $log -Append
return $Global:responseCode
}
}
# URL with the users new password
# Note the password is received in clear text for obvious reasons
# You should think about encoding the password with SHA-1 before sending to the API
# eg.. $pwdsha1 = Get-Hash -Algorithm SHA1 -StringEncoding utf8 -InputObject $NewPassword
# $NewPassword = $pwdsha1.HashString
$pwnedCheckURL = "https://haveibeenpwned.com/api/v2/pwnedpassword/$NewPassword"
# Check it
PwnedPassword($pwnedCheckURL)
[int]$i =0
do {
if ($Global:responseCode){
write-host $Global:responseCode
switch ($Global:responseCode) {
"200" {$Global:pwned = $true ; "Password is burnt. In the pwned list." | Out-File $log -Append}
"404" {$Global:pwned = $false ; "Password is good. It isn't in the pwned list." | Out-File $log -Append}
"429" {Start-Sleep -milliseconds 1600; "We hit the API rate limit Taking a short sleep." | Out-File $log -Append; PwnedPassword($pwnedCheck)}
}
}
$i++
} until ($pwned -or !$pwned -or $i -eq 10)
# Update the user in the MIM Service
if ($pwned -or !$pwned){
Import-Module lithnetrma
$pwd = $Password | ConvertTo-SecureString -asPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential($Username,$pwd)
Set-ResourceManagementClient -BaseAddress http://mimserviceServer:5725 -Credentials $Credential
# Get the user from the MIM Service
$user = Get-Resource -ObjectType Person -AttributeName AccountName -AttributeValue $Accountname
if ($user){
$user.pwnedPassword = $pwned
Save-Resource $user
"Updated MIM Service for $Accountname who's password pwned status is $pwned" | Out-File $log -Append
}
}
}
END
{
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.