Public/Start-CheckIDPasswordAgentListener.ps1
<# .DESCRIPTION Starts the CheckIDPasswordAgent listener. The listener continuously checks for password reset requests and processes them. .SYNOPSIS Starts the CheckIDPasswordAgent listener. .EXAMPLE Start-CheckIDPasswordAgentListener -Sleep 5 #> function Start-CheckIDPasswordAgentListener { [CmdletBinding()] Param( # Sleep interval in seconds between checks for new requests [Parameter(Mandatory = $false)] [ValidateRange(1, 10)] [int] $Sleep = 5 ) process { if(!(get-command Set-ADAccountPassword* | ? Name -eq Set-ADAccountPassword)) { Write-Error -Message "Set-ADAccountPassword cmdlet is not available. Please ensure the Active Directory module is installed and imported." Write-EventLog -LogName "Application" -Source "CheckIDPasswordAgent" -EventId 1210 -EntryType Error -Message "Set-ADAccountPassword cmdlet is not available. Please ensure the Active Directory module is installed and imported." -ErrorAction Continue return } Write-Verbose "Starting CheckIDPasswordAgent listener with a sleep interval of $Sleep seconds" Write-EventLog -LogName "Application" -Source "CheckIDPasswordAgent" -EventId 1006 -EntryType Information -Message "Starting CheckIDPasswordAgent listener with a sleep interval of $Sleep seconds" -ErrorAction Continue while ($true) { try { $requests = Receive-CheckIDPasswordAgentRequests if ($requests) { $requests | ForEach-Object { $request = $_ try { if(!$request.onPremisesSecurityIdentifier) { Write-Warning "No onPremisesSecurityIdentifier found for user $($request.userPrincipalName) (Cloud only probably, so we are not doing anything)" } else { Write-Verbose "Setting password for user $($request.userPrincipalName) / $($request.onPremisesSecurityIdentifier)" Write-EventLog -LogName "Application" -Source "CheckIDPasswordAgent" -EventId 1008 -EntryType Information -Message "Setting password for user $($request.userPrincipalName) / $($request.onPremisesSecurityIdentifier) with ID: $($request.id)" -ErrorAction Continue Set-ADAccountPassword -Identity $request.onPremisesSecurityIdentifier -NewPassword (ConvertTo-SecureString -String $request.password -AsPlainText -Force) -Reset } $request | Confirm-CheckIDPasswordAgentRequest -Status "Success" } catch { Write-Error -Message "Failed to set password for user $($request.userPrincipalName): $request" Write-EventLog -LogName "Application" -Source "CheckIDPasswordAgent" -EventId 1201 -EntryType Error -Message "Failed to set password for user $($request.userPrincipalName) with ID $($request.id) - $request" -ErrorAction Continue $request | Confirm-CheckIDPasswordAgentRequest -Status "Error" -Message $_.Exception.Message } } } else { Write-Verbose "No requests found, sleeping for $Sleep seconds" # Too verbose, no need to inform for every API GET request interval. Fills up Windows event log # Write-EventLog -LogName "Application" -Source "CheckIDPasswordAgent" -EventId 1007 -EntryType Information -Message "No requests found, sleeping for $Sleep seconds" -ErrorAction Continue Start-Sleep -Seconds $Sleep } } catch { Write-Error -Message "An error occurred in the listener loop: $_" Write-EventLog -LogName "Application" -Source "CheckIDPasswordAgent" -EventId 1203 -EntryType Error -Message "An error occurred in the listener loop: $_" -ErrorAction Continue Start-Sleep -Seconds $Sleep } } } } |