Public/PasswordSynchronisation/Resume-JIMPendingPasswordChange.ps1
|
# Copyright (c) Tetron Limited. All rights reserved. # Licensed under the Tetron Commercial License. See LICENSE file in the project root. function Resume-JIMPendingPasswordChange { <# .SYNOPSIS Puts queued password changes back on the Password Synchronisation queue and asks JIM to deliver them now. .DESCRIPTION Makes every matching change due immediately. The Password Delivery Service is woken by the change and attempts them within about a second, whatever the synchronisation engine is doing. This is what you run once the reason a Connected System refused the passwords has been dealt with: the changes are parked behind that system, and nothing will attempt them again until somebody says so. Applies to changes JIM could still deliver, which is Pending, Parked and Cancelled. An Expired change is left alone: the password it carried is gone, so there is nothing to send. Retrying a change clears the failure recorded against it and resets its attempt count. Whatever it covers, this is one request and one Activity. Piping a hundred parked changes in does not produce a hundred audit entries; a retry over a directory that has come back is one decision, and the record should say so. The command is named Resume- rather than Retry- because Retry is not a PowerShell approved verb; a module exporting one warns on import. Resume is the approved verb for starting something that was suspended, which is what a parked or cancelled change is. .PARAMETER Id The IDs of the queued changes to retry. Combines with the other criteria rather than replacing them, so -Status Parked alongside piped changes means these changes, if they are still parked. .PARAMETER ConnectedSystemId Retry the changes queued for this Connected System. .PARAMETER Status Retry only changes in this state. An Expired change is never retried, so -Status Expired matches nothing. .PARAMETER FailureReason Retry only changes whose last attempt failed this way. .PARAMETER MetaverseObjectId Retry only this Metaverse Object's queued changes. .PARAMETER Search Retry only changes matching this free-text search over the Metaverse Object and Connected System names. .PARAMETER EntireQueue Retry every queued password change in the deployment. Required when nothing else narrows the request, so a command that names no criteria cannot act on everything by accident. .PARAMETER Force Skips the confirmation prompt. .OUTPUTS One object, whose AffectedCount says how many changes were made due again. Zero is an answer, not an error. .EXAMPLE Resume-JIMPendingPasswordChange -ConnectedSystemId 3 Retries every queued password change for Connected System 3. The usual command after a directory that was refusing passwords has been fixed. .EXAMPLE Get-JIMPendingPasswordChange -Status Parked | Resume-JIMPendingPasswordChange -Force Retries every parked change, in a single request. Run the Get on its own first to see what that covers. .EXAMPLE Resume-JIMPendingPasswordChange -Status Parked -FailureReason Transient -WhatIf Shows what would be retried without retrying it: the changes that failed for a reason that may well have gone away on its own. .EXAMPLE $result = Resume-JIMPendingPasswordChange -ConnectedSystemId 3 -Force "$($result.AffectedCount) password change(s) will be attempted again." Reports how much the retry covered. Zero is a valid answer, not an error: it means nothing was owed. .LINK Get-JIMPendingPasswordChange Stop-JIMPendingPasswordChange Set-JIMMetaverseObjectPassword #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')] [OutputType('JIM.PasswordQueueActionResponse')] param( [Parameter(ValueFromPipelineByPropertyName)] [guid[]]$Id, [Parameter(ValueFromPipelineByPropertyName)] [int]$ConnectedSystemId, [Parameter()] [ValidateSet('Pending', 'Parked', 'Expired', 'Cancelled')] [string]$Status, [Parameter()] [ValidateSet('None', 'Transient', 'ConfigurationFault', 'PolicyRejection', 'TargetObjectNotFound', 'UnsupportedOperation')] [string]$FailureReason, [Parameter()] [guid]$MetaverseObjectId, [Parameter()] [string]$Search, [Parameter()] [switch]$EntireQueue, [Parameter()] [switch]$Force ) begin { # Collected here and acted on in end, deliberately. A per-row request would be one Activity per row, and # the server records an Activity per administrator action precisely so a bulk retry reads as the one # decision it was. $collectedIds = [System.Collections.Generic.List[guid]]::new() } process { if ($Id) { foreach ($changeId in $Id) { $collectedIds.Add($changeId) } } } end { 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 } # An empty pipeline is a successful no-op, not a failure: "retry everything parked" on a day when # nothing is parked is exactly the outcome the caller wanted. if ($collectedIds.Count -eq 0 -and $PSCmdlet.MyInvocation.ExpectingInput -and -not $PSBoundParameters.ContainsKey('ConnectedSystemId')) { Write-Verbose "Nothing reached Resume-JIMPendingPasswordChange from the pipeline; there is nothing to retry." return } $target = if ($collectedIds.Count -gt 0) { if ($collectedIds.Count -eq 1) { "1 queued password change" } else { "$($collectedIds.Count) queued password changes" } } elseif ($EntireQueue) { "every queued password change" } else { "the matching queued password changes" } if (-not (Confirm-JIMAction -Cmdlet $PSCmdlet -Target $target -Action "Attempt delivery again" -Force:$Force)) { return } Invoke-JIMPasswordQueueAction -Action 'retry' -Id $collectedIds.ToArray() ` -BoundParameters $PSBoundParameters -EntireQueue:$EntireQueue } } |