Private/Test-HDTSequenceNamesApplication.ps1
|
function Test-HDTSequenceNamesApplication { <# .SYNOPSIS Whether a task sequence document installs a given application. .DESCRIPTION WHAT Remove-HDTApplication HAS TO KNOW before it deletes anything, and it is not a text search. An id that appears in a comment, in a step's name or in a command line is not this sequence installing it: it is the selection of an InstallApplications step, and nothing else. IT WALKS THE TREE, because a sequence of any size is one - the sample sequence in this repository has six groups, and a scan of the top level would miss nearly every step in the share. A SELECTION THAT IS A VARIABLE IS NOT A MATCH. `selection: '%HDTApplications%'` is resolved from the rules at run time, so what it will install cannot be read from the document. Answering yes for those would name every such sequence for every application, which makes the report useless; answering no is what the document says. .PARAMETER Document The parsed sequence, as ConvertFrom-HDTYaml returns it. .PARAMETER Id The application's id. .INPUTS None. This command does not accept pipeline input. .OUTPUTS System.Boolean .EXAMPLE Test-HDTSequenceNamesApplication -Document $parsed -Id '7Zip-24.09' #> [CmdletBinding()] [OutputType([bool])] param( [Parameter(Mandatory = $true, Position = 0)] [AllowNull()] [object] $Document, [Parameter(Mandatory = $true, Position = 1)] [ValidateNotNullOrEmpty()] [string] $Id ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' if ($null -eq $Document -or -not ($Document -is [System.Collections.IDictionary])) { return $false } $wanted = $Id.Trim() $names = { param($Step) foreach ($current in @($Step)) { if ($null -eq $current -or -not ($current -is [System.Collections.IDictionary])) { continue } # A GROUP HOLDS STEPS, and its own type is not InstallApplications - # so the walk happens whatever this step turns out to be. if ($current.Contains('steps')) { if (& $names $current['steps']) { return $true } } $type = '' if ($current.Contains('type')) { $type = [string] $current['type'] } if ($type -ne 'InstallApplications') { continue } if (-not $current.Contains('selection')) { continue } $selection = $current['selection'] $part = @() if ($selection -is [string]) { # ONE STRING IS A LIST WRITTEN THE OTHER WAY, which is how the # step's own reader treats it - and a variable in it is not # something this can resolve. if ([string] $selection -match '%') { continue } $part = @(([string] $selection) -split ',') } else { $part = @(@($selection) | ForEach-Object { [string] $_ }) } foreach ($one in @($part)) { if ([string]::Equals(([string] $one).Trim(), $wanted, [System.StringComparison]::OrdinalIgnoreCase)) { return $true } } } return $false } if (-not $Document.Contains('steps')) { return $false } return [bool] (& $names $Document['steps']) } |