From 3a770083ad023714da5d602b084bb8fc54c0c8fa Mon Sep 17 00:00:00 2001 From: Zehadi Alam <63765084+zehadialam@users.noreply.github.com> Date: Thu, 28 Mar 2024 22:45:52 -0400 Subject: [PATCH 1/4] Add Confirm-ADKVersionIsLatest Function This commit introduces the Confirm-ADKVersionIsLatest function to check if the currently installed version of the ADK is the latest available version from Microsoft. --- FFUDevelopment/BuildFFUVM.ps1 | 39 ++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index ea1d339..ec6fa79 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -531,7 +531,44 @@ function Install-ADK { throw $_ } } -Function Get-ADK { +function Confirm-ADKVersionIsLatest { + param ( + [string]$KeyPath + ) + + # Retrieve all subkeys under the specified registry path recursively + $installedADKVersion = Get-ChildItem -Path $KeyPath -Recurse | + # Filter subkeys based on the display name containing "Windows Assessment and Deployment Kit" + Where-Object { $_.GetValue("DisplayName") -eq "Windows Assessment and Deployment Kit" } | + # Extract the display version from the filtered subkeys + ForEach-Object { $_.GetValue("DisplayVersion") } + + if ($null -eq $installedADKVersion) { + WriteLog "Failed to get ADK version" + return $false + } + + $ADKWebPage = Invoke-RestMethod "https://learn.microsoft.com/en-us/windows-hardware/get-started/adk-install" + $ADKVersionPattern = 'ADK\s+(\d+(\.\d+)+)' + $ADKVersionMatch = [regex]::Match($ADKWebPage, $ADKVersionPattern) + + if (-not $ADKVersionMatch.Success) { + Write-Host "Failed to retrieve latest ADK version from web page." + return $false + } + + $latestADKVersion = $ADKVersionMatch.Groups[1].Value + + if ($installedADKVersion -eq $latestADKVersion) { + WriteLog "Installed ADK version $installedADKVersion is the latest." + return $true + } else { + WriteLog "Installed ADK version $installedADKVersion is not the latest ($latestADKVersion)" + return $false + } +} + +function Get-ADK { Writelog 'Get ADK Path' # Define the registry key and value name to query $adkRegKey = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots" From 79c974867579de5bdaf835ff42df7a5f575698ff Mon Sep 17 00:00:00 2001 From: Zehadi Alam <63765084+zehadialam@users.noreply.github.com> Date: Thu, 28 Mar 2024 23:45:04 -0400 Subject: [PATCH 2/4] Add Uninstall-ADK and Find-InstalledProgramInfo functions The Uninstall-ADK function silently uninstalls the ADK component that is specified. The Find-InstalledProgramInfo function searches the registry path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" to determine if certain programs are installed or properties of installed programs (e.g., version number, uninstall string, etc.). --- FFUDevelopment/BuildFFUVM.ps1 | 61 +++++++++++++++++++++++++++++------ 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index ec6fa79..9408789 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -531,17 +531,55 @@ function Install-ADK { throw $_ } } -function Confirm-ADKVersionIsLatest { +function Find-InstalledProgramInfo { param ( - [string]$KeyPath + [string]$RegValueNameFilter, + [string]$RegValueDataFilter, + [string]$RegValueDataRetrieve ) + + $installedProgramInfo = Get-ChildItem -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" -Recurse | + # Filter subkeys based on the display name corresponding to the ADK option + Where-Object { $_.GetValue($RegValueNameFilter) -eq $RegValueDataFilter} | + # Extract the quiet uninstall string from the filtered subkeys + ForEach-Object { $_.GetValue($RegValueDataRetrieve) } - # Retrieve all subkeys under the specified registry path recursively - $installedADKVersion = Get-ChildItem -Path $KeyPath -Recurse | - # Filter subkeys based on the display name containing "Windows Assessment and Deployment Kit" - Where-Object { $_.GetValue("DisplayName") -eq "Windows Assessment and Deployment Kit" } | - # Extract the display version from the filtered subkeys - ForEach-Object { $_.GetValue("DisplayVersion") } + return $installedProgramInfo +} +function Uninstall-ADK { + param ( + [ValidateSet("Windows ADK", "WinPE add-on")] + [string]$ADKOption + ) + + $displayName = @{ + "Windows ADK" = "Windows Assessment and Deployment Kit" + "WinPE add-on" = "Windows Assessment and Deployment Kit Windows Preinstallation Environment Add-ons" + }[$ADKOption] + + try { + $ADKQuietUninstallString = Find-InstalledProgramInfo ` + -RegValueNameFilter "DisplayName" ` + -RegValueDataFilter $displayName ` + -RegValueDataRetrieve "QuietUninstallString" + + if ($null -eq $ADKQuietUninstallString) { + throw "Failed to retrieve quiet uninstall string for $ADKOption. Please manually uninstall it." + } + + Invoke-Process $ADKQuietUninstallString + } + catch { + WriteLog $_ + Write-Error "Error occurred while uninstalling $ADKOption. Please manually uninstall it." + throw $_ + } +} +function Confirm-ADKVersionIsLatest { + $installedADKVersion = Find-InstalledProgramInfo ` + -RegValueNameFilter "DisplayName" ` + -RegValueDataFilter "Windows Assessment and Deployment Kit" ` + -RegValueDataRetrieve "DisplayVersion" if ($null -eq $installedADKVersion) { WriteLog "Failed to get ADK version" @@ -553,7 +591,7 @@ function Confirm-ADKVersionIsLatest { $ADKVersionMatch = [regex]::Match($ADKWebPage, $ADKVersionPattern) if (-not $ADKVersionMatch.Success) { - Write-Host "Failed to retrieve latest ADK version from web page." + WriteLog "Failed to retrieve latest ADK version from web page." return $false } @@ -562,13 +600,16 @@ function Confirm-ADKVersionIsLatest { if ($installedADKVersion -eq $latestADKVersion) { WriteLog "Installed ADK version $installedADKVersion is the latest." return $true - } else { + } + else { WriteLog "Installed ADK version $installedADKVersion is not the latest ($latestADKVersion)" return $false } } function Get-ADK { + $windowsDeploymentTools = $true + Writelog 'Get ADK Path' # Define the registry key and value name to query $adkRegKey = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots" From 996d4352fdb7acb5585b6afcf22fb817997d5cf5 Mon Sep 17 00:00:00 2001 From: Zehadi Alam <63765084+zehadialam@users.noreply.github.com> Date: Sat, 30 Mar 2024 18:56:09 -0400 Subject: [PATCH 3/4] Add error handling and UninstallRegKeys parameter to functions --- FFUDevelopment/BuildFFUVM.ps1 | 198 ++++++++++++++++++++++++---------- 1 file changed, 141 insertions(+), 57 deletions(-) diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index 9408789..a1e516b 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -533,41 +533,55 @@ function Install-ADK { } function Find-InstalledProgramInfo { param ( + [array]$UninstallRegKeys, [string]$RegValueNameFilter, [string]$RegValueDataFilter, [string]$RegValueDataRetrieve ) - $installedProgramInfo = Get-ChildItem -Path "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" -Recurse | - # Filter subkeys based on the display name corresponding to the ADK option - Where-Object { $_.GetValue($RegValueNameFilter) -eq $RegValueDataFilter} | - # Extract the quiet uninstall string from the filtered subkeys - ForEach-Object { $_.GetValue($RegValueDataRetrieve) } - - return $installedProgramInfo + foreach ($key in $UninstallRegKeys) { + try { + $value = $key.GetValue($RegValueNameFilter) + # Check if the value matches the provided filter + if ($value -eq $RegValueDataFilter) { + $installedProgramInfo = $key.GetValue($RegValueDataRetrieve) + return $installedProgramInfo + } + } + catch { + WriteLog $_ + throw "Error occurred while retrieving info for $RegValueDataFilter." + } + } } function Uninstall-ADK { param ( [ValidateSet("Windows ADK", "WinPE add-on")] - [string]$ADKOption + [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 { - $ADKQuietUninstallString = Find-InstalledProgramInfo ` + $adkBundleCachePath = Find-InstalledProgramInfo ` + -UninstallRegKeys $UninstallRegKeys ` -RegValueNameFilter "DisplayName" ` - -RegValueDataFilter $displayName ` - -RegValueDataRetrieve "QuietUninstallString" + -RegValueDataFilter "$displayName" ` + -RegValueDataRetrieve "BundleCachePath" - if ($null -eq $ADKQuietUninstallString) { - throw "Failed to retrieve quiet uninstall string for $ADKOption. Please manually uninstall it." + if (-not $adkBundleCachePath) { + WriteLog "$ADKOption is not installed." + return } - - Invoke-Process $ADKQuietUninstallString + + WriteLog "Uninstalling $ADKOption..." + Invoke-Process $adkBundleCachePath "/uninstall /quiet" + WriteLog "$ADKOption uninstalled successfully." } catch { WriteLog $_ @@ -575,63 +589,133 @@ function Uninstall-ADK { throw $_ } } -function Confirm-ADKVersionIsLatest { - $installedADKVersion = Find-InstalledProgramInfo ` - -RegValueNameFilter "DisplayName" ` - -RegValueDataFilter "Windows Assessment and Deployment Kit" ` - -RegValueDataRetrieve "DisplayVersion" +function Confirm-ADKVersionIsLatest { + param ( + [ValidateSet("Windows ADK", "WinPE add-on")] + [string]$ADKOption, + [array]$UninstallRegKeys + ) - if ($null -eq $installedADKVersion) { - WriteLog "Failed to get ADK version" - return $false + # 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 ` + -UninstallRegKeys $UninstallRegKeys ` + -RegValueNameFilter "DisplayName" ` + -RegValueDataFilter "$displayName" ` + -RegValueDataRetrieve "DisplayVersion" + + if (-not $installedADKVersion) { + WriteLog "Failed to get $ADKOption version. It may not be installed." + return $false + } + + # Retrieve content of Microsoft documentation page + $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+)+)' + # Check for regex pattern match + $ADKVersionMatch = [regex]::Match($ADKWebPage, $ADKVersionPattern) + + if (-not $ADKVersionMatch.Success) { + WriteLog "Failed to retrieve latest ADK version from web page." + return $false + } + + # Extract ADK version from the matched pattern + $latestADKVersion = $ADKVersionMatch.Groups[1].Value + + if ($installedADKVersion -eq $latestADKVersion) { + WriteLog "Installed $ADKOption version $installedADKVersion is the latest." + return $true + } + else { + WriteLog "Installed $ADKOption version $installedADKVersion is not the latest ($latestADKVersion)" + return $false + } } - - $ADKWebPage = Invoke-RestMethod "https://learn.microsoft.com/en-us/windows-hardware/get-started/adk-install" - $ADKVersionPattern = 'ADK\s+(\d+(\.\d+)+)' - $ADKVersionMatch = [regex]::Match($ADKWebPage, $ADKVersionPattern) - - if (-not $ADKVersionMatch.Success) { - WriteLog "Failed to retrieve latest ADK version from web page." - return $false - } - - $latestADKVersion = $ADKVersionMatch.Groups[1].Value - - if ($installedADKVersion -eq $latestADKVersion) { - WriteLog "Installed ADK version $installedADKVersion is the latest." - return $true - } - else { - WriteLog "Installed ADK version $installedADKVersion is not the latest ($latestADKVersion)" + catch { + WriteLog "An error occurred while confirming the ADK version: $_" return $false } } function Get-ADK { - $windowsDeploymentTools = $true - - Writelog 'Get ADK Path' - # Define the registry key and value name to query + # Define registry paths + $uninstallRegPath = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" $adkRegKey = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots" $adkRegValueName = "KitsRoot10" - # Check if the registry value exists - if ($null -ne (Get-ItemProperty -Path $adkRegKey -Name $adkRegValueName -ErrorAction SilentlyContinue)) { - # Get the registry value for the Windows ADK installation path + # Get all uninstall registry keys + $uninstallRegKeys = Get-ChildItem -Path $uninstallRegPath -Recurse + $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 WriteLog "ADK located at $adkPath" - return $adkPath } else { - WriteLog "ADK is not installed. Installing ADK now..." - 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." + throw "Windows ADK 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 { param( From c3a4da79148e1331dedfc3c8e45fb4d9c1bdb84b Mon Sep 17 00:00:00 2001 From: Zehadi Alam <63765084+zehadialam@users.noreply.github.com> Date: Sun, 31 Mar 2024 16:12:22 -0400 Subject: [PATCH 4/4] Refactor functions for improved readability --- FFUDevelopment/BuildFFUVM.ps1 | 144 ++++++++++++++-------------------- 1 file changed, 57 insertions(+), 87 deletions(-) diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1 index a1e516b..a6910ab 100644 --- a/FFUDevelopment/BuildFFUVM.ps1 +++ b/FFUDevelopment/BuildFFUVM.ps1 @@ -531,54 +531,49 @@ function Install-ADK { throw $_ } } -function Find-InstalledProgramInfo { +function Get-InstalledProgramRegKey { param ( - [array]$UninstallRegKeys, - [string]$RegValueNameFilter, - [string]$RegValueDataFilter, - [string]$RegValueDataRetrieve + [string]$DisplayName ) - foreach ($key in $UninstallRegKeys) { + $uninstallRegPath = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" + $uninstallRegKeys = Get-ChildItem -Path $uninstallRegPath -Recurse + + foreach ($regKey in $uninstallRegKeys) { try { - $value = $key.GetValue($RegValueNameFilter) - # Check if the value matches the provided filter - if ($value -eq $RegValueDataFilter) { - $installedProgramInfo = $key.GetValue($RegValueDataRetrieve) - return $installedProgramInfo + $regValue = $regKey.GetValue("DisplayName") + if ($regValue -eq $DisplayName) { + return $regKey } - } + } catch { WriteLog $_ - throw "Error occurred while retrieving info for $RegValueDataFilter." + throw "Error retrieving installed program info for $DisplayName : $_" } } } + function Uninstall-ADK { param ( [ValidateSet("Windows ADK", "WinPE add-on")] - [string]$ADKOption, - [array]$UninstallRegKeys + [string]$ADKOption ) # 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] + $displayName = switch ($ADKOption) { + "Windows ADK" { "Windows Assessment and Deployment Kit" } + "WinPE add-on" { "Windows Assessment and Deployment Kit Windows Preinstallation Environment Add-ons" } + } try { - $adkBundleCachePath = Find-InstalledProgramInfo ` - -UninstallRegKeys $UninstallRegKeys ` - -RegValueNameFilter "DisplayName" ` - -RegValueDataFilter "$displayName" ` - -RegValueDataRetrieve "BundleCachePath" - - if (-not $adkBundleCachePath) { + $adkRegKey = Get-InstalledProgramRegKey -DisplayName $displayName + + if (-not $adkRegKey) { WriteLog "$ADKOption is not installed." return } + $adkBundleCachePath = $adkRegKey.GetValue("BundleCachePath") WriteLog "Uninstalling $ADKOption..." Invoke-Process $adkBundleCachePath "/uninstall /quiet" WriteLog "$ADKOption uninstalled successfully." @@ -589,51 +584,46 @@ function Uninstall-ADK { throw $_ } } + function Confirm-ADKVersionIsLatest { param ( [ValidateSet("Windows ADK", "WinPE add-on")] - [string]$ADKOption, - [array]$UninstallRegKeys + [string]$ADKOption ) - # 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] + $displayName = switch ($ADKOption) { + "Windows ADK" { "Windows Assessment and Deployment Kit" } + "WinPE add-on" { "Windows Assessment and Deployment Kit Windows Preinstallation Environment Add-ons" } + } try { - # Get installed ADK version - $installedADKVersion = Find-InstalledProgramInfo ` - -UninstallRegKeys $UninstallRegKeys ` - -RegValueNameFilter "DisplayName" ` - -RegValueDataFilter "$displayName" ` - -RegValueDataRetrieve "DisplayVersion" + $adkRegKey = Get-InstalledProgramRegKey -DisplayName $displayName - if (-not $installedADKVersion) { - WriteLog "Failed to get $ADKOption version. It may not be installed." + if (-not $adkRegKey) { return $false } - - # Retrieve content of Microsoft documentation page - $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+)+)' - # Check for regex pattern match - $ADKVersionMatch = [regex]::Match($ADKWebPage, $ADKVersionPattern) - if (-not $ADKVersionMatch.Success) { + $installedADKVersion = $adkRegKey.GetValue("DisplayVersion") + + # Retrieve content of Microsoft documentation page + $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+)+)' + # Check for regex pattern match + $adkVersionMatch = [regex]::Match($adkWebPage, $adkVersionPattern) + + if (-not $adkVersionMatch.Success) { WriteLog "Failed to retrieve latest ADK version from web page." return $false } # Extract ADK version from the matched pattern - $latestADKVersion = $ADKVersionMatch.Groups[1].Value + $latestADKVersion = $adkVersionMatch.Groups[1].Value if ($installedADKVersion -eq $latestADKVersion) { WriteLog "Installed $ADKOption version $installedADKVersion is the latest." return $true - } + } else { WriteLog "Installed $ADKOption version $installedADKVersion is not the latest ($latestADKVersion)" return $false @@ -646,44 +636,32 @@ function Confirm-ADKVersionIsLatest { } function Get-ADK { - # Define registry paths - $uninstallRegPath = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall" - $adkRegKey = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots" - $adkRegValueName = "KitsRoot10" - - # Get all uninstall registry keys - $uninstallRegKeys = Get-ChildItem -Path $uninstallRegPath -Recurse - $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 + $latestADKInstalled = Confirm-ADKVersionIsLatest -ADKOption "Windows ADK" + $latestWinPEInstalled = Confirm-ADKVersionIsLatest -ADKOption "WinPE add-on" # Uninstall older versions and install latest versions if necessary if (-not $latestADKInstalled) { - Uninstall-ADK -ADKOption "Windows ADK" -UninstallRegKeys $uninstallRegKeys + Uninstall-ADK -ADKOption "Windows ADK" Install-ADK -ADKOption "Windows ADK" - $uninstallKeysUpdated = $true } if (-not $latestWinPEInstalled) { - Uninstall-ADK -ADKOption "WinPE add-on" -UninstallRegKeys $uninstallRegKeys + Uninstall-ADK -ADKOption "WinPE add-on" Install-ADK -ADKOption "WinPE add-on" - $uninstallKeysUpdated = $true } - if ($uninstallKeysUpdated) { - # Get updated uninstall registry keys - $uninstallRegKeys = Get-ChildItem -Path $uninstallRegPath -Recurse - } + # Define registry path + $adkPathKey = "HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots" + $adkPathName = "KitsRoot10" # Check if ADK installation path exists in registry - $adkRegValueExists = (Get-ItemProperty -Path $adkRegKey -Name $adkRegValueName -ErrorAction SilentlyContinue) + $adkPathNameExists = (Get-ItemProperty -Path $adkPathKey -Name $adkPathName -ErrorAction SilentlyContinue) - if ($adkRegValueExists) { + if ($adkPathNameExists) { # Get the ADK installation path WriteLog 'Get ADK Path' - $adkPath = (Get-ItemProperty -Path $adkRegKey -Name $adkRegValueName).$adkRegValueName + $adkPath = (Get-ItemProperty -Path $adkPathKey -Name $adkPathName).$adkPathName WriteLog "ADK located at $adkPath" } else { @@ -691,30 +669,22 @@ function Get-ADK { } # 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" + $deploymentToolsRegKey = Get-InstalledProgramRegKey -DisplayName "Windows Deployment Tools" - if (-not $deploymentToolsInstalled) { + if (-not $deploymentToolsRegKey) { 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" + $adkRegKey = Get-InstalledProgramRegKey -DisplayName "Windows Assessment and Deployment Kit" + $adkBundleCachePath = $adkRegKey.GetValue("BundleCachePath") if ($adkBundleCachePath) { WriteLog "Installing Windows Deployment Tools..." - $installPath = $adkPath.TrimEnd('\') - Invoke-Process $adkBundleCachePath "/quiet /installpath ""$installPath"" /features OptionId.DeploymentTools" + $adkInstallPath = $adkPath.TrimEnd('\') + Invoke-Process $adkBundleCachePath "/quiet /installpath ""$adkInstallPath"" /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 {