Public/PasswordSynchronisation/Get-JIMPendingPasswordChange.ps1
|
# Copyright (c) Tetron Limited. All rights reserved. # Licensed under the Tetron Commercial License. See LICENSE file in the project root. function Get-JIMPendingPasswordChange { <# .SYNOPSIS Gets the Password Synchronisation queue: password changes waiting to be delivered to Connected Systems. .DESCRIPTION Lists what Set-JIMMetaverseObjectPassword put on the queue and what has happened to it since. One row per identity per Connected System, naming both, so a list reads as people and systems rather than identifiers. A change is in one of five states: - Pending: JIM still intends to deliver it. Read the Due and Held properties alongside this, which say whether the Password Delivery Service would attempt it now: a Pending change may be waiting out a retry backoff, or be Held because Password Synchronisation is switched off on its Connected System. A held change is never due; switching the system on delivers everything that accumulated for it. - Delivering: the Password Delivery Service has claimed it and is writing it to the Connected System right now. Momentary; it is gone once the target has the password, or back to Pending or Parked if the target refused. - Parked: the target refused it, or it ran out of attempts. JIM has stopped trying and it waits on a person. FailureReason and TargetMessage say why, in the target's own words. - Expired: it outlived its Connected System's time to live. The password it carried is gone and nothing can deliver it now. - Cancelled: an administrator stopped it. CancelledAt and CancelledByName record who and when. Every change also carries an Origin: Explicit (an administrator's named set), Propagated (JIM carried it to every configured system after the person's own password change), or Provisioned (the first password for an account an export has just created). A Provisioned change carries SyncRuleId, the Synchronisation Rule its password is generated from at each delivery attempt. An Explicit or Propagated change can also be a Connected System Object's first password: it was already waiting when JIM provisioned that object, or it replaced the object's Initial Password before it was delivered. ProvisionedConnectedSystemObjectId names the object, and SyncRuleId the Synchronisation Rule whose Initial Password settings for enabling the object and for whether its password never expires its delivery applies; the change keeps its own password and expiry. Cancelling such a change leaves the object without a password from JIM. Both are $null for a change that is no object's first password. No password is returned, in any form. The queued value is encrypted in the database and has no representation on this or any other surface. .PARAMETER ConnectedSystemId Only changes queued for this Connected System. .PARAMETER Status Only changes in this state. .PARAMETER FailureReason Only changes whose last attempt failed this way. A change that has never been attempted has no reason. .PARAMETER MetaverseObjectId Only this Metaverse Object's queued changes. .PARAMETER Search Free-text search over the Metaverse Object and Connected System names. .PARAMETER SortBy The column to sort by; queued when omitted. .PARAMETER SortDirection The sort direction; ascending when omitted. .PARAMETER Page The page of changes to return. .PARAMETER PageSize How many changes to return per page. .PARAMETER All Returns every page. Stops after 1,000 pages with a warning unless -Force is given. .PARAMETER Force Fetches beyond the -All page ceiling. .PARAMETER Summary Returns the queue's counts by state instead of its changes. .OUTPUTS One object per queued change, one entry per Metaverse Object per Connected System, or with -Summary one object of counts. No password is returned, in any form. .EXAMPLE Get-JIMPendingPasswordChange -Summary Reports how much is waiting, how much is due now, and how much is parked or expired. The cheapest way to find out whether Password Synchronisation needs attention. .EXAMPLE Get-JIMPendingPasswordChange -Status Parked Lists the changes JIM has given up on, which are the ones a person has to do something about. .EXAMPLE Get-JIMPendingPasswordChange -Status Parked | Group-Object ConnectedSystemName | Select-Object Name, Count Shows which Connected Systems the parked changes are piling up behind, which is usually one system rather than many. .EXAMPLE Get-JIMConnectedSystem -Name "Corporate AD" | Get-JIMPendingPasswordChange -Status Parked -All Lists every parked change for one Connected System, following pagination. .EXAMPLE Get-JIMPendingPasswordChange -Status Pending | Where-Object { -not $_.Due -and -not $_.Held } Lists changes waiting out a retry backoff, as opposed to those the Password Delivery Service is about to attempt or those held behind a Connected System that is switched off. .EXAMPLE Get-JIMPendingPasswordChange -Status Pending -All | Where-Object Held | Group-Object ConnectedSystemName | Select-Object Name, Count Lists the Connected Systems holding password changes because Password Synchronisation is switched off on them, and how many each is holding. Worth running before a change window closes: every one of these expires eventually, and switching the system back on is what delivers them. .EXAMPLE Get-JIMPendingPasswordChange -All | Where-Object { $_.ProvisionedConnectedSystemObjectId -and $_.Origin -ne 'Provisioned' } Lists the password changes that are also a Connected System Object's first password, which is worth knowing before cancelling any of them. .LINK Resume-JIMPendingPasswordChange Stop-JIMPendingPasswordChange Set-JIMMetaverseObjectPassword Set-JIMConnectedSystemPasswordSynchronisation #> [CmdletBinding(DefaultParameterSetName = 'List')] [OutputType('JIM.PendingPasswordChangeResponse', ParameterSetName = 'List')] [OutputType('JIM.PendingPasswordChangeResponse', ParameterSetName = 'ListAll')] [OutputType('JIM.PasswordQueueSummary', ParameterSetName = 'Summary')] param( [Parameter(ParameterSetName = 'List', ValueFromPipelineByPropertyName)] [Parameter(ParameterSetName = 'ListAll', ValueFromPipelineByPropertyName)] [int]$ConnectedSystemId, [Parameter(ParameterSetName = 'List')] [Parameter(ParameterSetName = 'ListAll')] [ValidateSet('Pending', 'Delivering', 'Parked', 'Expired', 'Cancelled')] [string]$Status, [Parameter(ParameterSetName = 'List')] [Parameter(ParameterSetName = 'ListAll')] [ValidateSet('None', 'Transient', 'ConfigurationFault', 'PolicyRejection', 'TargetObjectNotFound', 'UnsupportedOperation')] [string]$FailureReason, [Parameter(ParameterSetName = 'List')] [Parameter(ParameterSetName = 'ListAll')] [guid]$MetaverseObjectId, [Parameter(ParameterSetName = 'List')] [Parameter(ParameterSetName = 'ListAll')] [string]$Search, [Parameter(ParameterSetName = 'List')] [Parameter(ParameterSetName = 'ListAll')] [ValidateSet('queued', 'identity', 'system', 'status', 'attempts', 'nextAttempt', 'expires')] [string]$SortBy, [Parameter(ParameterSetName = 'List')] [Parameter(ParameterSetName = 'ListAll')] [ValidateSet('asc', 'desc')] [string]$SortDirection, [Parameter(ParameterSetName = 'List')] [ValidateRange(1, [int]::MaxValue)] [int]$Page = 1, [Parameter(ParameterSetName = 'List')] [Parameter(ParameterSetName = 'ListAll')] [ValidateRange(1, 100)] [int]$PageSize = 50, [Parameter(Mandatory, ParameterSetName = 'ListAll')] [switch]$All, [Parameter(ParameterSetName = 'ListAll')] [switch]$Force, [Parameter(Mandatory, ParameterSetName = 'Summary')] [switch]$Summary ) process { if (-not $script:JIMConnection) { Write-Error "You are not connected to JIM. Run Connect-JIM -Url <your JIM URL> to authenticate, then try again." return } if ($PSCmdlet.ParameterSetName -eq 'Summary') { Write-Verbose "Getting the Password Synchronisation queue summary" Invoke-JIMApi -Endpoint '/api/v1/password-synchronisation/queue/summary' return } # Built once and reused across pages, so an auto-paginating fetch cannot drift from the first page's # filters partway through. $criteria = @() if ($PSBoundParameters.ContainsKey('ConnectedSystemId')) { $criteria += "connectedSystemId=$ConnectedSystemId" } if ($Status) { $criteria += "status=$Status" } if ($FailureReason) { $criteria += "failureReason=$FailureReason" } if ($PSBoundParameters.ContainsKey('MetaverseObjectId')) { $criteria += "metaverseObjectId=$MetaverseObjectId" } if ($Search) { $criteria += "search=$([System.Uri]::EscapeDataString($Search))" } if ($SortBy) { $criteria += "sortBy=$SortBy" } if ($SortDirection) { $criteria += "sortDirection=$SortDirection" } $criteriaSuffix = if ($criteria.Count -gt 0) { '&' + ($criteria -join '&') } else { '' } if ($All) { Write-Verbose "Getting every queued password change" $pageRequest = { param($p) Invoke-JIMApi -Endpoint "/api/v1/password-synchronisation/queue?page=$p&pageSize=$PageSize$criteriaSuffix" } Invoke-JIMPagedFetch -PageRequest $pageRequest -CmdletName 'Get-JIMPendingPasswordChange' -PageSize $PageSize -Force:$Force ` -ItemNoun 'queued password changes' -NarrowHint 'narrow the query with -ConnectedSystemId, -Status or -Search' return } Write-Verbose "Getting queued password changes (Page: $Page, PageSize: $PageSize)" $response = Invoke-JIMApi -Endpoint "/api/v1/password-synchronisation/queue?page=$Page&pageSize=$PageSize$criteriaSuffix" foreach ($item in $response.items) { $item } } } |