Public/SyncRuleMappings/Set-JIMSyncRuleMapping.ps1
|
# Copyright (c) Tetron Limited. All rights reserved. # Licensed under the Tetron Commercial License. See LICENSE file in the project root. function Set-JIMSyncRuleMapping { <# .SYNOPSIS Updates the settings on an existing Synchronisation Rule Mapping (Attribute Flow). .DESCRIPTION Changes how an existing Attribute Flow behaves, leaving what it reads and writes alone. Only the parameters you supply are changed; everything else is left as it is. What a mapping targets, and whether its source is an attribute or an Expression, cannot be changed here. Those revalidate against attribute types and plurality, and for an import mapping they reopen its place in the attribute's priority order, so they remain a Remove-JIMSyncRuleMapping followed by a New-JIMSyncRuleMapping. .PARAMETER SyncRuleId The unique identifier of the Synchronisation Rule the mapping belongs to. .PARAMETER MappingId The unique identifier of the Mapping to update. .PARAMETER InputObject Mapping object to update (from pipeline). .PARAMETER Expression Replaces the mapping's expression. Expression mappings only. .PARAMETER MissingInputBehaviour What the expression does when an attribute it reads has no value on the object being synchronised. Expression mappings only. - EvaluateAnyway: evaluate with the input absent and contribute whatever it returns. - ContributeNoValue: do not evaluate; contribute nothing, resolved by Attribute Priority. - FailMapping: do not evaluate; record an ExpressionMissingInput error. The object's other attributes still flow. - FailObject: do not evaluate anything for the object; it is errored and left untouched. .PARAMETER NullIsValue Whether a contribution of no value from this mapping is authoritative. Import mappings only. .PARAMETER InboundValueProcessing Text value-processing transforms applied as the value flows to the Metaverse, as a comma-separated set of flag names (for example 'TreatWhitespaceAsNoValue, TrimWhitespace'). Import mappings only. .PARAMETER CaseNormalisation Case normalisation applied as the value flows to the Metaverse. Import mappings only. .PARAMETER InitialExportOnly Whether the mapping flows only during the initial provisioning export. Export mappings only. .PARAMETER Enabled Enables or disables the mapping. A disabled mapping is skipped by synchronisation in both directions until it is re-enabled; re-enabling clears any recorded disabled reason. Applies to import and export mappings alike. .PARAMETER TokenKind Changes which uniqueness token a generated mapping appends: OnlyIfTaken, Sequence or Random. Generated mappings only. Converting an ordinary mapping to or from a generated one is not supported here (delete and create). .PARAMETER SuffixStyle OnlyIfTaken only: whether the collision suffix is a Number or a Letter. .PARAMETER SuffixStart OnlyIfTaken only: the first suffix value tried once the bare base value is taken. .PARAMETER SequenceStart Sequence only: the lowest number this flow will ever issue. Raising it above the target attribute's counter moves the counter forward at save time; the response's Generation.SequenceSkippedAhead reports the move, and a warning names the old and new positions. A lower or equal value has no effect. .PARAMETER SequenceIncrement Sequence only: how much the counter advances per issued number. .PARAMETER FixedWidth Sequence only: zero-pads the number to this many digits. Supply 0 to clear the padding; omit to leave it unchanged. .PARAMETER OnWidthExceeded Sequence only: what happens when a number would no longer fit -FixedWidth. StopAndReport stops the object with an attributed error; AllowLonger lets the number grow past the width. .PARAMETER RandomFormat Random only: the shape of the token (Guid, Hex or Digits). .PARAMETER RandomLength Random only: the length of the token in characters. Required alongside -RandomFormat Hex or Digits; must not be supplied for Guid. .PARAMETER Separator The characters placed between the base value and the token. Supply an empty string ('' or $null) to clear it; omit to leave it unchanged. .PARAMETER AttemptLimit The maximum number of candidates tried, per object per synchronisation run, before generation fails hard for that object. .PARAMETER NeverReuse Whether a value whose assignment is deleted is retired and never issued again by this flow. Always treated as true for a Sequence token, whatever is supplied. .PARAMETER PassThru Returns the updated mapping. .OUTPUTS None by default. The updated mapping when -PassThru is supplied. A generated mapping's Generation property carries its uniqueness token settings; Generation.SequenceSkippedAhead is present only when -SequenceStart raised the target attribute's counter on this save. Warnings lists any non-blocking warnings the save raised (empty when there were none); each is written with Write-Warning whether or not -PassThru is supplied. .EXAMPLE Set-JIMSyncRuleMapping -SyncRuleId 2 -MappingId 15 -MissingInputBehaviour FailObject Stops an object with a missing input exporting at all, rather than exporting a Distinguished Name built around the gap. .EXAMPLE Set-JIMSyncRuleMapping -SyncRuleId 1 -MappingId 8 -Expression 'Lower(cs["mail"])' -PassThru Rewrites an import mapping's expression and returns the updated mapping. .EXAMPLE Set-JIMSyncRuleMapping -SyncRuleId 1 -MappingId 8 -Enabled $false Disables one Attribute Flow without touching the Synchronisation Rule; the mapping is skipped by synchronisation until it is re-enabled with -Enabled $true. .EXAMPLE Get-JIMSyncRuleMapping -SyncRuleId 1 | Where-Object { $_.sourceType -eq 'ExpressionMapping' } | Set-JIMSyncRuleMapping -SyncRuleId 1 -MissingInputBehaviour FailMapping Reports every expression mapping on the Rule that meets an object with a missing input, rather than letting it contribute a value built around the gap. .EXAMPLE Set-JIMSyncRuleMapping -SyncRuleId 1 -MappingId 12 -SequenceStart 500000 Raises a generated Sequence mapping's Sequence Start; if the counter was already below 500000 this moves it forward and warns naming the old and new positions. .EXAMPLE Set-JIMSyncRuleMapping -SyncRuleId 1 -MappingId 12 -FixedWidth 0 Clears a generated Sequence mapping's fixed width, so numbers are no longer zero-padded. .LINK Get-JIMSyncRuleMapping New-JIMSyncRuleMapping Remove-JIMSyncRuleMapping Get-JIMGeneratedValueSequence Restart-JIMGeneratedValues #> [CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = 'ById')] param( [Parameter(Mandatory)] [int]$SyncRuleId, [Parameter(Mandatory, ParameterSetName = 'ById', ValueFromPipelineByPropertyName)] [Alias('Id')] [int]$MappingId, [Parameter(Mandatory, ParameterSetName = 'ByInputObject', ValueFromPipeline)] [PSCustomObject]$InputObject, [string]$Expression, [ValidateSet('EvaluateAnyway', 'ContributeNoValue', 'FailMapping', 'FailObject')] [string]$MissingInputBehaviour, [bool]$NullIsValue, [string]$InboundValueProcessing, [ValidateSet('None', 'Upper', 'Lower', 'Title')] [string]$CaseNormalisation, [bool]$InitialExportOnly, [bool]$Enabled, # Unique Value Generation (#242): a generated mapping's uniqueness token settings. Refused by the # server for a mapping that is not currently a generated mapping. [ValidateSet('OnlyIfTaken', 'Sequence', 'Random')] [string]$TokenKind, [ValidateSet('Number', 'Letter')] [string]$SuffixStyle, [int]$SuffixStart, [long]$SequenceStart, [int]$SequenceIncrement, [int]$FixedWidth, [ValidateSet('StopAndReport', 'AllowLonger')] [string]$OnWidthExceeded, [ValidateSet('Guid', 'Hex', 'Digits')] [string]$RandomFormat, [int]$RandomLength, [string]$Separator, [int]$AttemptLimit, [bool]$NeverReuse, [switch]$PassThru ) process { # Check connection first 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 } $mapId = if ($InputObject) { $InputObject.id } else { $MappingId } # Only send what the caller named. An omitted setting must reach the API as absent rather than # as a default, or every call would silently rewrite settings it was never asked about. $body = @{} if ($PSBoundParameters.ContainsKey('Expression')) { $body.expression = $Expression } if ($PSBoundParameters.ContainsKey('MissingInputBehaviour')) { $body.missingInputBehaviour = $MissingInputBehaviour } if ($PSBoundParameters.ContainsKey('NullIsValue')) { $body.nullIsValue = $NullIsValue } if ($PSBoundParameters.ContainsKey('InboundValueProcessing')) { $body.inboundValueProcessing = $InboundValueProcessing } if ($PSBoundParameters.ContainsKey('CaseNormalisation')) { $body.caseNormalisation = $CaseNormalisation } if ($PSBoundParameters.ContainsKey('InitialExportOnly')) { $body.initialExportOnly = $InitialExportOnly } if ($PSBoundParameters.ContainsKey('Enabled')) { $body.enabled = $Enabled } # Unique Value Generation (#242): only settings the caller named are sent, nested under `generation` # (matching UpdateSyncRuleMappingGenerationRequest). -FixedWidth 0 clears the padding; omitting it # leaves it unchanged. $generation = @{} if ($PSBoundParameters.ContainsKey('TokenKind')) { $generation.tokenKind = $TokenKind } if ($PSBoundParameters.ContainsKey('SuffixStyle')) { $generation.suffixStyle = $SuffixStyle } if ($PSBoundParameters.ContainsKey('SuffixStart')) { $generation.suffixStart = $SuffixStart } if ($PSBoundParameters.ContainsKey('SequenceStart')) { $generation.sequenceStart = $SequenceStart } if ($PSBoundParameters.ContainsKey('SequenceIncrement')) { $generation.sequenceIncrement = $SequenceIncrement } if ($PSBoundParameters.ContainsKey('FixedWidth')) { $generation.fixedWidth = $FixedWidth } if ($PSBoundParameters.ContainsKey('OnWidthExceeded')) { $generation.onWidthExceeded = $OnWidthExceeded } if ($PSBoundParameters.ContainsKey('RandomFormat')) { $generation.randomFormat = $RandomFormat } if ($PSBoundParameters.ContainsKey('RandomLength')) { $generation.randomLength = $RandomLength } if ($PSBoundParameters.ContainsKey('Separator')) { $generation.separator = $Separator } if ($PSBoundParameters.ContainsKey('AttemptLimit')) { $generation.attemptLimit = $AttemptLimit } if ($PSBoundParameters.ContainsKey('NeverReuse')) { $generation.neverReuse = $NeverReuse } if ($generation.Count -gt 0) { $body.generation = $generation } if ($body.Count -eq 0) { Write-Error "No settings were supplied to change. Supply at least one of -Expression, -MissingInputBehaviour, -NullIsValue, -InboundValueProcessing, -CaseNormalisation, -InitialExportOnly, -Enabled, or a generated mapping's uniqueness token settings (-TokenKind, -SuffixStyle, -SuffixStart, -SequenceStart, -SequenceIncrement, -FixedWidth, -OnWidthExceeded, -RandomFormat, -RandomLength, -Separator, -AttemptLimit, -NeverReuse)." return } $displayName = "Mapping $mapId in Synchronisation Rule $SyncRuleId" if ($PSCmdlet.ShouldProcess($displayName, "Update Synchronisation Rule Mapping")) { Write-Verbose "Updating Synchronisation Rule Mapping: $mapId in Synchronisation Rule: $SyncRuleId" try { $result = Invoke-JIMApi -Endpoint "/api/v1/synchronisation/sync-rules/$SyncRuleId/mappings/$mapId" -Method 'PATCH' -Body $body Write-Verbose "Updated Synchronisation Rule Mapping: $mapId" # A raised -SequenceStart moves the target attribute's counter forward at save time (plan # decision 3); the response reports it rather than doing it silently. if ($result.Generation.SequenceSkippedAhead) { $skip = $result.Generation.SequenceSkippedAhead Write-Warning "Mapping $mapId's Sequence counter moved from $($skip.From) to $($skip.To) to honour the requested Sequence Start." } # Non-blocking warnings the save raised (for example, an Attribute Flow deriving a Metaverse # attribute that calls a function returning a different value each time, #1750). The save went # ahead; each warning is written as the server phrased it. foreach ($saveWarning in @($result.Warnings | Where-Object { $_ })) { Write-Warning $saveWarning } if ($PassThru) { $result } } catch { Write-Error "Failed to update Synchronisation Rule Mapping: $_" } } } } |