private/core-operatingsystem/Set-OSDCoreOperatingSystemCloudObject.ps1
|
function Set-OSDCoreOperatingSystemCloudObject { <# .SYNOPSIS Selects and sets the global OSD core operating system object. .DESCRIPTION Filters the preloaded operating system catalog using activation, architecture, language, release ID, and version criteria, then sets $global:OSDCoreOperatingSystemCloudObject to the best match. If multiple matches are found, the highest build is selected. .PARAMETER OSActivation Operating system activation channel used for catalog selection. .PARAMETER OSArchitecture Operating system architecture used for catalog selection. .PARAMETER OSLanguageCode Operating system language code used for catalog selection. .PARAMETER OSReleaseID Operating system release identifier used for catalog selection. .PARAMETER OSVersion Operating system family/version label used for catalog selection. .PARAMETER RefreshCatalog Reloads $global:OSDCoreOperatingSystems from the current module's operating system catalog provider before filtering. .EXAMPLE Set-OSDCoreOperatingSystemCloudObject -OSArchitecture amd64 -OSReleaseID 25H2 -OSLanguageCode en-us Selects the latest Windows 11 Retail amd64 en-us 25H2 catalog entry and sets $global:OSDCoreOperatingSystemCloudObject. .EXAMPLE Set-OSDCoreOperatingSystemCloudObject -OSActivation Volume -OSArchitecture arm64 -OSLanguageCode en-us -OSReleaseID 24H2 -RefreshCatalog Refreshes the catalog cache and selects the latest matching Volume arm64 record. .INPUTS None You cannot pipe input to this function. .OUTPUTS PSCustomObject The selected operating system object assigned to $global:OSDCoreOperatingSystemCloudObject. .LINK https://github.com/OSDeploy/OSD/tree/master/docs .NOTES Author: David Segura - Recast Software 2026-07-15 - Initial implementation to centralize OS catalog object selection. 2026-08-05 - Expanded help content and examples #> [CmdletBinding()] [OutputType([pscustomobject])] param ( [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [ValidateSet('Retail', 'Volume')] [string]$OSActivation = 'Retail', [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [ValidateSet('amd64', 'arm64', 'x64')] [string]$OSArchitecture = $env:PROCESSOR_ARCHITECTURE, [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [string]$OSLanguageCode = 'en-us', [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [string]$OSReleaseID = '25H2', [Parameter(Mandatory = $false)] [ValidateNotNullOrEmpty()] [string]$OSVersion = 'Windows 11', [Parameter(Mandatory = $false)] [switch]$RefreshCatalog ) <# OSD PowerShell Module PS C:\Users\david> $OSDCoreOperatingSystemCloudObject Status : ReleaseDate : Name : Windows 11 25H2 amd64 en-us Retail 26200.8873 Version : Windows 11 ReleaseID : 25H2 Architecture : amd64 Language : en-us Activation : Retail Build : 26200.8873 FileName : 26200.8873.260710-2020.25h2_ge_release_svc_refresh_CLIENTCONSUMER_RET_x64FRE_en-us.esd ImageIndex : ImageName : Url : http://dl.delivery.mp.microsoft.com/filestreamingservice/files/0f68e999-6e25-4ae7-92db-23cbb3a723a9/26200.8873.260710-2020.25h2_ge_release_svc_refresh_CLIENTCONSUMER_RET_x64FRE_en-us.esd SHA1 : SHA256 : e4c251a99eeade29aa5d462047bcb257d640cd2c98dfb7a2305f45876d1790c1 UpdateID : Win10 : False Win11 : True #> <# OSDCloud PowerShell Module PS C:\Users\david> $OSDCoreOperatingSystemCloudObject Id : Windows 11 25H2 amd64 Retail en-us 26200.8873 OperatingSystem : Windows 11 25H2 OSName : Windows 11 OSVersion : 25H2 OSArchitecture : amd64 OSActivation : Retail OSLanguageCode : en-us OSLanguage : English (United States) OSBuild : 26200 OSBuildVersion : 26200.8873 Size : 6050059595 Sha1 : Sha256 : e4c251a99eeade29aa5d462047bcb257d640cd2c98dfb7a2305f45876d1790c1 FileName : 26200.8873.260710-2020.25h2_ge_release_svc_refresh_CLIENTCONSUMER_RET_x64FRE_en-us.esd FilePath : http://dl.delivery.mp.microsoft.com/filestreamingservice/files/0f68e999-6e25-4ae7-92db-23cbb3a723a9/26200.8873.260710-2020.25h2_ge_release_svc_refresh_CLIENTCONSUMER_RET_x64FRE_en-us.esd #> $Error.Clear() $ModuleName = $($MyInvocation.MyCommand.Module.Name) Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Starting operating system cloud object selection" Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Input filters: Activation='$OSActivation', Architecture='$OSArchitecture', Language='$OSLanguageCode', ReleaseID='$OSReleaseID', Version='$OSVersion', RefreshCatalog='$($RefreshCatalog.IsPresent)'" $normalizedArchitecture = switch ($OSArchitecture.ToLowerInvariant()) { 'amd64' { 'amd64' } 'x64' { 'amd64' } 'arm64' { 'arm64' } } $normalizedLanguageCode = $OSLanguageCode.ToLowerInvariant() Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Normalized filters: Architecture='$normalizedArchitecture', Language='$normalizedLanguageCode'" $catalogProvider = $null $catalogShape = $null if ($ModuleName -eq 'OSD') { $catalogProvider = 'Get-OSDCoreOperatingSystems' $catalogShape = 'OSD' } elseif ($ModuleName -eq 'OSDCloud') { $catalogProvider = 'Get-OSDCloudCoreOperatingSystems' $catalogShape = 'OSDCloud' } elseif (Get-Command -Name 'Get-OSDCloudCoreOperatingSystems' -ErrorAction Ignore) { $catalogProvider = 'Get-OSDCloudCoreOperatingSystems' $catalogShape = 'OSDCloud' } elseif (Get-Command -Name 'Get-OSDCoreOperatingSystems' -ErrorAction Ignore) { $catalogProvider = 'Get-OSDCoreOperatingSystems' $catalogShape = 'OSD' } else { throw "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Unable to load core operating systems provider command." } Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Using operating systems provider '$catalogProvider' for '$catalogShape' object shape" $existingCatalogShape = $null if ($global:OSDCoreOperatingSystems) { $firstCachedOperatingSystem = @($global:OSDCoreOperatingSystems | Select-Object -First 1)[0] if ($firstCachedOperatingSystem.PSObject.Properties.Name -contains 'OSArchitecture') { $existingCatalogShape = 'OSDCloud' } elseif ($firstCachedOperatingSystem.PSObject.Properties.Name -contains 'Architecture') { $existingCatalogShape = 'OSD' } } $refreshOperatingSystems = $RefreshCatalog -or -not $global:OSDCoreOperatingSystems -or (($existingCatalogShape) -and ($existingCatalogShape -ne $catalogShape)) if ($refreshOperatingSystems) { Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Refreshing cached operating systems from $catalogProvider" $global:OSDCoreOperatingSystems = & $catalogProvider | Where-Object { ($_.Architecture -eq $normalizedArchitecture) -or ($_.OSArchitecture -eq $normalizedArchitecture) } Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Cached operating systems after architecture prefilter: $(@($global:OSDCoreOperatingSystems).Count)" } else { Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Using existing cached operating systems: $(@($global:OSDCoreOperatingSystems).Count)" } if (-not $global:OSDCoreOperatingSystems) { Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] No operating systems are available after loading cache" throw "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Unable to load Operating Systems" } Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Applying catalog filters to cached operating systems" $filteredOperatingSystems = $global:OSDCoreOperatingSystems | Where-Object { ($_.Activation -eq $OSActivation) -or ($_.OSActivation -eq $OSActivation) } | Where-Object { ($_.Architecture -eq $normalizedArchitecture) -or ($_.OSArchitecture -eq $normalizedArchitecture) } | Where-Object { ($_.Language -eq $normalizedLanguageCode) -or ($_.OSLanguageCode -eq $normalizedLanguageCode) } | Where-Object { ($_.ReleaseID -eq $OSReleaseID) -or ($_.OSVersion -eq $OSReleaseID) } | Where-Object { ($_.Version -eq $OSVersion) -or ($_.OSName -eq $OSVersion) } Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Matching operating systems found: $(@($filteredOperatingSystems).Count)" $global:OSDCoreOperatingSystemCloudObject = $filteredOperatingSystems | Sort-Object -Property @{ Expression = { try { $buildVersion = if ($_.Build) { $_.Build } else { $_.OSBuildVersion } [version]([string]$buildVersion -replace '[^0-9\.]', '') } catch { [version]'0.0' } }; Descending = $true } | Select-Object -First 1 if (-not $global:OSDCoreOperatingSystemCloudObject) { Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] No matching operating system object was selected after sorting" throw "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Unable to find a matching operating system object for OSReleaseID '$OSReleaseID', OSArchitecture '$normalizedArchitecture', Activation '$OSActivation', Language '$normalizedLanguageCode', and OSVersion '$OSVersion'." } $selectedOperatingSystemName = if ($global:OSDCoreOperatingSystemCloudObject.Id) { $global:OSDCoreOperatingSystemCloudObject.Id } else { $global:OSDCoreOperatingSystemCloudObject.Name } $selectedOperatingSystemBuild = if ($global:OSDCoreOperatingSystemCloudObject.OSBuildVersion) { $global:OSDCoreOperatingSystemCloudObject.OSBuildVersion } else { $global:OSDCoreOperatingSystemCloudObject.Build } Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Selected operating system object: Name='$selectedOperatingSystemName', Build='$selectedOperatingSystemBuild', FileName='$($global:OSDCoreOperatingSystemCloudObject.FileName)'" Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Operating system cloud object selection completed successfully" $global:OSDCoreOperatingSystemCloudObject | Export-Clixml -Path (Join-Path -Path $env:TEMP -ChildPath 'OSDCoreOperatingSystemCloudObject.xml') -Force return $global:OSDCoreOperatingSystemCloudObject } |