Public/Add-HDTStep.ps1
|
function Add-HDTStep { <# .SYNOPSIS Adds a new step to a task sequence document, or pastes a copied one, leaving every other line byte-identical. .DESCRIPTION The Add and Paste buttons, and the cmdlet an administrator can type instead ("the console may not do anything the cmdlets can't"). THIS IS THE ONLY OPERATION THAT INVENTS TEXT, and it therefore has to invent it at the right column. YAML is whitespace-significant, so a step written two columns out is a document the engine refuses - and the administrator's own edit is what broke it. The new lines take the indentation of the step they are placed after, which is also what puts them in that step's group. A PASTED BLOCK IS REINDENTED TO WHERE IT LANDS. Copy from a step inside a group and paste beside one at the top level and the block arrives with its old indentation; the difference between that and a parse error is a couple of spaces. The block's own internal shape is preserved by shifting every line by the same amount. THE TYPE IS CHECKED AGAINST THE ENGINE'S REGISTRY. Get-HDTStepType is what Invoke-HDTTaskSequence would consult, and the authoring lint reports an unknown type as an Error finding - so the editor must not be able to create one in the first place. IT RETURNS LINES AND WRITES NOTHING. Save-HDTSequenceDocument is what touches the share. .PARAMETER Line The document, already split into lines. .PARAMETER After The step or group the new one is placed after. .PARAMETER Name The new step's name. .PARAMETER Type The new step's type. Must be one the engine knows. .PARAMETER Block Lines from Copy-HDTStep, to paste instead of creating a new step. .INPUTS None. This command does not accept pipeline input. .OUTPUTS System.String[] - the document with the step added. .EXAMPLE Add-HDTStep -Line $line -After 'Validate' -Name 'Check TPM' -Type Validate .EXAMPLE $block = Copy-HDTStep -Line $line -Name 'Apply OS' Add-HDTStep -Line $line -After 'Prepare Boot' -Block $block #> [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Low', DefaultParameterSetName = 'New')] [OutputType([string[]])] param( [Parameter(Mandatory = $true, Position = 0)] [AllowEmptyCollection()] [AllowEmptyString()] [string[]] $Line, [Parameter(Mandatory = $true, Position = 1)] [ValidateNotNullOrEmpty()] [string] $After, [Parameter(Mandatory = $true, ParameterSetName = 'New')] [ValidateNotNullOrEmpty()] [string] $Name, [Parameter(Mandatory = $true, ParameterSetName = 'New')] [ValidateNotNullOrEmpty()] [string] $Type, [Parameter(Mandatory = $true, ParameterSetName = 'Paste')] [AllowEmptyString()] [string[]] $Block ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' $target = Resolve-HDTStepBlock -Line $Line -Name $After # A new step sits where its neighbour sits. Placing it after a GROUP puts it # after the whole group, at the group's own indentation, which is where a # sibling of that group belongs. $indent = ' ' * $target.Indent if ($PSCmdlet.ParameterSetName -eq 'New') { $known = @(Get-HDTStepType | ForEach-Object { $_.Type }) if ($known -notcontains $Type) { throw (New-HDTErrorRecord -Path $Type -Category InvalidArgument ` -Message ("'{0}' is not a step type this engine has. Get-HDTStepType lists the {1} it does." -f $Type, @($known).Count)) } $text = @( ('{0}- name: {1}' -f $indent, $Name) ('{0} type: {1}' -f $indent, $Type) ) } else { $text = @(Set-HDTBlockIndent -Block $Block -Indent $target.Indent) } $subject = $Name if ($PSCmdlet.ParameterSetName -eq 'Paste') { $subject = 'the copied step' } if (-not $PSCmdlet.ShouldProcess($subject, ('Add after {0}' -f $After))) { return [string[]] @($Line) } $result = New-Object -TypeName System.Collections.ArrayList for ($i = 0; $i -le $target.End; $i++) { [void] $result.Add($Line[$i]) } # A blank line before it, so the new step is spaced the way the ones around # it are rather than being welded to its neighbour. [void] $result.Add('') foreach ($current in $text) { [void] $result.Add($current) } for ($i = $target.End + 1; $i -lt $Line.Count; $i++) { [void] $result.Add($Line[$i]) } return [string[]] @($result) } |