Public/Get-HDTOperatingSystem.ps1
|
function Get-HDTOperatingSystem { <# .SYNOPSIS Reads an operating system out of the workspace catalog. .DESCRIPTION The read half of the OS catalog. It reads OperatingSystems\<id>\os.yaml through an injected IFileSystem - never Get-Content - so the whole authoring path is provable under Pester with no share, no media and no disk. Four steps, and a failure at any of them is a terminating HDTConfigurationError naming the file: 1. read through IFileSystem; 2. parse with ConvertFrom-HDTYaml, which turns a parser exception into an error naming the file and the LINE; 3. validate with Assert-HDTOperatingSystemDocument, which names the file and the offending key; 4. project, resolving ImagePath. ImagePath IS THE SEAM 04-02 MARKED AND 05-02 CLOSED. HDT abstracts content access behind a provider, and -Content is where one arrives: given one, ImagePath is what the provider answered; given none, it is resolved from the workspace root exactly as before, which is what an administrator importing on a workstation gets. ApplyImage changed from "ask the catalog" to "ask the provider" by passing $Context.Service.Content, and NO STEP LOGIC MOVED - asserted by running the same step through the Local and the Smb providers and comparing the ordered list of every service call (tests/unit/Invoke-HDTApplyImageStep.Tests.ps1). A rooted sourcePath is kept as it is, provider or no provider, because media too large to bring into the share is registered where it stands. .PARAMETER WorkspaceRoot The workspace root - a local path or a UNC share. .PARAMETER Id The catalog id, which is the folder name under OperatingSystems\. .PARAMETER FileSystem An IFileSystem - the real adapter in production, New-HDTFakeFileSystem in a test. .PARAMETER Content An IContentProvider, or nothing. When supplied, ImagePath is what it answered for the relative sourcePath; a refusal is reported as a configuration error naming os.yaml, because a sourcePath that climbs out of the workspace is a mistake in that file. .INPUTS None. This command does not accept pipeline input. .OUTPUTS System.Management.Automation.PSCustomObject: SchemaVersion, Id, Name, Description, Type, Architecture, SourcePath, ImportedUtc, DefaultIndex, Path, OsFolder, ImagePath and Images - one row per index carrying Index, Name, Description, Edition, SizeBytes and Version. .EXAMPLE Get-HDTOperatingSystem -WorkspaceRoot 'X:\Deploy' -Id 'Win11-LTSC-2024' -FileSystem (New-HDTFileSystem) .EXAMPLE $os = Get-HDTOperatingSystem -WorkspaceRoot $root -Id $id -FileSystem $fs Resolve-HDTImageIndex -Image $os.Images -Edition EnterpriseS The catalog and the index resolver, which is how ApplyImage will use both. #> [CmdletBinding()] [OutputType([pscustomobject])] param( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $WorkspaceRoot, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string] $Id, [Parameter(Mandatory = $true)] [ValidateNotNull()] [object] $FileSystem, [Parameter()] [AllowNull()] [object] $Content = $null ) Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' $osFolder = Get-HDTWorkspacePath -Root $WorkspaceRoot -Kind OperatingSystems -ChildPath $Id $catalogPath = Get-HDTWorkspacePath -Root $WorkspaceRoot -Kind OperatingSystems -ChildPath $Id, 'os.yaml' if (-not $FileSystem.TestPath($catalogPath)) { $PSCmdlet.ThrowTerminatingError((New-HDTErrorRecord -Path $catalogPath ` -Message ("no operating system with the id '{0}' is in this workspace. Import one with Import-HDTOperatingSystem." -f $Id) ` -Category ObjectNotFound)) } $text = $FileSystem.ReadAllText($catalogPath) $document = ConvertFrom-HDTYaml -Yaml $text -Path $catalogPath Assert-HDTOperatingSystemDocument -Document $document -Path $catalogPath try { return (ConvertTo-HDTOperatingSystemCatalog -Document $document -OsFolder $osFolder ` -CatalogPath $catalogPath -Content $Content) } catch { # A provider refusal - a sourcePath that escapes the content root - is a # mistake in os.yaml, so it is reported naming os.yaml rather than # surfacing as a MethodInvocationException from a ScriptMethod three # frames down. $PSCmdlet.ThrowTerminatingError((New-HDTErrorRecord -Path $catalogPath ` -Message ("the image path could not be resolved: {0}" -f [string] $_.Exception.Message))) } } |