Public/Metaverse/Remove-JIMMetaverseObjectTypeAttribute.ps1
|
# Copyright (c) Tetron Limited. All rights reserved. # Licensed under the Tetron Commercial License. See LICENSE file in the project root. function Remove-JIMMetaverseObjectTypeAttribute { <# .SYNOPSIS Unassigns a custom Metaverse Attribute from a Metaverse Object Type. .DESCRIPTION Removes the binding between a custom Metaverse Attribute and a Metaverse Object Type. The cmdlet first fetches an unassign preview to decide how to proceed: - If any Metaverse Object of the target type holds a stored value for the attribute, unassignment is a hard block; the cmdlet refuses and reports the affected object count. Clear the values first. - If Synchronisation Rules targeting the type reference the attribute (Attribute Flows, scoping criteria, Object Matching Rules), those type-scoped references are cascade-removed alongside the binding. This is guarded server-side by a type-the-name confirmation, which the cmdlet satisfies automatically once you confirm (or pass -Force); the cascade is recorded as child Activities. - If only the plain binding exists, it is simply removed. If the attribute is not bound to the Object Type, the cmdlet reports it and does nothing. Built-in attributes cannot be unassigned. .PARAMETER AttributeId The unique identifier of the Metaverse Attribute to unassign. .PARAMETER ObjectTypeId The unique identifier of the Metaverse Object Type to unassign the attribute from. .PARAMETER ChangeReason Optional reason for the change, recorded on the audit Activity and shown in the object's configuration change history. .PARAMETER Force Skips the confirmation prompt. The server-side type-the-name safeguard is still satisfied by the cmdlet; -Force only suppresses the interactive PowerShell prompt. .OUTPUTS None. .EXAMPLE Remove-JIMMetaverseObjectTypeAttribute -AttributeId 42 -ObjectTypeId 1 Unassigns attribute 42 from Object Type 1 after confirmation, cascade-removing any type-scoped references. .EXAMPLE Remove-JIMMetaverseObjectTypeAttribute -AttributeId 42 -ObjectTypeId 1 -Force Unassigns without an interactive prompt. .LINK Add-JIMMetaverseObjectTypeAttribute Get-JIMMetaverseAttribute Remove-JIMMetaverseAttribute #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] [Alias('Id')] [int]$AttributeId, [Parameter(Mandatory)] [int]$ObjectTypeId, [Parameter()] [ValidateNotNullOrEmpty()] [string]$ChangeReason, [switch]$Force ) 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 } # Fetch the unassign preview to decide how to proceed and to obtain the exact attribute name # for the server's type-the-name confirmation. try { $impact = Invoke-JIMApi -Endpoint "/api/v1/metaverse/attributes/$AttributeId/object-types/$ObjectTypeId/unassign-preview" } catch { Write-Error "Failed to evaluate unassignment of Metaverse Attribute $AttributeId from Object Type ${ObjectTypeId}: $_" return } if ($impact.builtIn) { Write-Error "Cannot unassign '$($impact.attributeName)': built-in attributes cannot be unassigned." return } if (-not $impact.wasBound) { Write-Warning "Metaverse Attribute '$($impact.attributeName)' is not bound to Object Type '$($impact.metaverseObjectTypeName)'. Nothing to do." return } if ($impact.blockedByValues) { Write-Error "Cannot unassign '$($impact.attributeName)' from '$($impact.metaverseObjectTypeName)': $($impact.objectsWithValues) Metaverse Object(s) of that type hold a stored value for it. Clear the values first, then retry." return } # References include the binding row itself; cascade items are those beyond the plain binding. $cascadeCount = if ($impact.references) { @($impact.references | Where-Object { $_.kind -ne 'Binding' }).Count } else { 0 } $action = if ($cascadeCount -gt 0) { "Unassign Metaverse Attribute and cascade-remove $cascadeCount type-scoped reference(s)" } else { "Unassign Metaverse Attribute from Object Type" } if ($Force -and -not $PSBoundParameters.ContainsKey('Confirm')) { $ConfirmPreference = 'None' } $target = "$($impact.attributeName) -> $($impact.metaverseObjectTypeName)" if ($PSCmdlet.ShouldProcess($target, $action)) { Write-Verbose "Unassigning Metaverse Attribute '$($impact.attributeName)' from Object Type '$($impact.metaverseObjectTypeName)'; type-scoped references to cascade: $cascadeCount" try { # Always send confirmationName: the server requires it to match when type-scoped # references exist and ignores it otherwise. $query = "confirmationName=$([uri]::EscapeDataString([string]$impact.attributeName))" if ($ChangeReason) { $query += "&changeReason=$([uri]::EscapeDataString($ChangeReason))" } $null = Invoke-JIMApi -Endpoint "/api/v1/metaverse/attributes/$AttributeId/object-types/$ObjectTypeId`?$query" -Method 'DELETE' Write-Verbose "Unassigned Metaverse Attribute '$($impact.attributeName)' from Object Type '$($impact.metaverseObjectTypeName)'" } catch { Write-Error "Failed to unassign Metaverse Attribute '$($impact.attributeName)' from Object Type '$($impact.metaverseObjectTypeName)': $_" } } } } |