Public/ExampleData/Add-JIMExampleDataTemplateAttribute.ps1
|
# Copyright (c) Tetron Limited. All rights reserved. # Licensed under the Tetron Commercial License. See LICENSE file in the project root. function Add-JIMExampleDataTemplateAttribute { <# .SYNOPSIS Adds an attribute-generation configuration to a Data Generation Template in JIM. .DESCRIPTION Adds one attribute's generation configuration to an Object Type within an existing Data Generation Template, without restating the rest of the template: the cmdlet reads the template, appends the new attribute to the named Object Type, and writes the whole configuration back. -MetaverseAttribute names the attribute values are generated for. .PARAMETER TemplateId The unique identifier of the Data Generation Template to add the attribute to. .PARAMETER TemplateName The name of the Data Generation Template to add the attribute to. .PARAMETER ObjectType The Metaverse Object Type (name or id) identifying which of the template's Object Types receives the attribute. .PARAMETER MetaverseAttribute The Metaverse Attribute (name or id) values are generated for. Always needed: the cmdlet stops with an error if it is omitted. .PARAMETER Pattern A variable-replacement pattern for constructing string values, for example "{0}.{1}@contoso.com". .PARAMETER Expression An expression that constructs the value from other already-generated attributes via mv["Attribute Name"]. .PARAMETER ExampleDataSet The Example Data Sets (names or ids) values are drawn from. Order follows array order, which is what index-based patterns like "{0} {1}" refer to. .PARAMETER WeightedValue Specific string values to choose from, weighted to control their distribution: one @{ Value = ..; Weight = .. } hashtable per value. .PARAMETER PopulatedValuesPercentage What percentage of generated objects receive a value for this attribute. .PARAMETER BoolTrueDistribution For boolean attributes, the percentage of the objects given a value that are given true. The share is exact, rounded to the nearest object with halves rounded up; when omitted, each object is given true or false at random. .PARAMETER MinDate For date attributes, the earliest value to generate. .PARAMETER MaxDate For date attributes, the latest value to generate. .PARAMETER MinNumber For number attributes, the smallest value to generate. .PARAMETER MaxNumber For number attributes, the largest value to generate. .PARAMETER SequentialNumbers For number attributes, whether values are generated sequentially. .PARAMETER RandomNumbers For number attributes, whether values are generated randomly. .PARAMETER ManagerDepthPercentage For Manager attributes, how far into the organisational hierarchy managers are present. .PARAMETER MvaRefMinAssignments For multi-valued reference attributes, the minimum number of values to assign. .PARAMETER MvaRefMaxAssignments For multi-valued reference attributes, the maximum number of values to assign. .PARAMETER ReferenceMetaverseObjectType For reference attributes, the Metaverse Object Types (names or ids) generated references may point at. .PARAMETER AttributeDependency A condition on another attribute that must hold for this attribute to be generated: @{ MetaverseAttribute = <name or id>; ComparisonType = <operator>; StringValue = <value> }. The operators are the ones Synchronisation Rule scoping offers for the depended-on attribute's data type, such as Equals, GreaterThanOrEquals, StartsWith, MatchesPattern, HasValue and HasNoValue (which take no StringValue). Write StringValue as the attribute's type reads it: numbers with a full stop, dates as 2026-07-01, Booleans as true or false. Text is compared case-sensitively. .PARAMETER ChangeReason A reason for the change, recorded on its Activity and shown in the Data Generation Template's Configuration Change History. .PARAMETER PassThru Returns the updated Data Generation Template. .OUTPUTS With -PassThru, the updated Data Generation Template; otherwise nothing. .EXAMPLE Add-JIMExampleDataTemplateAttribute -TemplateName "Demo Users" -ObjectType "User" -MetaverseAttribute "Display Name" -Pattern "{0} {1}" -ExampleDataSet "Firstnames Female", "Lastnames" Adds pattern-based Display Name generation drawing from two Example Data Sets. .EXAMPLE Add-JIMExampleDataTemplateAttribute -TemplateId 7 -ObjectType "User" -MetaverseAttribute "Status" -WeightedValue @{ Value = "active"; Weight = 0.9 }, @{ Value = "suspended"; Weight = 0.1 } Adds weighted-value generation for a Status attribute. .EXAMPLE Add-JIMExampleDataTemplateAttribute -TemplateId 7 -ObjectType "User" -MetaverseAttribute "Employee End Date" -MinDate (Get-Date) -MaxDate (Get-Date).AddYears(2) -PopulatedValuesPercentage 10 -AttributeDependency @{ MetaverseAttribute = "Employee Type"; ComparisonType = "Equals"; StringValue = "Contractor" } -PassThru Adds a date attribute generated for 10% of objects, only where the object's Employee Type is "Contractor". .LINK Get-JIMExampleDataTemplate New-JIMExampleDataTemplate Set-JIMExampleDataTemplate Remove-JIMExampleDataTemplate #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium', DefaultParameterSetName = 'ById')] [OutputType('JIM.ExampleDataTemplateDto')] param( [Parameter(Mandatory, ParameterSetName = 'ById', ValueFromPipelineByPropertyName)] [int]$TemplateId, [Parameter(Mandatory, ParameterSetName = 'ByName')] [ValidateNotNullOrEmpty()] [string]$TemplateName, [Parameter(Mandatory)] [object]$ObjectType, [Parameter()] [object]$MetaverseAttribute, [Parameter()] [string]$Pattern, [Parameter()] [string]$Expression, [Parameter()] [object[]]$ExampleDataSet, [Parameter()] [hashtable[]]$WeightedValue, [Parameter()] [ValidateRange(0, 100)] [int]$PopulatedValuesPercentage, [Parameter()] [ValidateRange(0, 100)] [int]$BoolTrueDistribution, [Parameter()] [datetime]$MinDate, [Parameter()] [datetime]$MaxDate, [Parameter()] [int]$MinNumber, [Parameter()] [int]$MaxNumber, [Parameter()] [bool]$SequentialNumbers, [Parameter()] [bool]$RandomNumbers, [Parameter()] [ValidateRange(0, 100)] [int]$ManagerDepthPercentage, [Parameter()] [int]$MvaRefMinAssignments, [Parameter()] [int]$MvaRefMaxAssignments, [Parameter()] [object[]]$ReferenceMetaverseObjectType, [Parameter()] [hashtable]$AttributeDependency, [ValidateNotNullOrEmpty()] [string]$ChangeReason, [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 } # The target attribute must be named. -MetaverseAttribute is not declared Mandatory so that this check, # rather than an interactive prompt, answers a call that leaves it out. if (-not $PSBoundParameters.ContainsKey('MetaverseAttribute')) { Write-Error "Specify -MetaverseAttribute to say which attribute values are generated for." return } # Resolve name to ID if using ByName parameter set $displayName = if ($PSCmdlet.ParameterSetName -eq 'ByName') { $TemplateName } else { $TemplateId } if ($PSCmdlet.ParameterSetName -eq 'ByName') { try { $resolvedTemplate = Resolve-JIMExampleDataTemplate -Name $TemplateName $TemplateId = $resolvedTemplate.id } catch { Write-Error $_ return } } if ($PSCmdlet.ShouldProcess($displayName, "Add attribute to Data Generation Template")) { Write-Verbose "Adding attribute to Data Generation Template: $TemplateId" try { # Get the existing template with its full Object Type graph $template = Invoke-JIMApi -Endpoint "/api/v1/example-data/templates/$TemplateId" if (-not $template) { Write-Error "Data Generation Template not found: $TemplateId" return } # Locate the Object Type receiving the attribute $existingObjectTypes = @($template.objectTypes) $targetIndex = -1 for ($i = 0; $i -lt $existingObjectTypes.Count; $i++) { $isMatch = if ($ObjectType -is [string]) { [string]$existingObjectTypes[$i].metaverseObjectTypeName -eq $ObjectType } else { [int]$existingObjectTypes[$i].metaverseObjectTypeId -eq [int]$ObjectType } if ($isMatch) { $targetIndex = $i break } } if ($targetIndex -lt 0) { $availableTypes = ($existingObjectTypes | ForEach-Object { "$($_.metaverseObjectTypeName) (id $($_.metaverseObjectTypeId))" }) -join ', ' Write-Error "Object Type '$ObjectType' was not found in Data Generation Template '$($template.name)'. The template's Object Types are: $availableTypes." return } # Convert the whole existing graph from response shape back into request shape (ids only), # passing every existing generation value through verbatim. $objectTypes = @(ConvertTo-JIMExampleDataTemplateRequest -Template $template) # Assemble the new attribute from the flat parameters and reuse the shared converter, # so names resolve to ids identically to New/Set-JIMExampleDataTemplate's hashtable path. $attributeSpec = @{ MetaverseAttribute = $MetaverseAttribute } foreach ($scalarParameter in 'Pattern', 'Expression', 'PopulatedValuesPercentage', 'BoolTrueDistribution', 'MinDate', 'MaxDate', 'MinNumber', 'MaxNumber', 'SequentialNumbers', 'RandomNumbers', 'ManagerDepthPercentage', 'MvaRefMinAssignments', 'MvaRefMaxAssignments') { if ($PSBoundParameters.ContainsKey($scalarParameter)) { $attributeSpec[$scalarParameter] = $PSBoundParameters[$scalarParameter] } } if ($PSBoundParameters.ContainsKey('ExampleDataSet')) { $attributeSpec.ExampleDataSets = $ExampleDataSet } if ($PSBoundParameters.ContainsKey('WeightedValue')) { $attributeSpec.WeightedStringValues = $WeightedValue } if ($PSBoundParameters.ContainsKey('ReferenceMetaverseObjectType')) { $attributeSpec.ReferenceMetaverseObjectTypeIds = @(foreach ($referenceType in $ReferenceMetaverseObjectType) { if ($referenceType -is [string]) { [int](Resolve-JIMMetaverseObjectType -Name $referenceType).id } else { [int]$referenceType } }) } if ($PSBoundParameters.ContainsKey('AttributeDependency')) { $attributeSpec.AttributeDependency = $AttributeDependency } $newAttribute = ConvertTo-JIMExampleDataTemplateAttributeRequest -Attribute $attributeSpec # Append the new attribute to the target Object Type and write the whole graph back. $objectTypes[$targetIndex].attributes = @($objectTypes[$targetIndex].attributes) + $newAttribute $body = @{ objectTypes = $objectTypes } if ($ChangeReason) { $body.changeReason = $ChangeReason } $response = Invoke-JIMApi -Endpoint "/api/v1/example-data/templates/$TemplateId" -Method 'PUT' -Body $body Write-Verbose "Added attribute to Data Generation Template: $TemplateId" # What the save said about the template's expressions without refusing it (#2055 Phase 3): each # written as the server phrased it. foreach ($saveWarning in @($response.Warnings | Where-Object { $_ })) { Write-Warning $saveWarning } if ($PassThru) { $response } } catch { Write-Error "Failed to add attribute to Data Generation Template: $_" } } } } |