Add error handling and UninstallRegKeys parameter to functions

This commit is contained in:
Zehadi Alam
2024-03-30 18:56:09 -04:00
parent 79c9748675
commit 996d4352fd
+118 -34
View File
@@ -533,41 +533,55 @@ function Install-ADK {
} }
function Find-InstalledProgramInfo { function Find-InstalledProgramInfo {
param ( param (
[array]$UninstallRegKeys,
[string]$RegValueNameFilter, [string]$RegValueNameFilter,
[string]$RegValueDataFilter, [string]$RegValueDataFilter,
[string]$RegValueDataRetrieve [string]$RegValueDataRetrieve
) )
$installedProgramInfo = Get-ChildItem -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" -Recurse | foreach ($key in $UninstallRegKeys) {
# Filter subkeys based on the display name corresponding to the ADK option try {
Where-Object { $_.GetValue($RegValueNameFilter) -eq $RegValueDataFilter} | $value = $key.GetValue($RegValueNameFilter)
# Extract the quiet uninstall string from the filtered subkeys # Check if the value matches the provided filter
ForEach-Object { $_.GetValue($RegValueDataRetrieve) } if ($value -eq $RegValueDataFilter) {
$installedProgramInfo = $key.GetValue($RegValueDataRetrieve)
return $installedProgramInfo return $installedProgramInfo
} }
}
catch {
WriteLog $_
throw "Error occurred while retrieving info for $RegValueDataFilter."
}
}
}
function Uninstall-ADK { function Uninstall-ADK {
param ( param (
[ValidateSet("Windows ADK", "WinPE add-on")] [ValidateSet("Windows ADK", "WinPE add-on")]
[string]$ADKOption [string]$ADKOption,
[array]$UninstallRegKeys
) )
# Match name as it appears in the registry
$displayName = @{ $displayName = @{
"Windows ADK" = "Windows Assessment and Deployment Kit" "Windows ADK" = "Windows Assessment and Deployment Kit"
"WinPE add-on" = "Windows Assessment and Deployment Kit Windows Preinstallation Environment Add-ons" "WinPE add-on" = "Windows Assessment and Deployment Kit Windows Preinstallation Environment Add-ons"
}[$ADKOption] }[$ADKOption]
try { try {
$ADKQuietUninstallString = Find-InstalledProgramInfo ` $adkBundleCachePath = Find-InstalledProgramInfo `
-UninstallRegKeys $UninstallRegKeys `
-RegValueNameFilter "DisplayName" ` -RegValueNameFilter "DisplayName" `
-RegValueDataFilter $displayName ` -RegValueDataFilter "$displayName" `
-RegValueDataRetrieve "QuietUninstallString" -RegValueDataRetrieve "BundleCachePath"
if ($null -eq $ADKQuietUninstallString) { if (-not $adkBundleCachePath) {
throw "Failed to retrieve quiet uninstall string for $ADKOption. Please manually uninstall it." WriteLog "$ADKOption is not installed."
return
} }
Invoke-Process $ADKQuietUninstallString WriteLog "Uninstalling $ADKOption..."
Invoke-Process $adkBundleCachePath "/uninstall /quiet"
WriteLog "$ADKOption uninstalled successfully."
} }
catch { catch {
WriteLog $_ WriteLog $_
@@ -576,18 +590,36 @@ function Uninstall-ADK {
} }
} }
function Confirm-ADKVersionIsLatest { function Confirm-ADKVersionIsLatest {
param (
[ValidateSet("Windows ADK", "WinPE add-on")]
[string]$ADKOption,
[array]$UninstallRegKeys
)
# Match name as it appears in the registry
$displayName = @{
"Windows ADK" = "Windows Assessment and Deployment Kit"
"WinPE add-on" = "Windows Assessment and Deployment Kit Windows Preinstallation Environment Add-ons"
}[$ADKOption]
try {
# Get installed ADK version
$installedADKVersion = Find-InstalledProgramInfo ` $installedADKVersion = Find-InstalledProgramInfo `
-UninstallRegKeys $UninstallRegKeys `
-RegValueNameFilter "DisplayName" ` -RegValueNameFilter "DisplayName" `
-RegValueDataFilter "Windows Assessment and Deployment Kit" ` -RegValueDataFilter "$displayName" `
-RegValueDataRetrieve "DisplayVersion" -RegValueDataRetrieve "DisplayVersion"
if ($null -eq $installedADKVersion) { if (-not $installedADKVersion) {
WriteLog "Failed to get ADK version" WriteLog "Failed to get $ADKOption version. It may not be installed."
return $false return $false
} }
# Retrieve content of Microsoft documentation page
$ADKWebPage = Invoke-RestMethod "https://learn.microsoft.com/en-us/windows-hardware/get-started/adk-install" $ADKWebPage = Invoke-RestMethod "https://learn.microsoft.com/en-us/windows-hardware/get-started/adk-install"
# Specify regex pattern for ADK version
$ADKVersionPattern = 'ADK\s+(\d+(\.\d+)+)' $ADKVersionPattern = 'ADK\s+(\d+(\.\d+)+)'
# Check for regex pattern match
$ADKVersionMatch = [regex]::Match($ADKWebPage, $ADKVersionPattern) $ADKVersionMatch = [regex]::Match($ADKWebPage, $ADKVersionPattern)
if (-not $ADKVersionMatch.Success) { if (-not $ADKVersionMatch.Success) {
@@ -595,43 +627,95 @@ function Confirm-ADKVersionIsLatest {
return $false return $false
} }
# Extract ADK version from the matched pattern
$latestADKVersion = $ADKVersionMatch.Groups[1].Value $latestADKVersion = $ADKVersionMatch.Groups[1].Value
if ($installedADKVersion -eq $latestADKVersion) { if ($installedADKVersion -eq $latestADKVersion) {
WriteLog "Installed ADK version $installedADKVersion is the latest." WriteLog "Installed $ADKOption version $installedADKVersion is the latest."
return $true return $true
} }
else { else {
WriteLog "Installed ADK version $installedADKVersion is not the latest ($latestADKVersion)" WriteLog "Installed $ADKOption version $installedADKVersion is not the latest ($latestADKVersion)"
return $false
}
}
catch {
WriteLog "An error occurred while confirming the ADK version: $_"
return $false return $false
} }
} }
function Get-ADK { function Get-ADK {
$windowsDeploymentTools = $true # Define registry paths
$uninstallRegPath = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
Writelog 'Get ADK Path'
# Define the registry key and value name to query
$adkRegKey = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots" $adkRegKey = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots"
$adkRegValueName = "KitsRoot10" $adkRegValueName = "KitsRoot10"
# Check if the registry value exists # Get all uninstall registry keys
if ($null -ne (Get-ItemProperty -Path $adkRegKey -Name $adkRegValueName -ErrorAction SilentlyContinue)) { $uninstallRegKeys = Get-ChildItem -Path $uninstallRegPath -Recurse
# Get the registry value for the Windows ADK installation path $uninstallKeysUpdated = $false
# Check if latest ADK and WinPE add-on are installed
$latestADKInstalled = Confirm-ADKVersionIsLatest -ADKOption "Windows ADK" -UninstallRegKeys $uninstallRegKeys
$latestWinPEInstalled = Confirm-ADKVersionIsLatest -ADKOption "WinPE add-on" -UninstallRegKeys $uninstallRegKeys
# Uninstall older versions and install latest versions if necessary
if (-not $latestADKInstalled) {
Uninstall-ADK -ADKOption "Windows ADK" -UninstallRegKeys $uninstallRegKeys
Install-ADK -ADKOption "Windows ADK"
$uninstallKeysUpdated = $true
}
if (-not $latestWinPEInstalled) {
Uninstall-ADK -ADKOption "WinPE add-on" -UninstallRegKeys $uninstallRegKeys
Install-ADK -ADKOption "WinPE add-on"
$uninstallKeysUpdated = $true
}
if ($uninstallKeysUpdated) {
# Get updated uninstall registry keys
$uninstallRegKeys = Get-ChildItem -Path $uninstallRegPath -Recurse
}
# Check if ADK installation path exists in registry
$adkRegValueExists = (Get-ItemProperty -Path $adkRegKey -Name $adkRegValueName -ErrorAction SilentlyContinue)
if ($adkRegValueExists) {
# Get the ADK installation path
WriteLog 'Get ADK Path'
$adkPath = (Get-ItemProperty -Path $adkRegKey -Name $adkRegValueName).$adkRegValueName $adkPath = (Get-ItemProperty -Path $adkRegKey -Name $adkRegValueName).$adkRegValueName
WriteLog "ADK located at $adkPath" WriteLog "ADK located at $adkPath"
return $adkPath
} }
else { else {
WriteLog "ADK is not installed. Installing ADK now..." throw "Windows ADK installation path could not be found."
Install-ADK -ADKOption "Windows ADK"
WriteLog "Installing WinPE add-on for Windows ADK..."
Install-ADK -ADKOption "WinPE add-on"
$adkPath = (Get-ItemProperty -Path $adkRegKey -Name $adkRegValueName).$adkRegValueName
WriteLog "ADK located at $adkPath"
return $adkPath
# throw "Windows ADK is not installed or the installation path could not be found."
} }
# If ADK was already installed, then check if the Windows Deployment Tools feature is also installed
$deploymentToolsInstalled = Find-InstalledProgramInfo `
-UninstallRegKeys $uninstallRegKeys `
-RegValueNameFilter "DisplayName" `
-RegValueDataFilter "Windows Deployment Tools" `
-RegValueDataRetrieve "DisplayVersion"
if (-not $deploymentToolsInstalled) {
WriteLog "ADK is installed, but the Windows Deployment Tools feature is not installed."
$adkBundleCachePath = Find-InstalledProgramInfo `
-UninstallRegKeys $uninstallRegKeys `
-RegValueNameFilter "DisplayName" `
-RegValueDataFilter "Windows Assessment and Deployment Kit" `
-RegValueDataRetrieve "BundleCachePath"
if ($adkBundleCachePath) {
WriteLog "Installing Windows Deployment Tools..."
$installPath = $adkPath.TrimEnd('\')
Invoke-Process $adkBundleCachePath "/quiet /installpath ""$installPath"" /features OptionId.DeploymentTools"
WriteLog "Windows Deployment Tools installed successfully."
}
else {
throw "Failed to retrieve path to adksetup.exe to install the Windows Deployment Tools. Please manually install it."
}
}
return $adkPath
} }
function Get-WindowsESD { function Get-WindowsESD {
param( param(