Add Commandline support

* Also fix a regression introduced by previous commit
* Closes #15
* Closes #24
This commit is contained in:
flx5
2021-08-07 23:32:09 +02:00
committed by Pete Batard
parent f70836e6c1
commit 8b40c85d76
2 changed files with 288 additions and 45 deletions

270
Fido.ps1
View File

@@ -1,6 +1,7 @@
# #
# Fido v1.20 - Retail Windows ISO Downloader # Fido v1.20 - Retail Windows ISO Downloader
# Copyright © 2019-2021 Pete Batard <pete@akeo.ie> # Copyright © 2019-2021 Pete Batard <pete@akeo.ie>
# Command line support: Copyright © 2021 flx5
# ConvertTo-ImageSource: Copyright © 2016 Chris Carter # ConvertTo-ImageSource: Copyright © 2016 Chris Carter
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
@@ -30,14 +31,32 @@ param(
[string]$Icon, [string]$Icon,
# (Optional) Name of a pipe the download URL should be sent to. # (Optional) Name of a pipe the download URL should be sent to.
# If not provided, a browser window is opened instead. # If not provided, a browser window is opened instead.
[string]$PipeName [string]$PipeName,
# (Optional) Specify Windows version (e.g. "Windows 10") [Toggles commandline mode]
[string]$Win,
# (Optional) Specify Windows release (e.g. "21H1") [Toggles commandline mode]
[string]$Rel,
# (Optional) Specify Windows edition (e.g. "Pro") [Toggles commandline mode]
[string]$Ed,
# (Optional) Specify Windows language [Toggles commandline mode]
[string]$Lang,
# (Optional) Specify Windows architecture [Toggles commandline mode]
[string]$Arch,
# (Optional) Only display the download URL [Toggles commandline mode]
[switch]$GetUrl = $False,
# (Optional) Increase verbosity
[switch]$Verbose = $False
) )
#endregion #endregion
try { try {
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8 [Console]::OutputEncoding = [System.Text.Encoding]::UTF8
} catch {} } catch {}
Write-Host Please Wait...
$Cmd = $False
if ($Win -or $Rel -or $Ed -or $Lang -or $Arch -or $GetUrl) {
$Cmd = $True
}
#region Assembly Types #region Assembly Types
$code = @" $code = @"
@@ -59,14 +78,17 @@ $code = @"
} }
"@ "@
if ($host.version -ge "7.0") { if (!$Cmd) {
Write-Host Please Wait...
if ($host.version -ge "7.0") {
Add-Type -WarningAction Ignore -IgnoreWarnings -MemberDefinition $code -Namespace Gui -UsingNamespace System.Runtime, System.IO, System.Text, System.Drawing, System.Globalization -ReferencedAssemblies System.Drawing.Common -Name Utils -ErrorAction Stop Add-Type -WarningAction Ignore -IgnoreWarnings -MemberDefinition $code -Namespace Gui -UsingNamespace System.Runtime, System.IO, System.Text, System.Drawing, System.Globalization -ReferencedAssemblies System.Drawing.Common -Name Utils -ErrorAction Stop
} else { } else {
Add-Type -MemberDefinition $code -Namespace Gui -UsingNamespace System.IO, System.Text, System.Drawing, System.Globalization -ReferencedAssemblies System.Drawing -Name Utils -ErrorAction Stop Add-Type -MemberDefinition $code -Namespace Gui -UsingNamespace System.IO, System.Text, System.Drawing, System.Globalization -ReferencedAssemblies System.Drawing -Name Utils -ErrorAction Stop
}
Add-Type -AssemblyName PresentationFramework
# Hide the powershell window: https://stackoverflow.com/a/27992426/1069307
[Gui.Utils]::ShowWindow(([System.Diagnostics.Process]::GetCurrentProcess() | Get-Process).MainWindowHandle, 0) | Out-Null
} }
Add-Type -AssemblyName PresentationFramework
# Hide the powershell window: https://stackoverflow.com/a/27992426/1069307
[Gui.Utils]::ShowWindow(([System.Diagnostics.Process]::GetCurrentProcess() | Get-Process).MainWindowHandle, 0) | Out-Null
#endregion #endregion
#region Data #region Data
@@ -209,7 +231,7 @@ $WindowsVersions = @(
@("Windows 8.1", "windows8ISO"), @("Windows 8.1", "windows8ISO"),
@( @(
"Update 3 (build 9600)", "Update 3 (build 9600)",
@("Windows 8.1", 52), @("Windows 8.1 Standard", 52),
@("Windows 8.1 N", 55) @("Windows 8.1 N", 55)
@("Windows 8.1 Single Language", 48), @("Windows 8.1 Single Language", 48),
@("Windows 8.1 K", ($ko + 61)), @("Windows 8.1 K", ($ko + 61)),
@@ -452,11 +474,15 @@ function GetElementById([object]$Request, [string]$Id)
function Error([string]$ErrorMessage) function Error([string]$ErrorMessage)
{ {
Write-Host Error: $ErrorMessage Write-Host Error: $ErrorMessage
if (!$Cmd) {
$XMLForm.Title = $(Get-Translation("Error")) + ": " + $ErrorMessage $XMLForm.Title = $(Get-Translation("Error")) + ": " + $ErrorMessage
Refresh-Control($XMLForm) Refresh-Control($XMLForm)
$XMLGrid.Children[2 * $script:Stage + 1].IsEnabled = $True $XMLGrid.Children[2 * $script:Stage + 1].IsEnabled = $True
$UserInput = [System.Windows.MessageBox]::Show($XMLForm.Title, $(Get-Translation("Error")), "OK", "Error") $UserInput = [System.Windows.MessageBox]::Show($XMLForm.Title, $(Get-Translation("Error")), "OK", "Error")
$script:ExitCode = $script:Stage-- $script:ExitCode = $script:Stage--
} else {
$script:ExitCode = 2
}
} }
function Get-RandomDate() function Get-RandomDate()
@@ -491,6 +517,9 @@ $dh = 58
$Stage = 0 $Stage = 0
$SelectedIndex = 0 $SelectedIndex = 0
$ltrm = "" $ltrm = ""
if ($Cmd) {
$ltrm = ""
}
$MaxStage = 4 $MaxStage = 4
$SessionId = [guid]::NewGuid() $SessionId = [guid]::NewGuid()
$ExitCode = 100 $ExitCode = 100
@@ -504,6 +533,10 @@ $RequestData["GetLinks"] = @("a224afab-2097-4dfa-a2ba-463eb191a285", "GetProduct
$FirefoxVersion = Get-Random -Minimum 50 -Maximum 90 $FirefoxVersion = Get-Random -Minimum 50 -Maximum 90
$FirefoxDate = Get-RandomDate $FirefoxDate = Get-RandomDate
$UserAgent = "Mozilla/5.0 (X11; Linux i586; rv:$FirefoxVersion.0) Gecko/$FirefoxDate Firefox/$FirefoxVersion.0" $UserAgent = "Mozilla/5.0 (X11; Linux i586; rv:$FirefoxVersion.0) Gecko/$FirefoxDate Firefox/$FirefoxVersion.0"
$Verbosity = 0
if ($Verbose) {
$Verbosity = 1
}
#endregion #endregion
# Localization # Localization
@@ -536,7 +569,9 @@ if ($PSVersionTable.PSVersion.Major -lt 3) {
function Check-Locale { function Check-Locale {
try { try {
$url = "https://www.microsoft.com/" + $QueryLocale + "/software-download/" $url = "https://www.microsoft.com/" + $QueryLocale + "/software-download/"
if (!$Cmd -or $Verbose) {
Write-Host Querying $url Write-Host Querying $url
}
Invoke-WebRequest -UseBasicParsing -MaximumRedirection 0 -UserAgent $UserAgent $url | Out-Null Invoke-WebRequest -UseBasicParsing -MaximumRedirection 0 -UserAgent $UserAgent $url | Out-Null
} catch { } catch {
$script:QueryLocale = "en-US" $script:QueryLocale = "en-US"
@@ -593,11 +628,16 @@ function Get-Windows-Languages([int]$SelectedVersion, [int]$SelectedEdition)
$url += "&sessionId=" + $SessionId $url += "&sessionId=" + $SessionId
$url += "&productEditionId=" + [Math]::Abs($SelectedEdition) $url += "&productEditionId=" + [Math]::Abs($SelectedEdition)
$url += "&sdVersion=2" $url += "&sdVersion=2"
if (!$Cmd -or $Verbose) {
Write-Host Querying $url Write-Host Querying $url
}
$script:SelectedIndex = 0 $script:SelectedIndex = 0
try { try {
$r = Invoke-WebRequest -UseBasicParsing -UserAgent $UserAgent -SessionVariable "Session" $url $r = Invoke-WebRequest -UseBasicParsing -UserAgent $UserAgent -SessionVariable "Session" $url
if ($r -match "errorModalMessage") {
Throw-Error -Req $r -Alt "Could not retrieve languages from server"
}
$pattern = '(?s)<select id="product-languages">(.*)?</select>' $pattern = '(?s)<select id="product-languages">(.*)?</select>'
$html = [regex]::Match($r, $pattern).Groups[1].Value $html = [regex]::Match($r, $pattern).Groups[1].Value
# Go through an XML conversion to keep all PowerShells happy... # Go through an XML conversion to keep all PowerShells happy...
@@ -643,7 +683,9 @@ function Get-Windows-Download-Links([int]$SelectedVersion, [int]$SelectedEdition
$url += "&skuId=" + $SkuId $url += "&skuId=" + $SkuId
$url += "&language=" + $LanguageName $url += "&language=" + $LanguageName
$url += "&sdVersion=2" $url += "&sdVersion=2"
if (!$Cmd -or $Verbose) {
Write-Host Querying $url Write-Host Querying $url
}
$i = 0 $i = 0
$script:SelectedIndex = 0 $script:SelectedIndex = 0
@@ -651,6 +693,9 @@ function Get-Windows-Download-Links([int]$SelectedVersion, [int]$SelectedEdition
try { try {
$Is64 = [Environment]::Is64BitOperatingSystem $Is64 = [Environment]::Is64BitOperatingSystem
$r = Invoke-WebRequest -Method Post -UseBasicParsing -UserAgent $UserAgent -WebSession $Session $url $r = Invoke-WebRequest -Method Post -UseBasicParsing -UserAgent $UserAgent -WebSession $Session $url
if ($r -match "errorModalMessage") {
Throw-Error -Req $r -Alt "Could not retrieve architectures from server"
}
$pattern = '(?s)(<input.*?></input>)' $pattern = '(?s)(<input.*?></input>)'
ForEach-Object { [regex]::Matches($r, $pattern) } | ForEach-Object { $html += $_.Groups[1].value } ForEach-Object { [regex]::Matches($r, $pattern) } | ForEach-Object { $html += $_.Groups[1].value }
# Need to fix the HTML and JSON data so that it is well-formed # Need to fix the HTML and JSON data so that it is well-formed
@@ -687,10 +732,171 @@ function Process-Download-Link([string]$Url)
{ {
if ($PipeName -and -not $Check.IsChecked) { if ($PipeName -and -not $Check.IsChecked) {
Send-Message -PipeName $PipeName -Message $Url Send-Message -PipeName $PipeName -Message $Url
} else {
if ($Cmd) {
$pattern = '.*\/(.*\.iso).*'
$File = [regex]::Match($Url, $pattern).Groups[1].Value
Write-Host "Downloading '$File'..."
Invoke-WebRequest -UseBasicParsing -Uri $Url -OutFile $File
} else { } else {
Write-Host Download Link: $Url Write-Host Download Link: $Url
Start-Process -FilePath $Url Start-Process -FilePath $Url
} }
}
}
if ($Cmd) {
$winVersionId = $null
$winReleaseId = $null
$winEditionId = $null
$winLanguageId = $null
$winLanguageName = $null
$winLink = $null
$i = 0
$Selected = ""
if ($Win -eq "List") {
Write-Host "Please select a Windows Version (-Win):"
}
foreach($version in $WindowsVersions) {
if ($Win -eq "List") {
Write-Host " -" $version[0][0]
} elseif ($version[0][0] -match $Win) {
$Selected += $version[0][0]
$winVersionId = $i
break;
}
$i++
}
if ($winVersionId -eq $null) {
if ($Win -ne "List") {
Write-Host "Invalid Windows version provided."
Write-Host "Use '-Win List' for a list of available Windows versions."
}
exit 1
}
# Windows Version selection
$releases = Get-Windows-Releases $winVersionId
if ($Rel -eq "List") {
Write-Host "Please select a Windows Release (-Rel) for ${Selected} (or use 'Latest' for most recent):"
}
foreach ($release in $releases) {
if ($Rel -eq "List") {
Write-Host " -" $release.Release
} elseif (!$Rel -or $release.Release.StartsWith($Rel) -or $Rel -eq "Latest") {
if (!$Rel -and $Verbosity -ge 1) {
Write-Host "No release specified (-Rel). Defaulting to '$($release.Release)'."
}
$Selected += " " + $release.Release
$winReleaseId = $release.Index
break;
}
}
if ($winReleaseId -eq $null) {
if ($Rel -ne "List") {
Write-Host "Invalid Windows release provided."
Write-Host "Use '-Rel List' for a list of available $Selected releases or '-Rel Latest' for latest."
}
exit 1
}
# Windows Release selection => Populate Product Edition
$editions = Get-Windows-Editions $winVersionId $winReleaseId
if ($Ed -eq "List") {
Write-Host "Please select a Windows Edition (-Ed) for ${Selected}:"
}
foreach($edition in $editions) {
if ($Ed -eq "List") {
Write-Host " -" $edition.Edition
} elseif (!$Ed -or $edition.Edition -match $Ed) {
if (!$Ed -and $Verbosity -ge 1) {
Write-Host "No edition specified (-Ed). Defaulting to '$($edition.Edition)'."
}
$Selected += "," + $edition.Edition -replace "Windows [0-9\.]*", ""
$winEditionId = $edition.Id
break;
}
}
if ($winEditionId -eq $null) {
if ($Ed -ne "List") {
Write-Host "Invalid Windows edition provided."
Write-Host "Use '-Ed List' for a list of available editions or remove the -Ed parameter to use default."
}
exit 1
}
# Product Edition selection => Request and populate Languages
$languages = Get-Windows-Languages $winVersionId $winEditionId
if (!$languages) {
exit 3
}
if ($Lang -eq "List") {
Write-Host "Please select a Language (-Lang) for ${Selected}:"
}
$i = 0
foreach ($language in $languages) {
if ($Lang -eq "List") {
Write-Host " -" $language.Language
} elseif ((!$Lang -and $script:SelectedIndex -eq $i) -or ($Lang -and $language.Language -match $Lang)) {
if (!$Lang -and $Verbosity -ge 1) {
Write-Host "No language specified (-Lang). Defaulting to '$($language.Language)'."
}
$Selected += ", " + $language.Language
$winLanguageId = $language.Id
$winLanguageName = $language.Language
break;
}
$i++
}
if ($winLanguageId -eq $null -or $winLanguageName -eq $null) {
if ($Lang -ne "List") {
Write-Host "Invalid Windows language provided."
Write-Host "Use '-Lang List' for a list of available languages or remove the option to use system default."
}
exit 1
}
# Language selection => Request and populate Arch download links
$links = Get-Windows-Download-Links $winVersionId $winEditionId $winLanguageId $winLanguageName
if (!$links) {
exit 3
}
if ($Arch -eq "List") {
Write-Host "Please select an Architecture (-Arch) for ${Selected}:"
}
$i = 0
foreach ($link in $links) {
if ($Arch -eq "List") {
Write-Host " -" $link.Type
} elseif ((!$Arch -and $script:SelectedIndex -eq $i) -or ($Arch -and $link.Type -match $Arch)) {
if (!$Arch -and $Verbosity -ge 1) {
Write-Host "No architecture specified (-Arch). Defaulting to '$($link.Type)'."
}
$Selected += ", " + $link.Type
$winLink = $link
break;
}
$i++
}
if ($winLink -eq $null) {
if ($Arch -ne "List") {
Write-Host "Invalid Windows architecture provided."
Write-Host "Use '-Arch List' for a list of available architectures or remove the option to use system default."
}
exit 1
}
# Arch selection => Return selected download link
if ($GetUrl) {
Write-Host $winLink.Link
} else {
Write-Host "Selected: $Selected"
Process-Download-Link $winLink.Link
}
# Clean up & exit
exit $ExitCode
} }
# Form creation # Form creation
@@ -764,7 +970,7 @@ $Continue.add_click({
if ($links.Length -eq 0) { if ($links.Length -eq 0) {
break break
} }
$script:Arch = Add-Entry $Stage "Architecture" $links "Type" $script:Architecture = Add-Entry $Stage "Architecture" $links "Type"
if ($PipeName) { if ($PipeName) {
$XMLForm.Height += $dh / 2; $XMLForm.Height += $dh / 2;
$Margin = $Continue.Margin $Margin = $Continue.Margin
@@ -780,13 +986,13 @@ $Continue.add_click({
$Check.Content = Get-Translation($English[13]) $Check.Content = Get-Translation($English[13])
$Check.Visibility = "Visible" $Check.Visibility = "Visible"
} }
$Arch.SelectedIndex = $script:SelectedIndex $Architecture.SelectedIndex = $script:SelectedIndex
$Continue.Content = Get-Translation("Download") $Continue.Content = Get-Translation("Download")
$XMLForm.Title = $AppTitle $XMLForm.Title = $AppTitle
} }
5 { # Arch selection => Return selected download link 5 { # Arch selection => Return selected download link
Process-Download-Link $Arch.SelectedValue.Link Process-Download-Link $Architecture.SelectedValue.Link
$script:ExitCode = 0 $script:ExitCode = 0
$XMLForm.Close() $XMLForm.Close()
} }
@@ -837,8 +1043,8 @@ exit $ExitCode
# SIG # Begin signature block # SIG # Begin signature block
# MIIm3wYJKoZIhvcNAQcCoIIm0DCCJswCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # MIIm3wYJKoZIhvcNAQcCoIIm0DCCJswCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU5yzyhB7xB9Ie7S056ccu7PP0 # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU/L412YdnIqFymsnYAgDOGvme
# L2eggiCiMIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAw # DtKggiCiMIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAw
# TDEgMB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkds # TDEgMB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkds
# b2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcN # b2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcN
# MjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBS # MjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBS
@@ -1017,30 +1223,30 @@ exit $ExitCode
# T01PRE8gQ0EgTGltaXRlZDEjMCEGA1UEAxMaQ09NT0RPIFJTQSBDb2RlIFNpZ25p # T01PRE8gQ0EgTGltaXRlZDEjMCEGA1UEAxMaQ09NT0RPIFJTQSBDb2RlIFNpZ25p
# bmcgQ0ECECRpJmPvbAwKOyPPoxDDZJswCQYFKw4DAhoFAKB4MBgGCisGAQQBgjcC # bmcgQ0ECECRpJmPvbAwKOyPPoxDDZJswCQYFKw4DAhoFAKB4MBgGCisGAQQBgjcC
# AQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYB # AQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYB
# BAGCNwIBCzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYEFHSgabWDiKT0 # BAGCNwIBCzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYEFNjCGFk20sPC
# kFTQHrkkzG7GqWwHMA0GCSqGSIb3DQEBAQUABIIBAA94kPua+V1jjChd8NH7snaF # Cpi9ZluvDPRcbQNiMA0GCSqGSIb3DQEBAQUABIIBALeyMVfNZvv8ADrtW/SWGXi9
# /dgAG99AUxpguCkYcV8Pn+FCruH34XjYirRA4NowZAjXbHj+UmT9eYC0kAfvXLsn # 30lhtesUfS+9TWT9d6AIuv9ooJI2itDBwcPBHy4iV3gnIV+sEbJQN3319fcYP7Er
# BO+tfr6ffQa3lAVDUj+Ord/uPhPyV8FTfcXO48VlTK5aziKRUrZLyllpDMoihKEI # aUTU3MmGpFvNiuU5IUuMAVSGZz8fgwjHdifFLghBb6dELltlYdX23u/tz5S+o4RX
# xtxgPFj+8fOMmOzLw22IzcmOLOKIV010f/54aFjbF+OhddAtPeGcVipH6kfG/PLZ # 7LZrRa7eRcu3sAYAG6O4z1AnhzHg/Z68re0gGGC2zv4g9nQrPLsTNscaULChxcA9
# gZ4aUjuV8qTZtRZehSWx1tte8xvpBH3TKhlQn8mFB8EtGLNcen1EXeFrOSmNBBCx # dLrJwbIZuZCvWivy26HRzVUrxiY8nK4WDIErHDQ3jl36ycyIBb+hdl61PCWLDKPs
# z8GT5q+nkl5qWPhx5bSQ3j9uIXq1Y+xG5aqR2/YN7x1h3hI2GZcEdSOOTb9aOt6h # 0PUt5hI4IIKdL4CWGREz26vgaIZssZcTZdWZLX1xKwc54FhrSezJPwW2Ae8WC4yh
# ggNwMIIDbAYJKoZIhvcNAQkGMYIDXTCCA1kCAQEwbzBbMQswCQYDVQQGEwJCRTEZ # ggNwMIIDbAYJKoZIhvcNAQkGMYIDXTCCA1kCAQEwbzBbMQswCQYDVQQGEwJCRTEZ
# MBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTExMC8GA1UEAxMoR2xvYmFsU2lnbiBU # MBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTExMC8GA1UEAxMoR2xvYmFsU2lnbiBU
# aW1lc3RhbXBpbmcgQ0EgLSBTSEEzODQgLSBHNAIQAYTTqM43getX9P2He4OusjAN # aW1lc3RhbXBpbmcgQ0EgLSBTSEEzODQgLSBHNAIQAYTTqM43getX9P2He4OusjAN
# BglghkgBZQMEAgEFAKCCAT8wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkq # BglghkgBZQMEAgEFAKCCAT8wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkq
# hkiG9w0BCQUxDxcNMjEwODA2MjAzNzMxWjAtBgkqhkiG9w0BCTQxIDAeMA0GCWCG # hkiG9w0BCQUxDxcNMjEwODA3MjEzMDMxWjAtBgkqhkiG9w0BCTQxIDAeMA0GCWCG
# SAFlAwQCAQUAoQ0GCSqGSIb3DQEBCwUAMC8GCSqGSIb3DQEJBDEiBCBnBz20+9Eg # SAFlAwQCAQUAoQ0GCSqGSIb3DQEBCwUAMC8GCSqGSIb3DQEJBDEiBCCcvqCWuD80
# DNDIFUZ0tcrA3PX6vneV+vtEQoOI2axwyTCBpAYLKoZIhvcNAQkQAgwxgZQwgZEw # KNl9ZWmLr4VnwtUXdbgMURXSuFa/UXlNfDCBpAYLKoZIhvcNAQkQAgwxgZQwgZEw
# gY4wgYsEFN1XtbOHPIYbKcauxHMa++iNdcFJMHMwX6RdMFsxCzAJBgNVBAYTAkJF # gY4wgYsEFN1XtbOHPIYbKcauxHMa++iNdcFJMHMwX6RdMFsxCzAJBgNVBAYTAkJF
# MRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTEwLwYDVQQDEyhHbG9iYWxTaWdu # MRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTEwLwYDVQQDEyhHbG9iYWxTaWdu
# IFRpbWVzdGFtcGluZyBDQSAtIFNIQTM4NCAtIEc0AhABhNOozjeB61f0/Yd7g66y # IFRpbWVzdGFtcGluZyBDQSAtIFNIQTM4NCAtIEc0AhABhNOozjeB61f0/Yd7g66y
# MA0GCSqGSIb3DQEBCwUABIIBgKdqzuxRLglJlYPDrqXGviBKqWpb8N8B5qHyGGdI # MA0GCSqGSIb3DQEBCwUABIIBgL0I1stv/LKS2eWaUOkrWDchIY1XL2wQQLyu+F/w
# 1dHsIumXeGQt2+Ua978LtRisI1LHy3yNWYQQ/OkviTDAM0L2Q4cEBxiyBmzbQQi+ # 43dFR16c1rzL2SwyiQx85whTxivm24WJQFWyAtEFUqrXfboL0WW6RoFtgIKi0PEX
# HlcTe/yw8zU4R3t2vzx4qAEpBcaex33pel6pflJ34s9b3+npfalgsKDDPcJ1ACFR # ecpdrD2ECiGnGnVrgHMoyB0t7m9WzwItEpGMgmiLfqWP63tv3/foVFC5/0rn0D65
# Z9jhFki5BieV75MmvliVXM+Kxs5qBn3zqOSJoEhejbCfQcaP6XnVDdrMyYuZnCXA # EOm5BEgOvsvJgPb+RtFHgzPGU7Srj+OqJmiRjxy+CzZee3hKHCWzwB09jd0XhVCT
# iPnzAQUMiKraO+uKx1ivK7v4n7sjAG0Is5izoneIVclBd+fII7k6hOSRGH3WivP4 # hb1ycICO3lKkiTFtXXh02o35jm7YQaC53ibMnCeWrIyHfx/PNWFFKARpLMndwrkY
# UND1Z8+HVCStyA+EE6VfioIbc3xnaOPMpMwBl21xELZm4L7EYyEZqFccKNB0LxWJ # cVZDLmMOKYKdyD9nUWNZ/hDCJOh856e0xJNJ0Ov39Edl8SF6P4ghR3nYQqN5zbWV
# l1y1dE8uewm8Xii+3OiDkp9bFpVc0eBgzpZ3M4SdGSN51DmunRmfToXC9840hZ5b # y2Ee6Aaifjej/M9/UoqNJELXtojy+YWUVmK0CFAAGEzyar2o5n4/dPaeu0f+7/AV
# dOp5iOKonlTGzkdvFR1P8x2m7DAmoB+jX83MBPLA5EoZdiAOZR+fG6c4/qz/wsyw # 5H+HdRMoxmllQrmSVY9A7Bz/xlE4qxchhxfUP+kEbs6uz0AqpDVQj9B2fwFDYLs0
# Nw6mR724FE4VFOaE4QVh6a+mKQ== # Kzy+fokB/NwBSYEWoRMPc8oRSg==
# SIG # End signature block # SIG # End signature block

View File

@@ -65,6 +65,43 @@ of Windows 7).
Note that the current version of the script does not need Internet Explorer to be installed and should also work with Note that the current version of the script does not need Internet Explorer to be installed and should also work with
PowerShell 7. PowerShell 7.
Commandline mode
----------------
Fido supports commandline mode whereas, whenever one of the following options is provided, a GUI is not instantiated
and you can instead generate the ISO download from within a PowerShell console or script.
The options are:
- `Win`: Specify Windows version (e.g. _"Windows 10"_). Abbreviated version should work as well (e.g `-Win 10`) as long
as it is unique enough. If this option isn't specified, the most recent version of Windows is automatically selected.
You can obtain a list of supported versions by specifying `-Win List`.
- `Rel`: Specify Windows release (e.g. _"21H1"_). If this option isn't specified, the most recent release for the chosen
version of Windows is automatically selected. You can also use `-Rel Latest` to force the most recent to be used.
You can obtain a list of supported versions by specifying `-Rel List`.
- `Ed`: Specify Windows edition (e.g. _"Pro/Home"_). Abbreviated editions should work as well (e.g `-Ed Pro`) as long
as it is unique enough. If this option isn't specified, the most recent version of Windows is automatically selected.
You can obtain a list of supported versions by specifying `-Ed List`.
- `Lang`: Specify Windows language (e.g. _"Arabic"_). Abbreviated or part of a language (e.g. `-Lang Int` for
`English International` should work as long as it's unique enough. If this option isn't specified, the script attempts
to select the same language as the system locale.
You can obtain a list of supported languages by specifying `-Lang List`.
- `Arch`: Specify Windows architecture (e.g. _"x64"_). If this option isn't specified, the script attempts to use the same
architecture as the one from the current system.
- `GetUrl`: By default, the script attempts to automatically launch the download. But when using the `-GetUrl` switch,
the script only displays the download URL, which can then be piped into another command or into a file.
Examples of a commandline download:
```
PS C:\Projects\Fido> .\Fido.ps1 -Win 10 -Rel Latest
No edition specified (-Ed). Defaulting to 'Windows 10 Home/Pro'.
No language specified (-Lang). Defaulting to 'English International'.
No architecture specified (-Arch). Defaulting to 'x64'.
Downloading 'Win10_21H1_EnglishInternational_x64.iso'...
PS C:\Projects\Fido> .\Fido.ps1 -Win 10 -Rel 20H2 -Ed Edu -Lang Fre -Arch x86 -GetUrl
https://software-download.microsoft.com/db/Win10_Edu_20H2_French_x32.iso?t=fb914101-aaaa-4e0d-b686-e187a205e202&e=1628437094&h=8a2e25a6346e630c817cdca9fadbe588
```
Additional Notes Additional Notes
---------------- ----------------