Public/Get-Windows11ISO.ps1

function Get-Windows11ISO {
    <#
    .SYNOPSIS
        Downloads Windows 11 ISO using multiple methods with fallback options for upgrade installations.
 
    .DESCRIPTION
        Downloads Windows 11 ISO using multiple automated methods: Automated Media Creation Tool (primary),
        Fido script (fallback), UUP dump (alternative), and manual helpers (last resort). Automatically detects
        the system language and downloads the appropriate localized ISO. The automated Media Creation Tool method
        runs unattended using command-line parameters for fully programmatic ISO creation.
 
    .PARAMETER OutputPath
        Directory where the ISO will be downloaded. Default: C:\Temp
 
    .PARAMETER Edition
        Windows 11 edition to download. Default: Pro
 
    .PARAMETER Language
        Override automatic language detection with a specific language.
        If not specified, the system's current display language will be detected automatically.
 
    .PARAMETER Method
        Preferred download method. Options: Auto (tries all methods), Fido, UUP, MediaCreationTool
        Default: Auto
 
    .PARAMETER LogPath
        Path to the log file for detailed logging.
 
    .EXAMPLE
        $isoPath = Get-Windows11ISO -OutputPath "D:\ISOs" -LogPath "C:\Logs\wu.log"
 
    .EXAMPLE
        $isoPath = Get-Windows11ISO -OutputPath "D:\ISOs" -Edition "Pro" -Language "German" -Method "Auto" -LogPath "C:\Logs\wu.log"
 
    .NOTES
        Downloads Windows 11 ISO files using automated methods with fallback options.
        Requires internet connectivity and adequate disk space (8GB+ for ISO).
        Returns the full path to the downloaded ISO file or helper script.
        Supports automatic language detection and multiple download methods for reliability.
        The automated Media Creation Tool method runs unattended for fully programmatic downloads.
    #>


    [CmdletBinding()]
    param(
        [string]$OutputPath = "C:\Temp",
        
        [ValidateSet('Home', 'Pro', 'Enterprise', 'Education')]
        [string]$Edition = "Pro",
        
        [ValidateSet('Arabic', 'Brazilian Portuguese', 'Bulgarian', 'Chinese (Simplified)', 'Chinese (Traditional)', 
                     'Croatian', 'Czech', 'Danish', 'Dutch', 'English', 'English International', 'Estonian', 
                     'Finnish', 'French', 'French Canadian', 'German', 'Greek', 'Hebrew', 'Hungarian', 'Italian', 
                     'Japanese', 'Korean', 'Latvian', 'Lithuanian', 'Norwegian', 'Polish', 'Portuguese', 'Romanian', 
                     'Russian', 'Serbian Latin', 'Slovak', 'Slovenian', 'Spanish', 'Spanish (Mexico)', 'Swedish', 
                     'Thai', 'Turkish', 'Ukrainian')]
        [string]$Language,
        
        [ValidateSet('Auto', 'Fido', 'UUP', 'MediaCreationTool')]
        [string]$Method = "Auto",
        
        [string]$LogPath
    )
    
    # The public command uses the familiar "Pro" edition name, while the
    # private downloader expects Fido's "Professional" value. Build the
    # private parameter set explicitly so public-only parameters (notably
    # LogPath) are not forwarded to a command that does not declare them.
    $privateParameters = @{
        OutputPath = $OutputPath
        Edition    = if ($Edition -eq 'Pro') { 'Professional' } else { $Edition }
        Method     = $Method
    }

    if ($PSBoundParameters.ContainsKey('Language')) {
        $privateParameters.Language = $Language
    }

    # Private downloader helpers call Write-WULog without carrying LogPath
    # through every helper signature. Scope the requested path to this call
    # and restore any prior value so unrelated module commands are unaffected.
    $previousActiveLogPath = $script:WUActiveLogPath
    if ($PSBoundParameters.ContainsKey('LogPath')) {
        $script:WUActiveLogPath = $LogPath
    }

    try {
        Get-WUWindows11ISO @privateParameters
    }
    finally {
        $script:WUActiveLogPath = $previousActiveLogPath
    }
}