Private/Invoke-OSDAppUIStage.ps1
|
function Get-OSDAppUIStagedApps { [CmdletBinding()] param([Parameter(Mandatory)][string]$WindowsPath) $manifestPath = Join-Path $WindowsPath 'Windows\Temp\OSDApps\DeviceManifest.json' if (-not (Test-Path -LiteralPath $manifestPath -PathType Leaf)) { return } $manifest = Get-Content -LiteralPath $manifestPath -Raw -Encoding UTF8 | ConvertFrom-Json -ErrorAction Stop if ($null -eq $manifest -or -not ($manifest.PSObject.Properties.Name -contains 'Apps')) { throw "Invalid DeviceManifest.json: Apps property is missing: $manifestPath" } foreach ($app in @($manifest.Apps)) { if ($null -ne $app -and -not [string]::IsNullOrWhiteSpace([string]$app.Id)) { $app } } } function Get-OSDAppUIStagedIds { [CmdletBinding()] param([Parameter(Mandatory)][string]$WindowsPath) foreach ($app in @(Get-OSDAppUIStagedApps -WindowsPath $WindowsPath)) { [string]$app.Id } } function Get-OSDAppUITestWindowsPath { [CmdletBinding()] param() if ([string]::IsNullOrWhiteSpace($env:TEMP)) { throw 'TEMP is unavailable.' } [System.IO.Path]::GetFullPath((Join-Path $env:TEMP 'OSDApps-GUI-Staging-Test')) } function Format-OSDAppUIStagedDetails { [CmdletBinding()] param( [Parameter(Mandatory)]$Application, [string]$Vendor ) $lines = [System.Collections.Generic.List[string]]::new() if ($Vendor -and $Vendor -ne '-') { $lines.Add("Vendor: $Vendor") } # Whitelist descriptive manifest fields; do not display arbitrary scripts, # custom arguments, installer command lines or authenticated download URLs. foreach ($key in @( 'DisplayName','Id','Source','Type','Version','Architecture','Channel', 'Language','ProductId','SharedComputerLicensing','DeviceBasedLicensing', 'UpdatesEnabled','InstallMeetingAddin','IncludeVisio','IncludeProject', 'ExcludeApp','AutoStartWithWindows','PreventPreLoginUpdates', 'EnableOutlookIntegration','DefaultTheme','InstallTimeoutMinutes' )) { $property = $Application.PSObject.Properties[$key] if ($null -eq $property -or $null -eq $property.Value) { continue } $value = if ($property.Value -is [array]) { @($property.Value) -join ', ' } else { [string]$property.Value } if (-not [string]::IsNullOrWhiteSpace($value)) { $lines.Add(('{0}: {1}' -f $key,$value)) } } $lines.Add('') $lines.Add('Staged for SetupComplete. This does not confirm the application was installed.') $lines -join [Environment]::NewLine } function Get-OSDAppUIReadOnlySnapshot { [CmdletBinding()] param( [string]$WindowsPath, [switch]$Offline, [switch]$SkipSignatureVerification ) # Only reads files, disk metadata and (optionally) catalog contents. # No SetupComplete, DeviceManifest, cache, or configuration mutations. $staged = @() $manifestPath = $null $setupCompletePath = $null if ($WindowsPath) { $manifestPath = Join-Path $WindowsPath 'Windows\Temp\OSDApps\DeviceManifest.json' $setupCompletePath = Join-Path $WindowsPath 'Windows\Setup\Scripts\SetupComplete.cmd' $staged = @(Get-OSDAppUIStagedApps -WindowsPath $WindowsPath) } $catalog = @(Get-OSDApp -Offline:$Offline -ErrorAction Stop) # On full Windows inspect any legacy built-in cache with Version=Current # without writing metadata or downloading anything. WinPE uses CacheInfo.json. $fullWindows = -not (Test-OSDAppWinPE) $cache = @(Get-OSDAppCache -ResolveVersions:$fullWindows -VerifySignatures:(-not $SkipSignatureVerification) -ErrorAction Stop) $cachePath = $null try { $cachePath = Get-OSDAppCachePath } catch { } $logFiles = [System.Collections.Generic.List[object]]::new() if ($cachePath) { foreach ($name in @('Client.log','Runtime.log')) { $file = Join-Path $cachePath (Join-Path 'Logs' $name) if (Test-Path -LiteralPath $file -PathType Leaf) { $logFiles.Add([pscustomobject]@{ Label="USB cache: $name"; Path=$file }) } } } if ($WindowsPath) { foreach ($definition in @( @{ Label='Device: Runtime.log'; Relative='ProgramData\OSDApps\Logs\Runtime.log' }, @{ Label='Device: Client.log'; Relative='ProgramData\OSDApps\Logs\Client.log' } )) { $file = Join-Path $WindowsPath $definition.Relative if (Test-Path -LiteralPath $file -PathType Leaf) { $logFiles.Add([pscustomobject]@{ Label=$definition.Label; Path=$file }) } } } [pscustomobject]@{ WindowsPath = $WindowsPath ManifestPath = $manifestPath ManifestExists = [bool]($manifestPath -and (Test-Path -LiteralPath $manifestPath -PathType Leaf)) SetupCompleteExists = [bool]($setupCompletePath -and (Test-Path -LiteralPath $setupCompletePath -PathType Leaf)) StagedApps = @($staged) CatalogApps = @($catalog) CacheEntries = @($cache) CachePath = $cachePath Logs = @($logFiles) } } |