Public/ScopingCriteria/Set-JIMScopingCriterion.ps1
|
# Copyright (c) Tetron Limited. All rights reserved. # Licensed under the Tetron Commercial License. See LICENSE file in the project root. function Set-JIMScopingCriterion { <# .SYNOPSIS Replaces a criterion in a scoping criteria group. .DESCRIPTION Replaces a criterion: its attribute (or expression), comparison and value are all set from what you give, as New-JIMScopingCriterion would set them. Its case sensitivity is kept unless -CaseSensitive is given. .PARAMETER SyncRuleId The ID of the Synchronisation Rule. .PARAMETER GroupId The ID of the group the criterion is in. .PARAMETER CriterionId The ID of the criterion to replace. .PARAMETER MetaverseAttributeId The ID of the Metaverse attribute to test. An export Synchronisation Rule's criteria test Metaverse attributes. .PARAMETER MetaverseAttributeName The name of the Metaverse attribute to test, instead of its ID. .PARAMETER ConnectedSystemAttributeId The ID of the Connected System attribute to test. An import Synchronisation Rule's criteria test Connected System attributes. .PARAMETER ConnectedSystemAttributeName The name of the Connected System attribute to test, instead of its ID. .PARAMETER Expression An expression whose computed value the criterion compares, in place of an attribute. It reads the object the Synchronisation Rule scopes: cs["name"] on an import rule, mv["Name"] on an export rule. Use it to compare a value reshaped first, such as Lower(Trim(cs["department"])). Requires -CompareAs. .PARAMETER CompareAs The type the expression's computed value is compared as, which decides the comparisons and the value parameter that apply, as an attribute's own type does. A value the expression computes that cannot be read as this type stops that object with an error rather than deciding its scope. .PARAMETER ComparisonType How the attribute is compared with the value. The Not forms are met when the attribute holds a value and none matches; the others when any value does. HasValue and HasNoValue test whether the attribute holds a value at all and take no value. MatchesPattern and NotMatchesPattern take a .NET regular expression in -StringValue, for Text attributes. .PARAMETER StringValue The value to compare a Text attribute with, or the regular expression for MatchesPattern and NotMatchesPattern. .PARAMETER IntValue The value to compare a Number attribute with. .PARAMETER LongValue The value to compare a LongNumber attribute with. .PARAMETER DecimalValue The value to compare a Decimal attribute with. For a high-precision value, use the d suffix (123.456789012345678d) or a quoted string: a bare number is read as a double first, and can lose precision. .PARAMETER DateTimeValue The date and time to compare a DateTime attribute with, when -ValueMode is Absolute. .PARAMETER BoolValue The value to compare a Boolean attribute with. .PARAMETER GuidValue The value to compare a Guid attribute with. .PARAMETER CaseSensitive Whether a Text comparison respects case: $false ignores it. When omitted, the criterion keeps its current setting. .PARAMETER ValueMode For a DateTime attribute: Absolute compares with -DateTimeValue, and Relative with a date worked out from now each time the rule is evaluated, set by -RelativeCount, -RelativeUnit and -RelativeDirection. Relative cannot be used with -DateTimeValue. Absolute when omitted. .PARAMETER RelativeCount How many units from now the date is, zero or more. Used with -ValueMode Relative. .PARAMETER RelativeUnit The unit -RelativeCount counts. Used with -ValueMode Relative. .PARAMETER RelativeDirection Whether the date is in the past (Ago) or the future (FromNow). Used with -ValueMode Relative. .PARAMETER SaveAnyway Saves even though the change stops configuration test cases passing. Without it, or -AcceptNewResult, such a change is refused, nothing is saved, and the error names each case. Configuration History records the cases saved past, by name. .PARAMETER AcceptNewResult Takes what the configuration now gives as what each configuration test case that stopped passing expects, rewriting those cases, and saves. A case whose new result cannot be expected (it needs review, could not run, or its Scope cannot be determined) still refuses the change unless -SaveAnyway is given too. .PARAMETER PassThru Returns the criterion as replaced. .OUTPUTS With -PassThru, the criterion as replaced; otherwise nothing. JIM.ScopingCriterion SyncRuleId (int): The ID of the Synchronisation Rule the criterion belongs to. GroupId (int): The ID of the group the criterion is in. With SyncRuleId and Id, it lets the criterion be piped to Set-JIMScopingCriterion and Remove-JIMScopingCriterion. .EXAMPLE Set-JIMScopingCriterion -SyncRuleId 5 -GroupId 10 -CriterionId 15 -MetaverseAttributeName 'AccountExpiry' -ComparisonType LessThanOrEquals -ValueMode Relative -RelativeCount 7 -RelativeUnit Days -RelativeDirection FromNow Updates criterion 15 to match when AccountExpiry is on or before 7 days from now. .EXAMPLE Set-JIMScopingCriterion -SyncRuleId 5 -GroupId 10 -CriterionId 15 -Expression 'Upper(Trim(mv["Department"]))' -CompareAs Text -ComparisonType Equals -StringValue 'FINANCE' Updates criterion 15 to compare the Department with its spacing removed and in capitals, so ' Finance ' and 'finance' are both in scope. .LINK New-JIMScopingCriterion Get-JIMScopingCriteria Remove-JIMScopingCriterion #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium', DefaultParameterSetName = 'ByMvId')] [OutputType('JIM.ScopingCriterion')] param( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [int]$SyncRuleId, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [int]$GroupId, [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Alias('Id')] [int]$CriterionId, [Parameter(Mandatory, ParameterSetName = 'ByMvId')] [int]$MetaverseAttributeId, [Parameter(Mandatory, ParameterSetName = 'ByMvName')] [string]$MetaverseAttributeName, [Parameter(Mandatory, ParameterSetName = 'ByCsId')] [int]$ConnectedSystemAttributeId, [Parameter(Mandatory, ParameterSetName = 'ByCsName')] [string]$ConnectedSystemAttributeName, [Parameter(Mandatory, ParameterSetName = 'ByExpression')] [ValidateNotNullOrEmpty()] [string]$Expression, [Parameter(Mandatory, ParameterSetName = 'ByExpression')] [ValidateSet('Text', 'Number', 'LongNumber', 'Decimal', 'DateTime', 'Boolean', 'Guid')] [string]$CompareAs, [Parameter(Mandatory)] [ValidateSet('Equals', 'NotEquals', 'StartsWith', 'NotStartsWith', 'EndsWith', 'NotEndsWith', 'Contains', 'NotContains', 'LessThan', 'LessThanOrEquals', 'GreaterThan', 'GreaterThanOrEquals', 'HasValue', 'HasNoValue', 'MatchesPattern', 'NotMatchesPattern')] [string]$ComparisonType, [Parameter()] [string]$StringValue, [Parameter()] [int]$IntValue, [Parameter()] [long]$LongValue, [Parameter()] [decimal]$DecimalValue, [Parameter()] [datetime]$DateTimeValue, [Parameter()] [bool]$BoolValue, [Parameter()] [guid]$GuidValue, [Parameter()] [bool]$CaseSensitive, [Parameter()] [ValidateSet('Absolute', 'Relative')] [string]$ValueMode, [Parameter()] [int]$RelativeCount, [Parameter()] [ValidateSet('Hours', 'Days', 'Weeks', 'Months', 'Years')] [string]$RelativeUnit, [Parameter()] [ValidateSet('Ago', 'FromNow')] [string]$RelativeDirection, [switch]$SaveAnyway, [switch]$AcceptNewResult, [switch]$PassThru ) 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 } $body = @{ comparisonType = $ComparisonType } if ($PSCmdlet.ParameterSetName -eq 'ByMvId') { $body.metaverseAttributeId = $MetaverseAttributeId } elseif ($PSCmdlet.ParameterSetName -eq 'ByMvName') { try { $attribute = Resolve-JIMMetaverseAttribute -Name $MetaverseAttributeName } catch { Write-Error $_ return } $body.metaverseAttributeId = $attribute.id } elseif ($PSCmdlet.ParameterSetName -eq 'ByCsId') { $body.connectedSystemAttributeId = $ConnectedSystemAttributeId } elseif ($PSCmdlet.ParameterSetName -eq 'ByCsName') { $syncRule = Invoke-JIMApi -Endpoint "/api/v1/synchronisation/sync-rules/$SyncRuleId" if (-not $syncRule) { Write-Error "Synchronisation Rule $SyncRuleId not found." return } if ($syncRule.direction -ne 'Import') { Write-Error "Connected System attributes can only be used with import Synchronisation Rules. This Synchronisation Rule is an export rule." return } $connectedSystemId = $syncRule.connectedSystemId $objectTypeId = $syncRule.connectedSystemObjectTypeId $objectTypes = Invoke-JIMApi -Endpoint "/api/v1/synchronisation/connected-systems/$connectedSystemId/object-types" $objectType = $objectTypes | Where-Object { $_.id -eq $objectTypeId } | Select-Object -First 1 if (-not $objectType) { Write-Error "Could not find object type $objectTypeId on Connected System $connectedSystemId." return } $attribute = $objectType.attributes | Where-Object { $_.name -eq $ConnectedSystemAttributeName } | Select-Object -First 1 if (-not $attribute) { Write-Error "Connected System attribute '$ConnectedSystemAttributeName' not found on object type '$($objectType.name)'." return } $body.connectedSystemAttributeId = $attribute.id } if ($PSCmdlet.ParameterSetName -eq 'ByExpression') { $body.expression = $Expression $body.compareAs = $CompareAs } if ($PSBoundParameters.ContainsKey('StringValue')) { $body.stringValue = $StringValue } if ($PSBoundParameters.ContainsKey('IntValue')) { $body.intValue = $IntValue } if ($PSBoundParameters.ContainsKey('LongValue')) { $body.longValue = $LongValue } if ($PSBoundParameters.ContainsKey('DecimalValue')) { $body.decimalValue = $DecimalValue } if ($PSBoundParameters.ContainsKey('DateTimeValue')) { $body.dateTimeValue = $DateTimeValue.ToString('o') } if ($PSBoundParameters.ContainsKey('BoolValue')) { $body.boolValue = $BoolValue } if ($PSBoundParameters.ContainsKey('GuidValue')) { $body.guidValue = $GuidValue.ToString() } if ($PSBoundParameters.ContainsKey('CaseSensitive')) { $body.caseSensitive = $CaseSensitive } $relativeRequested = ($PSBoundParameters.ContainsKey('ValueMode') -and $ValueMode -eq 'Relative') -or $PSBoundParameters.ContainsKey('RelativeCount') -or $PSBoundParameters.ContainsKey('RelativeUnit') -or $PSBoundParameters.ContainsKey('RelativeDirection') if ($relativeRequested) { if ($PSBoundParameters.ContainsKey('DateTimeValue')) { Write-Error "Provide either -DateTimeValue (absolute) or the relative parameters, not both." return } if (-not ($PSBoundParameters.ContainsKey('RelativeCount') -and $PSBoundParameters.ContainsKey('RelativeUnit') -and $PSBoundParameters.ContainsKey('RelativeDirection'))) { Write-Error "Relative criteria require -RelativeCount, -RelativeUnit and -RelativeDirection." return } $body.valueMode = 'Relative' $body.relativeCount = $RelativeCount $body.relativeUnit = $RelativeUnit $body.relativeDirection = $RelativeDirection } if ($PSCmdlet.ShouldProcess("Criterion $CriterionId in Group $GroupId", "Update")) { try { # The save gate (#2055 Phase 4b): what to do if the change stops configuration test cases passing. if ($SaveAnyway) { $body.saveAnyway = $true } if ($AcceptNewResult) { $body.acceptNewResults = $true } $result = Invoke-JIMApi -Endpoint "/api/v1/synchronisation/sync-rules/$SyncRuleId/scoping-criteria/$GroupId/criteria/$CriterionId" -Method 'PUT' -Body $body # Something the administrator should know about the criterion as saved, such as an expression compared # against a relative date costing a full pass on every Temporal Scope Reconciliation. if ($result.notice) { Write-Warning $result.notice } if ($PassThru) { $result | Add-Member -NotePropertyName 'SyncRuleId' -NotePropertyValue $SyncRuleId -Force $result | Add-Member -NotePropertyName 'GroupId' -NotePropertyValue $GroupId -PassThru -Force } } catch { Write-Error "Failed to update criterion: $_" } } } } |