From ab86c5e1ac34bbb766cd5a1650ff8ece4bdeab1f Mon Sep 17 00:00:00 2001
From: Zehadi Alam <63765084+zehadialam@users.noreply.github.com>
Date: Mon, 18 Mar 2024 18:35:37 -0400
Subject: [PATCH 1/2] Add Get-ADKURL and Install-ADK functions
This commit introduces two new functions, Get-ADKURL and Install-ADK, to facilitate the retrieval and installation of the Windows Assessment and Deployment Kit (ADK) components.
The Get-ADKURL function retrieves the download URL for the specified ADK option (either "Windows ADK" or "WinPE Add-on") from the official Microsoft documentation page. It utilizes web scraping to extract the URL dynamically.
The Install-ADK function downloads the specified ADK component from the obtained URL and installs it silently on the system. It handles errors gracefully and cleans up the temporary installation file after completion.
These functions enhance the automation capabilities of the project by simplifying the process of acquiring and installing ADK components required for Windows deployment and assessment tasks.
---
FFUDevelopment/BuildFFUVM.ps1 | 116 +++++++++++++++++++++++++++++++---
1 file changed, 108 insertions(+), 8 deletions(-)
diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1
index ef0f168..97040ed 100644
--- a/FFUDevelopment/BuildFFUVM.ps1
+++ b/FFUDevelopment/BuildFFUVM.ps1
@@ -436,24 +436,124 @@ function Invoke-Process {
}
}
+function Get-ADKURL {
+ param (
+ [ValidateSet("Windows ADK", "WinPE add-on")]
+ [string]$ADKOption
+ )
+
+ # Define base pattern for URL scraping
+ $basePattern = '
Download the '
+
+ # Define specific URL patterns based on ADK options
+ $ADKUrlPattern = @{
+ "Windows ADK" = $basePattern + "Windows ADK"
+ "WinPE add-on" = $basePattern + "Windows PE add-on for the Windows ADK"
+ }[$ADKOption]
+
+ try {
+ # Retrieve content of Microsoft documentation page
+ $ADKWebPage = Invoke-RestMethod "https://learn.microsoft.com/en-us/windows-hardware/get-started/adk-install"
+
+ # Extract download URL based on specified pattern
+ $ADKMatch = [regex]::Match($ADKWebPage, $ADKUrlPattern)
+
+ if (-not $ADKMatch.Success) {
+ WriteLog "Failed to retrieve ADK download URL. Pattern match failed."
+ return
+ }
+
+ # Extract FWlink from the matched pattern
+ $ADKFWLink = $ADKMatch.Groups[1].Value
+
+ if ($null -eq $ADKFWLink) {
+ WriteLog "FWLink for $ADKOption not found."
+ return
+ }
+
+ # Retrieve headers of the FWlink URL
+ $FWLinkRequest = Invoke-WebRequest -Uri $ADKFWLink -Method Head -MaximumRedirection 0 -ErrorAction SilentlyContinue
+
+ if ($FWLinkRequest.StatusCode -ne 302) {
+ WriteLog "Failed to retrieve ADK download URL. Unexpected status code: $($FWLinkRequest.StatusCode)"
+ return
+ }
+
+ # Get the ADK link redirected to by the FWlink
+ $ADKUrl = $FWLinkRequest.Headers.Location
+ return $ADKUrl
+ }
+ catch {
+ WriteLog $_
+ Write-Error "Error occurred while retrieving ADK download URL"
+ throw $_
+ }
+}
+function Install-ADK {
+ param (
+ [ValidateSet("Windows ADK", "WinPE add-on")]
+ [string]$ADKOption
+ )
+
+ try {
+ $ADKUrl = Get-ADKURL -ADKOption $ADKOption
+
+ if ($null -eq $ADKUrl) {
+ throw "Failed to retrieve URL for $ADKOption. Please manually install it."
+ }
+
+ $installer = @{
+ "Windows ADK" = "adksetup.exe"
+ "WinPE add-on" = "adkwinpesetup.exe"
+ }[$ADKOption]
+
+ $feature = @{
+ "Windows ADK" = "OptionId.DeploymentTools"
+ "WinPE add-on" = "OptionId.WindowsPreinstallationEnvironment"
+ }[$ADKOption]
+
+ $installerLocation = Join-Path $env:TEMP $installer
+
+ WriteLog "Downloading $ADKOption from $ADKUrl to $installerLocation"
+ Start-BitsTransfer -Source $ADKUrl -Destination $installerLocation -ErrorAction Stop
+ WriteLog "$ADKOption downloaded to $installerLocation"
+
+ WriteLog "Installing $ADKOption with $feature enabled"
+ Invoke-Process $installerLocation "/quiet /installpath ""%ProgramFiles(x86)%\Windows Kits\10"" /features $feature"
+
+ WriteLog "$ADKOption installation completed."
+ WriteLog "Removing $installer from $installerLocation"
+ # Clean up downloaded installation file
+ Remove-Item -Path $installerLocation -Force -ErrorAction SilentlyContinue
+ }
+ catch {
+ WriteLog $_
+ Write-Error "Error occurred while installing $ADKOption. Please manually install it."
+ throw $_
+ }
+}
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"
$adkRegValueName = "KitsRoot10"
- # Check if the registry key exists
- if (Test-Path $adkRegKey) {
+ # 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
$adkPath = (Get-ItemProperty -Path $adkRegKey -Name $adkRegValueName).$adkRegValueName
-
- if ($adkPath) {
- WriteLog "ADK located at $adkPath"
- return $adkPath
- }
+ WriteLog "ADK located at $adkPath"
+ return $adkPath
}
else {
- throw "Windows ADK is not installed or the installation path could not be found."
+ 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."
}
}
function Get-WindowsESD {
From 662572e5e5da7fb852c87c09868f3726216fb260 Mon Sep 17 00:00:00 2001
From: Zehadi Alam <63765084+zehadialam@users.noreply.github.com>
Date: Mon, 18 Mar 2024 19:45:08 -0400
Subject: [PATCH 2/2] Add clarifying comments to Install-ADK function
---
FFUDevelopment/BuildFFUVM.ps1 | 2 ++
1 file changed, 2 insertions(+)
diff --git a/FFUDevelopment/BuildFFUVM.ps1 b/FFUDevelopment/BuildFFUVM.ps1
index 97040ed..84f464a 100644
--- a/FFUDevelopment/BuildFFUVM.ps1
+++ b/FFUDevelopment/BuildFFUVM.ps1
@@ -502,11 +502,13 @@ function Install-ADK {
throw "Failed to retrieve URL for $ADKOption. Please manually install it."
}
+ # Select the installer based on the ADK option specified
$installer = @{
"Windows ADK" = "adksetup.exe"
"WinPE add-on" = "adkwinpesetup.exe"
}[$ADKOption]
+ # Select the feature based on the ADK option specified
$feature = @{
"Windows ADK" = "OptionId.DeploymentTools"
"WinPE add-on" = "OptionId.WindowsPreinstallationEnvironment"