Public/Set-HDTStepCondition.ps1
|
function Set-HDTStepCondition { <# .SYNOPSIS Gives a step the expression that decides whether it runs, or takes it away. .DESCRIPTION THE FILTER MDT PUTS ON THE OPTIONS TAB. Workbench lists conditions under the two checkboxes and a step with none runs every time; HDT carries the same idea as one expression on the step's `condition` key, evaluated by the engine before the step is invoked. This is that control, as a command: every button maps to a cmdlet invocation, and the console shows the invocation. ONE EXPRESSION, NOT A CLAUSE BUILDER. MDT's dialog composes an if-statement tree out of variable tests, WMI queries and registry reads, and stores it as XML nobody can read in a diff. HDT's condition is a PowerShell expression over the rules' variables, which is the same power in a form an administrator can also grep, and which `rules.yaml` already gave them the vocabulary for. CLEARING IT REMOVES THE LINE RATHER THAN EMPTYING IT. `condition:` with nothing after it is a key whose value is null, which reads at a glance like a condition somebody forgot to finish. A step that runs every time should say so by carrying no condition at all, the way a newly added step does. IT SPLICES, LIKE EVERY EDIT HERE, and it quotes only when leaving the expression bare would change what the engine reads back - a colon-space inside it would otherwise turn one key into two. .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 Condition The expression. Empty removes the condition. .INPUTS None. This command does not accept pipeline input. .OUTPUTS System.String[] - the document, with one line changed. .EXAMPLE Set-HDTStepCondition -Line $line -Name 'Apply Drivers' -Condition '$Make -eq "Dell Inc."' .EXAMPLE Set-HDTStepCondition -Line $line -Name 'Apply Drivers' -Condition '' Takes the condition off, so the step runs every time. #> [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)] [AllowEmptyString()] [string] $Condition ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' $target = Resolve-HDTStepBlock -Line $Line -Name $Name $found = Get-HDTStepKey -Line $Line -Block $target -Key 'condition' $clear = [string]::IsNullOrWhiteSpace($Condition) # Nothing to remove and nothing to write. if ($clear -and $found.Index -lt 0) { return [string[]] @($Line) } $action = "Set the condition to {0}" -f $Condition if ($clear) { $action = 'Remove the condition' } if (-not $PSCmdlet.ShouldProcess($Name, $action)) { return [string[]] @($Line) } # Bare wherever bare reads back the same, quoted where it would not - see # Get-HDTConsoleScalarText, which Set-HDTStepProperty shares. $written = '{0}condition: {1}' -f (' ' * $found.Indent), (Get-HDTConsoleScalarText -Value $Condition) $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) { # Cleared: the line goes, and the keys around it close up. 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) } |