private/Get-OSDeployWindowsAdkInstall.ps1

#Requires -PSEdition Core

function Get-OSDeployWindowsAdkInstall {
    <#
    .SYNOPSIS
        Gets Windows ADK installation information
 
    .DESCRIPTION
        Reads the 32-bit Windows Kits Installed Roots registry key and verifies the
        Assessment and Deployment Kit directory. When available, it derives the installed
        version from an amd64 or arm64 winpe.wim by using Get-WindowsImage, then falls back
        to BuildLabEx or a child registry key name. The function always returns one status
        object, including when no ADK installation is found.
 
    .EXAMPLE
        PS> Get-OSDeployWindowsAdkInstall
 
        Returns the detected ADK installation status, path, and version.
 
    .INPUTS
        None. This function does not accept pipeline input.
 
    .OUTPUTS
        System.Management.Automation.PSCustomObject. Returns one object with IsInstalled,
        InstallPath, and InstallVersion properties. InstallPath and InstallVersion can be
        null when the ADK is not detected or its version cannot be resolved.
 
    .NOTES
        Author: David Segura
        Company: Recast Software
        Version: 0.1.0
        Date: 2026-08-28
 
        Dependencies:
          PowerShell Modules: Dism when winpe.wim is available
          Windows Features: Windows registry, Windows ADK when installed
          DotNet Classes: System.Management.Automation.PSCustomObject
    #>

    [CmdletBinding()]
    param ()

    $result = [ordered]@{
        IsInstalled    = $false
        InstallPath    = $null
        InstallVersion = $null
    }

    $regPath = 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows Kits\Installed Roots'

    if (Test-Path -Path $regPath) {
        $kitsRoot = Get-ItemPropertyValue -Path $regPath -Name 'KitsRoot10' -ErrorAction SilentlyContinue
        if ($kitsRoot) {
            $adkPath = Join-Path $kitsRoot 'Assessment and Deployment Kit'
            if (Test-Path -Path $adkPath) {
                $result.IsInstalled = $true
                $result.InstallPath = $adkPath

                # Determine version from the WinPE OC directory names or registry
                $winpePath = Join-Path $adkPath 'Windows Preinstallation Environment'
                if (Test-Path $winpePath) {
                    # Try to get version from the winpe.wim file if available
                    $wimFile = Join-Path $winpePath 'amd64\en-us\winpe.wim'
                    if (-not (Test-Path $wimFile)) {
                        $wimFile = Join-Path $winpePath 'arm64\en-us\winpe.wim'
                    }
                    if (Test-Path $wimFile) {
                        try {
                            $wimInfo = Get-WindowsImage -ImagePath $wimFile -Index 1 -ErrorAction SilentlyContinue
                            if ($wimInfo) {
                                $result.InstallVersion = "$($wimInfo.MajorVersion).$($wimInfo.MinorVersion).$($wimInfo.Build).$($wimInfo.SPBuild)"
                            }
                        }
                        catch {
                            Write-Verbose "[$($MyInvocation.MyCommand.Name)] Could not read WinPE image version: $_"
                        }
                    }
                }

                # Fallback: use the KitsRoot10 path version segment
                if (-not $result.InstallVersion) {
                    $buildLabEx = Get-ItemPropertyValue -Path $regPath -Name 'BuildLabEx' -ErrorAction SilentlyContinue
                    if ($buildLabEx) {
                        $result.InstallVersion = $buildLabEx
                    }
                    else {
                        # Use the registry key names under Installed Roots as version indicators
                        $versionKeys = Get-ChildItem -Path $regPath -ErrorAction SilentlyContinue |
                            Select-Object -ExpandProperty PSChildName |
                            Sort-Object -Descending
                        if ($versionKeys) {
                            $result.InstallVersion = $versionKeys[0]
                        }
                    }
                }
            }
        }
    }

    [PSCustomObject]$result
}