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 {