private/Step-BuildBootSetEnvironmentVariables.ps1
|
#Requires -PSEdition Core function Step-BuildBootSetEnvironmentVariables { <# .SYNOPSIS Sets configured and identity environment variables in the mounted WinPE image .DESCRIPTION Builds an environment-variable table from global OSDeployModule.BootImage.env, the installed OSDeploy module version, generated OSDeploy identifiers, and available license email and license GUID values. The device UUID is SHA-256 hashed for ID_OSDEPLOYDEVICE; a generated GUID is used when the hash is empty. A new ID_OSDEPLOYBOOT is generated on every invocation. The function loads the mounted SYSTEM hive, creates the environment registry key when needed, writes each value as REG_SZ, appends X:\Program Files\WindowsPowerShell\Scripts to the system Path as REG_EXPAND_SZ, and unloads the hive in a finally block. A missing SYSTEM hive produces a warning. Terminating errors are reported as warnings so they do not abort the calling build. .EXAMPLE PS> Step-BuildBootSetEnvironmentVariables Writes configured, version, device, and available license values into WinPE. .INPUTS None. This function does not accept pipeline input. .OUTPUTS None. .NOTES Author: David Segura Company: Recast Software Version: 0.1.0 Date: 2026-08-28 Requires global BuildMedia.MountPath, global OSDeployModule.BootImage.env, Get-OSDeployModuleVersion, Get-CimInstance, reg.exe, and access to load the mounted SYSTEM hive. Reads OSDCoreLicense from the caller's scope when present and modifies the mounted environment registry key, including the system Path. #> [CmdletBinding()] param () try { $MountPath = $global:BuildMedia.MountPath # Build the env var table: static entries from module.json + dynamic OSDEPLOY_VERSION $envVars = [ordered]@{} $envConfig = $global:OSDeployModule.BootImage.env if ($envConfig) { foreach ($prop in $envConfig.PSObject.Properties) { $envVars[$prop.Name] = $prop.Value } } $moduleVersion = Get-OSDeployModuleVersion if ($moduleVersion) { $envVars['OSDEPLOY_VERSION'] = $moduleVersion.ToString() } # Unique identifier for this device, used for telemetry and license enforcement $deviceUUID = $null try { $deviceUUID = (Get-CimInstance -ClassName Win32_ComputerSystemProduct -ErrorAction Stop).UUID } catch { Write-Verbose "[$($MyInvocation.MyCommand.Name)] Could not query system UUID. Falling back to build GUID." } [string]$distinctId = $null # Convert the UUID to a hash value to protect user privacy and ensure a consistent identifier across events if (-not [string]::IsNullOrWhiteSpace($deviceUUID)) { $sha256 = [System.Security.Cryptography.SHA256]::Create() try { $distinctId = [System.BitConverter]::ToString( $sha256.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($deviceUUID)) ).Replace("-", "") } finally { $sha256.Dispose() } } if ([string]::IsNullOrWhiteSpace($distinctId)) { $distinctId = [System.Guid]::NewGuid().ToString() } $envVars['ID_OSDEPLOYDEVICE'] = $distinctId $envVars['ID_OSDEPLOYBOOT'] = $global:BuildMedia.BootGuid if ($OSDCoreLicense -and $OSDCoreLicense.License -and $OSDCoreLicense.License.Email) { $envVars['ID_REGISTEREDEMAIL'] = $OSDCoreLicense.License.Email } if ($OSDCoreLicense -and $OSDCoreLicense.License -and $OSDCoreLicense.License.LicenseGuid) { $envVars['ID_REGISTEREDLICENSE'] = $OSDCoreLicense.License.LicenseGuid } if ($envVars.Count -eq 0) { Write-HostDateTimeDarkGray 'No environment variables to set in WinPE — skipping' return } Write-HostDateTimeDarkGray 'Setting environment variables in WinPE SYSTEM hive' $systemHivePath = Join-Path $MountPath 'Windows\System32\Config\SYSTEM' if (-not (Test-Path $systemHivePath)) { Write-Warning "[$($MyInvocation.MyCommand.Name)] SYSTEM hive not found at $systemHivePath" return } #================================================= # Add Windows PowerShell scripts to the WinPE PATH $RegistryHiveLoaded = $false try { & reg.exe LOAD HKLM\Mount "$MountPath\Windows\System32\Config\SYSTEM" Start-Sleep -Seconds 3 if ($LASTEXITCODE -ne 0) { Write-Warning "Failed to load SYSTEM hive from $systemHivePath (exit code $LASTEXITCODE)." -WarningAction Continue } $RegistryHiveLoaded = $true $RegistryKey = 'HKLM:\Mount\ControlSet001\Control\Session Manager\Environment' $CurrentPath = (Get-Item -path $RegistryKey).GetValue('Path', '', 'DoNotExpandEnvironmentNames') $NewPath = $CurrentPath + ';X:\Program Files\WindowsPowerShell\Scripts' $Result = New-ItemProperty -Path $RegistryKey -Name 'Path' -PropertyType ExpandString -Value $NewPath -Force } finally { if ($RegistryHiveLoaded) { Get-Variable Result -ErrorAction SilentlyContinue | Remove-Variable -ErrorAction SilentlyContinue Get-Variable RegistryKey -ErrorAction SilentlyContinue | Remove-Variable -ErrorAction SilentlyContinue [gc]::Collect() Start-Sleep -Seconds 3 & reg.exe UNLOAD HKLM\Mount if ($LASTEXITCODE -ne 0) { Write-Warning "Failed to unload SYSTEM hive from HKLM\Mount (exit code $LASTEXITCODE)." -WarningAction Continue } } } } catch { Write-Warning "[$($MyInvocation.MyCommand.Name)] $($_.Exception.Message)" -WarningAction Continue } } |