Public/New-WindowsServerISO.ps1

function New-WindowsServerISO {
    [CmdletBinding()]
    Param(
        [Parameter (Mandatory=$true)]
        [ValidateScript({$_ -like "*.iso"})]
        [string]$ISODestinationPath,

        [Parameter (Mandatory=$true)]
        [string]$Uri,

        [switch]$Force
    )
    try {
        $Drive = Split-Path $ISODestinationPath -Qualifier
        if ((Test-Path $Drive) -eq $false) {
            throw "Could not access drive '$Drive'."
        }
        elseif (Test-Path $ISODestinationPath -ErrorAction SilentlyContinue) {
            if ($Force -eq $false) {
                throw "The file '$ISODestinationPath' already exists."
            }
            else {
                Remove-Item -Path $ISODestinationPath -Force
            }
        }
        elseif ((Test-Path "$Drive\Hyper-V") -eq $false) {
            New-Item -Path (Split-Path $ISODestinationPath) -ItemType Directory | Out-Null
        }
        $WebRequest = [System.Net.WebRequest]::Create($Uri)
        $WebResponse = $WebRequest.GetResponse()
        $WebResponse.Close()
        $DownloadSize = $WebResponse.ContentLength      
        $WebClient = New-Object System.Net.WebClient
        Write-Verbose 'Downloading ISO. This could take a while...'
        $WebClient.DownloadFileAsync($Uri, $ISODestinationPath)
        $i = 0
        while ((Test-Path $ISODestinationPath) -ne $true) {
            if ($i -gt 5) {
                throw 'Timed out waiting for download to start.'
            }
            Start-Sleep -Seconds 2
            $i++
        }
        while ((Get-Item $ISODestinationPath).length -ne $DownloadSize) {
            $Downloaded = (Get-Item $ISODestinationPath).Length
            Write-Progress -Activity "Downloading: $Uri" -Status "$([math]::Round($Downloaded/1MB))MB of $([math]::Round($DownloadSize/1MB))MB" -PercentComplete (($Downloaded / $DownloadSize) * 100)
            Start-Sleep -Milliseconds 200
        }
        Write-Progress -Activity "Downloading: $Uri" -Completed -Status 'Complete'
    }
    catch {
        $PSCmdlet.ThrowTerminatingError($_)
    }
}