Public/Set-HDTStepProperty.ps1
|
function Set-HDTStepProperty { <# .SYNOPSIS Changes one property of a step or group - what it does, rather than whether it does it. .DESCRIPTION THE PROPERTIES TAB'S CMDLET. Options carries the three keys that decide whether a step runs; this carries the rest - the index ApplyImage installs, the minRamMB Validate insists on, the name on the row. The console may not do anything the cmdlets can't, and it shows the invocation for what it does. IT SPLICES, and it is the same three-way splice as the flags: rewrite the line if the key is there, insert one under `type:` if it is not, remove it if the value is cleared. Get-HDTStepKey finds all three cases, and stops at a group's `steps:` so setting a property on 'Install' cannot rewrite a line belonging to the first step inside it. THE NAME IS A PROPERTY LIKE ANY OTHER, and it lives on the entry line - `- name: Apply OS`. The dash is part of the list, not part of the key, so a rename rewrites what follows it and leaves the indentation and the marker alone. A NAME CANNOT BE CLEARED. Every editing cmdlet here resolves its target by name; a step with none could not be found again, by this console or by an administrator reading the file. Removing a step is Remove-HDTStep, where it is what was asked for. THE TYPE CANNOT BE CHANGED AT ALL. A step's properties belong to its type - `index` means something to ApplyImage and nothing to Restart - so retyping one leaves a step carrying keys the new type has never heard of, which the engine will either ignore silently or refuse at the worst moment. Workbench does not offer it either. The answer there and here is to delete the step and add the one you meant. .PARAMETER Line The document, already split into lines. .PARAMETER Name The step or group to change. Ambiguous names are refused rather than guessed - see Resolve-HDTStepBlock. .PARAMETER Property The YAML key, exactly as it is written in the file. .PARAMETER Value What it becomes. Empty removes the key. .INPUTS None. This command does not accept pipeline input. .OUTPUTS System.String[] - the document, with one line changed. .EXAMPLE Set-HDTStepProperty -Line $line -Name 'Apply OS' -Property 'index' -Value '2' .EXAMPLE Set-HDTStepProperty -Line $line -Name 'Apply OS' -Property 'name' -Value 'Apply Windows 11' Renames the step, on its own entry line. #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Low')] [OutputType([string[]])] param( [Parameter(Mandatory = $true, Position = 0)] [AllowEmptyCollection()] [AllowEmptyString()] [string[]] $Line, [Parameter(Mandatory = $true, Position = 1)] [ValidateNotNullOrEmpty()] [string] $Name, [Parameter(Mandatory = $true, Position = 2)] [ValidateNotNullOrEmpty()] [string] $Property, [Parameter(Mandatory = $true, Position = 3)] [AllowEmptyString()] [string] $Value ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' if ($Property -eq 'type') { $PSCmdlet.ThrowTerminatingError((New-HDTErrorRecord -Path $Name -Category InvalidOperation ` -Message ("a step's type cannot be changed, because its properties belong to that type and would be left behind. Remove '{0}' and add the step you meant." -f $Name))) } $naming = @('name', 'group') $clear = [string]::IsNullOrWhiteSpace($Value) if ($clear -and $naming -contains $Property) { $PSCmdlet.ThrowTerminatingError((New-HDTErrorRecord -Path $Name -Category InvalidArgument ` -Message ("a step's name cannot be cleared - every edit here finds its target by name, and one with none could not be found again. Use Remove-HDTStep to delete it."))) } $target = Resolve-HDTStepBlock -Line $Line -Name $Name $found = Get-HDTStepKey -Line $Line -Block $target -Key $Property if ($clear -and $found.Index -lt 0) { return [string[]] @($Line) } $action = "Set {0} to {1}" -f $Property, $Value if ($clear) { $action = 'Remove {0}' -f $Property } if (-not $PSCmdlet.ShouldProcess($Name, $action)) { return [string[]] @($Line) } $written = '{0}{1}: {2}' -f (' ' * $found.Indent), $Property, (Get-HDTConsoleScalarText -Value $Value) # THE ENTRY LINE KEEPS ITS DASH. `- name: X` is a list item whose first key # happens to be the name; rewriting it as a plain key would fold the step # into the one above it. if ($found.Index -eq [int] $target.Entry) { $written = '{0}- {1}: {2}' -f (' ' * [int] $target.Indent), $Property, (Get-HDTConsoleScalarText -Value $Value) } $result = New-Object -TypeName System.Collections.ArrayList for ($i = 0; $i -lt $Line.Count; $i++) { if ($found.Index -ge 0 -and $i -eq $found.Index) { if (-not $clear) { [void] $result.Add($written) } continue } [void] $result.Add($Line[$i]) if ($found.Index -lt 0 -and $i -eq $found.Insert) { [void] $result.Add($written) } } return [string[]] @($result) } |