mirror of
https://github.com/rbalsleyMSFT/FFU.git
synced 2026-06-13 18:07:20 -06:00
Consolidate WinGet version detection
Add a shared WinGet component status helper that uses Get-WinGetVersion through Microsoft.WinGet.Client, and route both the CLI and UI status checks through it. This removes the UI-only winget.exe --version parsing path and adds clearer logging for missing modules, missing cmdlets, parse failures, and caught WinGet version errors.
This commit is contained in:
@@ -1023,6 +1023,94 @@ function Install-WinGet {
|
|||||||
}
|
}
|
||||||
WriteLog "WinGet installation complete."
|
WriteLog "WinGet installation complete."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Get-WinGetComponentStatus {
|
||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[Parameter(Mandatory = $false)]
|
||||||
|
[version]$MinimumVersion = [version]"1.8.1911"
|
||||||
|
)
|
||||||
|
|
||||||
|
$moduleName = 'Microsoft.WinGet.Client'
|
||||||
|
$status = [PSCustomObject]@{
|
||||||
|
Success = $false
|
||||||
|
NeedsUpdate = $true
|
||||||
|
WinGetInstalled = $false
|
||||||
|
WinGetNeedsUpdate = $true
|
||||||
|
WinGetVersion = "Unknown"
|
||||||
|
WinGetVersionObject = $null
|
||||||
|
WinGetStatus = "Unknown"
|
||||||
|
ModuleInstalled = $false
|
||||||
|
ModuleNeedsUpdate = $true
|
||||||
|
ModuleVersion = "Not installed"
|
||||||
|
ModuleVersionObject = $null
|
||||||
|
CmdletAvailable = $false
|
||||||
|
ErrorMessage = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$installedModule = @(Get-InstalledModule -Name $moduleName -ErrorAction SilentlyContinue) | Sort-Object -Property Version -Descending | Select-Object -First 1
|
||||||
|
$availableModule = @(Get-Module -ListAvailable -Name $moduleName -ErrorAction SilentlyContinue) | Sort-Object -Property Version -Descending | Select-Object -First 1
|
||||||
|
$wingetModule = if ($null -ne $installedModule) { $installedModule } else { $availableModule }
|
||||||
|
|
||||||
|
if ($null -eq $wingetModule) {
|
||||||
|
$status.WinGetStatus = "$moduleName module is not installed."
|
||||||
|
WriteLog $status.WinGetStatus
|
||||||
|
return $status
|
||||||
|
}
|
||||||
|
|
||||||
|
$status.ModuleInstalled = $true
|
||||||
|
$status.ModuleVersion = $wingetModule.Version.ToString()
|
||||||
|
$status.ModuleVersionObject = [version]$wingetModule.Version
|
||||||
|
$status.ModuleNeedsUpdate = $status.ModuleVersionObject -lt $MinimumVersion
|
||||||
|
WriteLog "$moduleName module version detected: $($status.ModuleVersion)"
|
||||||
|
|
||||||
|
Import-Module -Name $moduleName -Force -ErrorAction Stop
|
||||||
|
$wingetVersionCommand = Get-Command -Name Get-WinGetVersion -ErrorAction SilentlyContinue
|
||||||
|
if ($null -eq $wingetVersionCommand) {
|
||||||
|
$status.WinGetStatus = "Get-WinGetVersion cmdlet is not available."
|
||||||
|
$status.ErrorMessage = $status.WinGetStatus
|
||||||
|
WriteLog $status.WinGetStatus
|
||||||
|
return $status
|
||||||
|
}
|
||||||
|
|
||||||
|
$status.CmdletAvailable = $true
|
||||||
|
$wingetVersion = Get-WinGetVersion -ErrorAction Stop
|
||||||
|
$wingetVersionText = [string]$wingetVersion
|
||||||
|
WriteLog "Get-WinGetVersion returned: $wingetVersionText"
|
||||||
|
|
||||||
|
if ([string]::IsNullOrWhiteSpace($wingetVersionText)) {
|
||||||
|
$status.WinGetVersion = "Not installed"
|
||||||
|
$status.WinGetStatus = "WinGet is not installed."
|
||||||
|
WriteLog $status.WinGetStatus
|
||||||
|
return $status
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($wingetVersionText -match 'v?(\d+\.\d+\.\d+)') {
|
||||||
|
$parsedVersion = [version]$matches[1]
|
||||||
|
$status.WinGetInstalled = $true
|
||||||
|
$status.WinGetVersion = $parsedVersion.ToString()
|
||||||
|
$status.WinGetVersionObject = $parsedVersion
|
||||||
|
$status.WinGetNeedsUpdate = $parsedVersion -lt $MinimumVersion
|
||||||
|
$status.WinGetStatus = if ($status.WinGetNeedsUpdate) { "Update required" } else { $parsedVersion.ToString() }
|
||||||
|
$status.NeedsUpdate = $status.ModuleNeedsUpdate -or $status.WinGetNeedsUpdate
|
||||||
|
$status.Success = -not $status.NeedsUpdate
|
||||||
|
return $status
|
||||||
|
}
|
||||||
|
|
||||||
|
$status.WinGetStatus = "Version check failed."
|
||||||
|
$status.ErrorMessage = "Could not parse Get-WinGetVersion output: $wingetVersionText"
|
||||||
|
WriteLog $status.ErrorMessage
|
||||||
|
return $status
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
$status.ErrorMessage = $_.Exception.Message
|
||||||
|
$status.WinGetStatus = "Get-WinGetVersion failed."
|
||||||
|
WriteLog "Get-WinGetVersion failed: $($status.ErrorMessage)"
|
||||||
|
return $status
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function Confirm-WinGetInstallation {
|
function Confirm-WinGetInstallation {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
param(
|
param(
|
||||||
@@ -1032,12 +1120,11 @@ function Confirm-WinGetInstallation {
|
|||||||
|
|
||||||
WriteLog 'Checking if WinGet is installed...'
|
WriteLog 'Checking if WinGet is installed...'
|
||||||
$minVersion = [version]"1.8.1911"
|
$minVersion = [version]"1.8.1911"
|
||||||
|
$wingetStatus = Get-WinGetComponentStatus -MinimumVersion $minVersion
|
||||||
|
|
||||||
# Check WinGet PowerShell module
|
# Check WinGet PowerShell module
|
||||||
$wingetModule = Get-InstalledModule -Name Microsoft.Winget.Client -ErrorAction SilentlyContinue
|
if ($wingetStatus.ModuleNeedsUpdate) {
|
||||||
$wingetModuleVersion = [version]$wingetModule.Version
|
WriteLog 'Microsoft.WinGet.Client module is not installed or is an older version. Installing the latest version...'
|
||||||
if ($wingetModuleVersion -lt $minVersion -or -not $wingetModule) {
|
|
||||||
WriteLog 'Microsoft.Winget.Client module is not installed or is an older version. Installing the latest version...'
|
|
||||||
|
|
||||||
# Handle PSGallery trust settings
|
# Handle PSGallery trust settings
|
||||||
$PSGalleryTrust = (Get-PSRepository -Name 'PSGallery').InstallationPolicy
|
$PSGalleryTrust = (Get-PSRepository -Name 'PSGallery').InstallationPolicy
|
||||||
@@ -1046,30 +1133,49 @@ function Confirm-WinGetInstallation {
|
|||||||
Set-PSRepository -Name 'PSGallery' -InstallationPolicy Trusted
|
Set-PSRepository -Name 'PSGallery' -InstallationPolicy Trusted
|
||||||
}
|
}
|
||||||
|
|
||||||
Install-Module -Name Microsoft.Winget.Client -Force -Repository 'PSGallery'
|
Install-Module -Name Microsoft.WinGet.Client -Force -Repository 'PSGallery'
|
||||||
|
|
||||||
if ($PSGalleryTrust -eq 'Untrusted') {
|
if ($PSGalleryTrust -eq 'Untrusted') {
|
||||||
WriteLog 'Setting PSGallery back to untrusted repository...'
|
WriteLog 'Setting PSGallery back to untrusted repository...'
|
||||||
Set-PSRepository -Name 'PSGallery' -InstallationPolicy Untrusted
|
Set-PSRepository -Name 'PSGallery' -InstallationPolicy Untrusted
|
||||||
WriteLog 'Done'
|
WriteLog 'Done'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$wingetStatus = Get-WinGetComponentStatus -MinimumVersion $minVersion
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
WriteLog "Installed Microsoft.Winget.Client module version: $($wingetModule.Version)"
|
WriteLog "Installed Microsoft.WinGet.Client module version: $($wingetStatus.ModuleVersion)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($wingetStatus.ModuleNeedsUpdate) {
|
||||||
|
$message = "Microsoft.WinGet.Client module version $($wingetStatus.ModuleVersion) does not meet the minimum required version $minVersion."
|
||||||
|
WriteLog $message
|
||||||
|
throw $message
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not $wingetStatus.CmdletAvailable) {
|
||||||
|
$message = "Get-WinGetVersion cmdlet is not available from Microsoft.WinGet.Client. $($wingetStatus.ErrorMessage)"
|
||||||
|
WriteLog $message
|
||||||
|
throw $message
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not [string]::IsNullOrWhiteSpace($wingetStatus.ErrorMessage)) {
|
||||||
|
$message = "Unable to determine WinGet version by using Get-WinGetVersion. $($wingetStatus.ErrorMessage)"
|
||||||
|
WriteLog $message
|
||||||
|
throw $message
|
||||||
|
}
|
||||||
|
|
||||||
# Check WinGet CLI
|
# Check WinGet CLI
|
||||||
$wingetVersion = Get-WinGetVersion
|
if (-not $wingetStatus.WinGetInstalled) {
|
||||||
if (-not $wingetVersion) {
|
|
||||||
WriteLog "WinGet is not installed. Installing WinGet..."
|
WriteLog "WinGet is not installed. Installing WinGet..."
|
||||||
Install-WinGet -Architecture $WindowsArch
|
Install-WinGet -Architecture $WindowsArch
|
||||||
}
|
}
|
||||||
elseif ($wingetVersion -match 'v?(\d+\.\d+\.\d+)' -and [version]$matches[1] -lt $minVersion) {
|
elseif ($wingetStatus.WinGetNeedsUpdate) {
|
||||||
WriteLog "The installed version of WinGet $($matches[1]) does not support downloading MSStore apps. Installing the latest version of WinGet..."
|
WriteLog "The installed version of WinGet $($wingetStatus.WinGetVersion) does not support downloading MSStore apps. Installing the latest version of WinGet..."
|
||||||
Install-WinGet -Architecture $WindowsArch
|
Install-WinGet -Architecture $WindowsArch
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
WriteLog "Installed WinGet version: $wingetVersion"
|
WriteLog "Installed WinGet version: $($wingetStatus.WinGetVersion)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
@@ -1561,4 +1667,4 @@ function Add-Win32SilentInstallCommand {
|
|||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
|
|
||||||
# Export functions needed by both BuildFFUVM and the UI Core module
|
# Export functions needed by both BuildFFUVM and the UI Core module
|
||||||
Export-ModuleMember -Function Get-Application, Get-Apps, Start-WingetAppDownloadTask, Confirm-WinGetInstallation, Add-Win32SilentInstallCommand, Install-Winget
|
Export-ModuleMember -Function Get-Application, Get-Apps, Start-WingetAppDownloadTask, Confirm-WinGetInstallation, Get-WinGetComponentStatus, Add-Win32SilentInstallCommand, Install-Winget
|
||||||
@@ -233,44 +233,6 @@ function Search-WingetPackagesPublic {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function Test-WingetCLI {
|
|
||||||
[CmdletBinding()]
|
|
||||||
param()
|
|
||||||
|
|
||||||
$minVersion = [version]"1.8.1911"
|
|
||||||
|
|
||||||
# Check Winget CLI
|
|
||||||
$wingetCmd = Get-Command -Name winget -ErrorAction SilentlyContinue
|
|
||||||
if (-not $wingetCmd) {
|
|
||||||
return @{
|
|
||||||
Version = "Not installed"
|
|
||||||
Status = "Not installed - Install from Microsoft Store"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get and check version
|
|
||||||
$wingetVersion = & winget.exe --version
|
|
||||||
if ($wingetVersion -match 'v?(\d+\.\d+.\d+)') {
|
|
||||||
$version = [version]$matches[1]
|
|
||||||
if ($version -lt $minVersion) {
|
|
||||||
return @{
|
|
||||||
Version = $version.ToString()
|
|
||||||
Status = "Update required - Install from Microsoft Store"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return @{
|
|
||||||
Version = $version.ToString()
|
|
||||||
Status = $version.ToString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return @{
|
|
||||||
Version = "Unknown"
|
|
||||||
Status = "Version check failed"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function Install-WingetComponents {
|
function Install-WingetComponents {
|
||||||
[CmdletBinding()]
|
[CmdletBinding()]
|
||||||
param(
|
param(
|
||||||
@@ -339,19 +301,22 @@ function Confirm-WingetInstallationUI {
|
|||||||
try {
|
try {
|
||||||
# Initial Check
|
# Initial Check
|
||||||
WriteLog "Confirm-WingetInstallationUI: Starting checks..."
|
WriteLog "Confirm-WingetInstallationUI: Starting checks..."
|
||||||
$cliStatus = Test-WingetCLI
|
$wingetStatus = Get-WinGetComponentStatus -MinimumVersion $minVersion
|
||||||
$module = @(Get-InstalledModule -Name Microsoft.WinGet.Client -ErrorAction SilentlyContinue) | Sort-Object -Top 1 -Descending Version -ErrorAction SilentlyContinue
|
|
||||||
|
|
||||||
$result.CliVersion = $cliStatus.Version
|
$result.CliVersion = $wingetStatus.WinGetVersion
|
||||||
$result.ModuleVersion = if ($null -ne $module) { $module.Version.ToString() } else { "Not installed" }
|
$result.ModuleVersion = $wingetStatus.ModuleVersion
|
||||||
|
|
||||||
# Use callback for initial status display
|
# Use callback for initial status display
|
||||||
& $UiUpdateCallback $result.CliVersion $result.ModuleVersion
|
& $UiUpdateCallback $result.CliVersion $result.ModuleVersion
|
||||||
|
|
||||||
# Determine if install/update is needed
|
# Determine if install/update is needed
|
||||||
$needsCliUpdate = $cliStatus.Status -notmatch '^\d+\.\d+\.\d+$' -or ([version]$cliStatus.Version -lt $minVersion)
|
$needsCliUpdate = $wingetStatus.WinGetNeedsUpdate
|
||||||
$needsModuleUpdate = ($null -eq $module) -or ([version]$module.Version -lt $minVersion)
|
$needsModuleUpdate = $wingetStatus.ModuleNeedsUpdate
|
||||||
$result.NeedsUpdate = $needsCliUpdate -or $needsModuleUpdate
|
$result.NeedsUpdate = $wingetStatus.NeedsUpdate
|
||||||
|
|
||||||
|
if (-not [string]::IsNullOrWhiteSpace($wingetStatus.ErrorMessage)) {
|
||||||
|
WriteLog "Confirm-WingetInstallationUI: WinGet status error - $($wingetStatus.ErrorMessage)"
|
||||||
|
}
|
||||||
|
|
||||||
if ($result.NeedsUpdate) {
|
if ($result.NeedsUpdate) {
|
||||||
WriteLog "Confirm-WingetInstallationUI: Update needed. CLI Needs Update: $needsCliUpdate, Module Needs Update: $needsModuleUpdate"
|
WriteLog "Confirm-WingetInstallationUI: Update needed. CLI Needs Update: $needsCliUpdate, Module Needs Update: $needsModuleUpdate"
|
||||||
@@ -361,21 +326,29 @@ function Confirm-WingetInstallationUI {
|
|||||||
& $UiUpdateCallback $result.CliVersion "Installing/Updating..."
|
& $UiUpdateCallback $result.CliVersion "Installing/Updating..."
|
||||||
|
|
||||||
# Attempt to install/update Winget CLI and module
|
# Attempt to install/update Winget CLI and module
|
||||||
$installedModule = Install-WingetComponents -UiUpdateCallback $UiUpdateCallback
|
Install-WingetComponents -UiUpdateCallback $UiUpdateCallback | Out-Null
|
||||||
|
|
||||||
# Re-check status after attempt
|
# Re-check status after attempt
|
||||||
WriteLog "Confirm-WingetInstallationUI: Re-checking status after update attempt..."
|
WriteLog "Confirm-WingetInstallationUI: Re-checking status after update attempt..."
|
||||||
$cliStatus = Test-WingetCLI
|
$wingetStatus = Get-WinGetComponentStatus -MinimumVersion $minVersion
|
||||||
$result.CliVersion = $cliStatus.Version
|
$result.CliVersion = $wingetStatus.WinGetVersion
|
||||||
$result.ModuleVersion = if ($null -ne $installedModule) { $installedModule.Version } else { "Install Failed" }
|
$result.ModuleVersion = $wingetStatus.ModuleVersion
|
||||||
# Use callback for final status display after update attempt
|
# Use callback for final status display after update attempt
|
||||||
& $UiUpdateCallback $result.CliVersion $result.ModuleVersion
|
& $UiUpdateCallback $result.CliVersion $result.ModuleVersion
|
||||||
|
|
||||||
# Check if update was successful
|
# Check if update was successful
|
||||||
$cliOk = $cliStatus.Status -match '^\d+\.\d+\.\d+$' -and ([version]$cliStatus.Version -ge $minVersion)
|
$cliOk = $wingetStatus.WinGetInstalled -and -not $wingetStatus.WinGetNeedsUpdate
|
||||||
$moduleOk = ($null -ne $installedModule) -and ([version]$installedModule.Version -ge $minVersion)
|
$moduleOk = $wingetStatus.ModuleInstalled -and -not $wingetStatus.ModuleNeedsUpdate
|
||||||
$result.Success = $cliOk -and $moduleOk
|
$result.Success = $cliOk -and $moduleOk -and [string]::IsNullOrWhiteSpace($wingetStatus.ErrorMessage)
|
||||||
$result.Message = if ($result.Success) { "Winget components installed/updated successfully." } else { "Winget component installation/update failed or is incomplete." }
|
$result.Message = if ($result.Success) {
|
||||||
|
"Winget components installed/updated successfully."
|
||||||
|
}
|
||||||
|
elseif (-not [string]::IsNullOrWhiteSpace($wingetStatus.ErrorMessage)) {
|
||||||
|
"Winget component installation/update failed: $($wingetStatus.ErrorMessage)"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
"Winget component installation/update failed or is incomplete."
|
||||||
|
}
|
||||||
WriteLog "Confirm-WingetInstallationUI: Update attempt finished. Success: $($result.Success). Message: $($result.Message)"
|
WriteLog "Confirm-WingetInstallationUI: Update attempt finished. Success: $($result.Success). Message: $($result.Message)"
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
Reference in New Issue
Block a user