Public/Metaverse/Set-JIMMetaverseObjectType.ps1
|
# Copyright (c) Tetron Limited. All rights reserved. # Licensed under the Tetron Commercial License. See LICENSE file in the project root. function Set-JIMMetaverseObjectType { <# .SYNOPSIS Updates a Metaverse Object Type's deletion rules in JIM. .DESCRIPTION Updates an existing Metaverse Object Type: its identity (name, plural name, icon) and/or its deletion rule settings (which control how and when Metaverse Objects of this type are automatically deleted). Built-in types (User, Group) accept deletion-rule changes but reject changes to Name, Plural Name and Icon. When the stored deletion rule is WhenLastConnectorDisconnected and enabled provisioning export Synchronisation Rules exist for the type, the API attaches a configuration advisory (provisioned target accounts count as connectors, so objects outlive their last source and keep its values as last known state) and the cmdlet surfaces it as a warning; the returned object carries it as DeletionRuleAdvisory. .PARAMETER Id The unique identifier of the Object Type to update. .PARAMETER Name The name of a specific Object Type to update (used to locate it; use -NewName to rename). .PARAMETER InputObject Object Type object to update (from pipeline). .PARAMETER NewName A new singular name for the Object Type (rename). Must be unique (compared case-insensitively). Cannot be changed on a built-in type. .PARAMETER PluralName A new plural name for the Object Type. Must be unique (compared case-insensitively). Cannot be changed on a built-in type. .PARAMETER Icon The MudBlazor icon name shown for the type in the UI (e.g. "Devices"). Pass $null or '' to clear it. Cannot be changed on a built-in type. .PARAMETER DeletionRule The deletion rule for objects of this type. - Manual: Objects are never automatically deleted - WhenLastConnectorDisconnected: Objects are deleted when all connectors are removed - WhenAuthoritativeSourceDisconnected: Objects are deleted when any authoritative source disconnects (requires DeletionTriggerConnectedSystemIds) .PARAMETER DeletionGracePeriod Grace period before deletion is executed, as a TimeSpan. Examples: [TimeSpan]::FromMinutes(1), [TimeSpan]::FromDays(30), [TimeSpan]::FromHours(2) Set to [TimeSpan]::Zero or omit for immediate deletion when conditions are met. .PARAMETER DeletionTriggerConnectedSystemIds Array of Connected System IDs that are authoritative sources for deletion. Required when DeletionRule is WhenAuthoritativeSourceDisconnected. How they trigger deletion is governed by -DeletionTriggerMode. Ignored when DeletionRule is Manual or WhenLastConnectorDisconnected. .PARAMETER DeletionTriggerMode For the WhenAuthoritativeSourceDisconnected deletion rule, controls how the selected authoritative sources trigger deletion. - AllSourcesDisconnect: the Metaverse Object is deleted only once no selected source retains a joined Connected System Object. - SpecificSourcesDisconnect: the Metaverse Object is deleted when any one of the selected sources disconnects, even if others remain connected. When omitted, the stored mode is left unchanged. .PARAMETER ChangeReason Optional reason for the change, recorded on the audit Activity and shown in the object's configuration change history. .PARAMETER PreviewActivityId The Configuration Change Preview read before making this change, if any. Pass the ActivityId returned by New-JIMConfigurationChangePreview and the update's own Activity records the link, so the audit answers not only what changed but what the caller was told it would do. Optional: a preview is an affordance, not a precondition. .PARAMETER PassThru If specified, returns the updated Object Type object. .OUTPUTS If -PassThru is specified, returns the updated Object Type object. .EXAMPLE Set-JIMMetaverseObjectType -Id 1 -DeletionRule WhenLastConnectorDisconnected -DeletionGracePeriod ([TimeSpan]::FromDays(30)) Configures User type to delete 30 days after last connector disconnects. .EXAMPLE Set-JIMMetaverseObjectType -Name 'User' -DeletionGracePeriod ([TimeSpan]::Zero) Configures immediate deletion for User type when connectors disconnect. .EXAMPLE Get-JIMMetaverseObjectType -Name 'User' | Set-JIMMetaverseObjectType -DeletionGracePeriod ([TimeSpan]::FromDays(7)) -PassThru Updates from pipeline and returns the updated object. .EXAMPLE Set-JIMMetaverseObjectType -Id 1 -DeletionGracePeriod ([TimeSpan]::FromMinutes(1)) Configures a 1-minute grace period (useful for testing). .EXAMPLE Set-JIMMetaverseObjectType -Id 1 -DeletionRule WhenAuthoritativeSourceDisconnected -DeletionTriggerConnectedSystemIds 1,2 Configure deletion to trigger when HR system (ID 1) or AD system (ID 2) disconnects. .EXAMPLE Set-JIMMetaverseObjectType -Id 1 -DeletionTriggerConnectedSystemIds 1,2 -DeletionTriggerMode AllSourcesDisconnect Configure deletion to trigger only once both HR systems (IDs 1 and 2) have disconnected; while either retains a joined Connected System Object, the Metaverse Object is kept. .EXAMPLE Set-JIMMetaverseObjectType -Id 5 -NewName 'Gadget' -PluralName 'Gadgets' -Icon 'Devices' Renames a custom Object Type and sets its UI icon. .EXAMPLE Set-JIMMetaverseObjectType -Id 5 -Icon $null Clears the Object Type's icon (passing '' is equivalent). .EXAMPLE $preview = New-JIMConfigurationChangePreview -MetaverseObjectTypeId 1 -DeletionRule WhenLastConnectorDisconnected -Wait Set-JIMMetaverseObjectType -Id 1 -DeletionRule WhenLastConnectorDisconnected -PreviewActivityId $preview.ActivityId Applies the change that was previewed, recording which preview informed it. .LINK Get-JIMMetaverseObjectType Remove-JIMMetaverseObjectType Get-JIMMetaverseObject New-JIMConfigurationChangePreview #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium', DefaultParameterSetName = 'ById')] [OutputType([PSCustomObject])] param( [Parameter(Mandatory, ParameterSetName = 'ById', ValueFromPipelineByPropertyName)] [int]$Id, [Parameter(Mandatory, ParameterSetName = 'ByName')] [ValidateNotNullOrEmpty()] [string]$Name, [Parameter(Mandatory, ParameterSetName = 'ByInputObject', ValueFromPipeline)] [PSCustomObject]$InputObject, [Parameter()] [ValidateNotNullOrEmpty()] [string]$NewName, [Parameter()] [ValidateNotNullOrEmpty()] [string]$PluralName, [Parameter()] [string]$Icon, [Parameter()] [ValidateSet('Manual', 'WhenLastConnectorDisconnected', 'WhenAuthoritativeSourceDisconnected')] [string]$DeletionRule, [Parameter()] [TimeSpan]$DeletionGracePeriod, [Parameter()] [int[]]$DeletionTriggerConnectedSystemIds, [Parameter()] [ValidateSet('AllSourcesDisconnect', 'SpecificSourcesDisconnect')] [string]$DeletionTriggerMode, [Parameter()] [ValidateNotNullOrEmpty()] [string]$ChangeReason, [Parameter()] [guid]$PreviewActivityId, [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 } # Resolve name to ID if using ByName parameter set if ($PSCmdlet.ParameterSetName -eq 'ByName') { try { $resolvedType = Resolve-JIMMetaverseObjectType -Name $Name $Id = $resolvedType.id } catch { Write-Error $_ return } } elseif ($InputObject) { $Id = $InputObject.id } # Build update body $body = @{} if ($PSBoundParameters.ContainsKey('NewName')) { $body.name = $NewName } if ($PSBoundParameters.ContainsKey('PluralName')) { $body.pluralName = $PluralName } # Icon is clearable: both $null and '' clear it (the binder coerces $null to '' for [string]). if ($PSBoundParameters.ContainsKey('Icon')) { $body.icon = $Icon } if ($DeletionRule) { # Enum sent as its string name; -DeletionRule's ValidateSet equals the # MetaverseObjectDeletionRule member names. The API rejects numeric ordinals # (JsonStringEnumConverter allowIntegerValues:false, PR #1060). $body.deletionRule = $DeletionRule } if ($PSBoundParameters.ContainsKey('DeletionGracePeriod')) { # API expects TimeSpan as "d.hh:mm:ss" string format $body.deletionGracePeriod = $DeletionGracePeriod.ToString() } if ($PSBoundParameters.ContainsKey('DeletionTriggerConnectedSystemIds')) { $body.deletionTriggerConnectedSystemIds = $DeletionTriggerConnectedSystemIds } if ($PSBoundParameters.ContainsKey('DeletionTriggerMode')) { # Enum sent as its string name; -DeletionTriggerMode's ValidateSet equals the # AuthoritativeSourceTriggerMode member names. Only sent when bound, so an # omitted parameter leaves the stored mode unchanged. $body.deletionTriggerMode = $DeletionTriggerMode } if ($body.Count -eq 0) { Write-Warning "No updates specified." return } if ($ChangeReason) { $body.changeReason = $ChangeReason } # Set after the "no updates specified" guard above deliberately: a preview link on its own is not # a change, and recording one against an update that changes nothing would be a false audit entry. if ($PSBoundParameters.ContainsKey('PreviewActivityId')) { $body.previewActivityId = $PreviewActivityId } $displayName = $Name ?? "ID $Id" if ($PSCmdlet.ShouldProcess($displayName, "Update Metaverse Object Type")) { Write-Verbose "Updating Metaverse Object Type: $Id" try { $result = Invoke-JIMApi -Endpoint "/api/v1/metaverse/object-types/$Id" -Method 'PUT' -Body $body Write-Verbose "Updated Metaverse Object Type: $Id" # Configuration advisory (#1570): the API attaches advice when the stored deletion rule will # keep objects alive after their last source departs (provisioned targets count as connectors). if ($result.deletionRuleAdvisory) { Write-Warning $result.deletionRuleAdvisory } if ($PassThru) { $result } } catch { Write-Error "Failed to update Metaverse Object Type: $_" } } } } |