Skip to content

Instantly share code, notes, and snippets.

@darrenjrobinson
Last active November 17, 2018 22:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save darrenjrobinson/903921b8032b3a2a2a733a7aea002bde to your computer and use it in GitHub Desktop.
Save darrenjrobinson/903921b8032b3a2a2a733a7aea002bde to your computer and use it in GitHub Desktop.
Microsoft Identity Manager PowerShell Management Agent Import 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,
$OperationType,
[bool] $usepagedimport,
$pagesize
)
$DebugFilePath = "C:\PROGRA~1\MICROS~4\2010\SYNCHR~1\EXTENS~2\PwnedPWD\Debug\ADImport.txt"
if(!(Test-Path $DebugFilePath))
{
$DebugFile = New-Item -Path $DebugFilePath -ItemType File
}
else
{
$DebugFile = Get-Item -Path $DebugFilePath
}
"Starting Import as : " + $OperationType + (Get-Date) | Out-File $DebugFile -Append
#Needs reference to .NET assembly used in the script.
Add-Type -AssemblyName System.DirectoryServices.Protocols
$CookieFile = "C:\PROGRA~1\MICROS~4\2010\SYNCHR~1\EXTENS~2\PwnedPWD\ADCookie.bin"
$count = 0
#Getting Cookie from file
If (Test-Path $CookieFile –PathType leaf) {
[byte[]] $Cookie = Get-Content -Encoding byte –Path $CookieFile
} else {
$Cookie = $null
}
#region User
$Properties = @("objectGuid","givenName","displayName","mail","sn","pwdLastSet","badPwdCount","badPasswordTime","lastLogon","logonCount","adminCount","sAMAccountName","userPrincipalName","isDeleted")
#Running as ther user specified on the MA
$Credentials = New-Object System.Net.NetworkCredential($username,$password)
$RootDSE = [ADSI]"LDAP://RootDSE"
$LDAPDirectory = New-Object System.DirectoryServices.Protocols.LdapDirectoryIdentifier($RootDSE.dnsHostName)
$LDAPConnection = New-Object System.DirectoryServices.Protocols.LDAPConnection($LDAPDirectory, $Credentials)
$Request = New-Object System.DirectoryServices.Protocols.SearchRequest($RootDSE.defaultNamingContext, "(&(objectClass=user))", "Subtree", $Properties)
#Defining the object type returned from searches for performance reasons.
[System.DirectoryServices.Protocols.SearchResultEntry]$entry = $null
if ($OperationType -eq "Full")
{
$Cookie = $null
}
else
{
# delta run and we should use the cookie we already found
}
$DirSyncRC = New-Object System.DirectoryServices.Protocols.DirSyncRequestControl($Cookie, [System.DirectoryServices.Protocols.DirectorySynchronizationOptions]::IncrementalValues, [System.Int32]::MaxValue)
$Request.Controls.Add($DirSyncRC) | Out-Null
$MoreData = $true
$Guids = @()
while ($MoreData) {
$Response = $LDAPConnection.SendRequest($Request)
ForEach($entry in $Response.Entries){
#Check if this GUID already been handled to avoid adding duplicate objects
If($Guids -contains ([GUID] $entry.Attributes["objectguid"][0]).ToString()){continue}
# Add objectGuid and objectClass to all objects
$obj = @{}
$obj.Add("objectGuid", ([GUID] $entry.Attributes["objectguid"][0]).ToString())
$obj.Add("objectClass", "user")
if ( $entry.distinguishedName.Contains("CN=Deleted Objects"))
{
# this is a deleted object, so we return a changeType of 'delete'; default changeType is 'Add'
$obj.Add("changeType", "Delete")
}
else
{
# we need to get the directory entry to get the additional attributes
$DirEntry = New-Object System.DirectoryServices.DirectoryEntry "LDAP://$($entry.distinguishedName)"
# add values to the attributes that have changed
$obj.Add("sAMAccountName",$DirEntry.Properties["sAMAccountName"][0])
if ($DirEntry.Properties["userPrincipalName"][0]){$obj.Add("userPrincipalName",$DirEntry.Properties["userPrincipalName"][0])}
if ($DirEntry.Properties["givenName"][0]){$obj.Add("givenName",$DirEntry.Properties["givenName"][0])}
if ($DirEntry.Properties["displayName"][0]){$obj.Add("displayName",$DirEntry.Properties["displayName"][0])}
if ($DirEntry.Properties["mail"][0]){$obj.Add("mail",$DirEntry.Properties["mail"][0])}
if ($DirEntry.Properties["sn"][0]){$obj.Add("sn",$DirEntry.Properties["sn"][0])}
# [datetime]::fromfiletime($entry.Attributes.pwdlastset[0])
if ($entry.Attributes.pwdlastset[0]){$obj.Add("pwdLastSet",$entry.Attributes.pwdlastset[0])}
if ($entry.Attributes.lastlogontimestamp[0]){$obj.Add("lastLogon",$entry.Attributes.lastlogontimestamp[0])}
if ($DirEntry.Properties["logonCount"][0]){$obj.Add("logonCount",$DirEntry.Properties["logonCount"][0])}
if ($DirEntry.Properties["adminCount"][0]){$obj.Add("adminCount",$DirEntry.Properties["adminCount"][0])}
#Add Guid to list of processed guids to avoid duplication
$Guids += ,([GUID] $entry.Attributes["objectguid"][0]).ToString()
#Return the object to the MA
$obj
}
}
ForEach ($Control in $Response.Controls) {
If ($Control.GetType().Name -eq "DirSyncResponseControl") {
$Cookie = $Control.Cookie
$MoreData = $Control.MoreData
}
}
$DirSyncRC.Cookie = $Cookie
}
#Saving cookie file
Set-Content -Value $Cookie -Encoding byte –Path $CookieFile
$global:RunStepCustomData = [System.Convert]::ToBase64String($Cookie)
# ***********************************************************
"Finished Import as : " + $OperationType + (Get-Date) | Out-File $DebugFile -Append
#endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment