mirror of
https://github.com/pbatard/Fido.git
synced 2025-09-16 14:18:02 +02:00
Add Commandline support
* Also fix a regression introduced by previous commit * Closes #15 * Closes #24
This commit is contained in:
296
Fido.ps1
296
Fido.ps1
@@ -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) {
|
||||||
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
|
Write-Host Please Wait...
|
||||||
} else {
|
if ($host.version -ge "7.0") {
|
||||||
Add-Type -MemberDefinition $code -Namespace Gui -UsingNamespace System.IO, System.Text, System.Drawing, System.Globalization -ReferencedAssemblies System.Drawing -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 {
|
||||||
|
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
|
||||||
$XMLForm.Title = $(Get-Translation("Error")) + ": " + $ErrorMessage
|
if (!$Cmd) {
|
||||||
Refresh-Control($XMLForm)
|
$XMLForm.Title = $(Get-Translation("Error")) + ": " + $ErrorMessage
|
||||||
$XMLGrid.Children[2 * $script:Stage + 1].IsEnabled = $True
|
Refresh-Control($XMLForm)
|
||||||
$UserInput = [System.Windows.MessageBox]::Show($XMLForm.Title, $(Get-Translation("Error")), "OK", "Error")
|
$XMLGrid.Children[2 * $script:Stage + 1].IsEnabled = $True
|
||||||
$script:ExitCode = $script:Stage--
|
$UserInput = [System.Windows.MessageBox]::Show($XMLForm.Title, $(Get-Translation("Error")), "OK", "Error")
|
||||||
|
$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/"
|
||||||
Write-Host Querying $url
|
if (!$Cmd -or $Verbose) {
|
||||||
|
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"
|
||||||
Write-Host Querying $url
|
if (!$Cmd -or $Verbose) {
|
||||||
|
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"
|
||||||
Write-Host Querying $url
|
if (!$Cmd -or $Verbose) {
|
||||||
|
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
|
||||||
@@ -688,11 +733,172 @@ 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 {
|
} else {
|
||||||
Write-Host Download Link: $Url
|
if ($Cmd) {
|
||||||
Start-Process -FilePath $Url
|
$pattern = '.*\/(.*\.iso).*'
|
||||||
|
$File = [regex]::Match($Url, $pattern).Groups[1].Value
|
||||||
|
Write-Host "Downloading '$File'..."
|
||||||
|
Invoke-WebRequest -UseBasicParsing -Uri $Url -OutFile $File
|
||||||
|
} else {
|
||||||
|
Write-Host Download Link: $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
|
||||||
$XMLForm = [Windows.Markup.XamlReader]::Load((New-Object System.Xml.XmlNodeReader $XAML))
|
$XMLForm = [Windows.Markup.XamlReader]::Load((New-Object System.Xml.XmlNodeReader $XAML))
|
||||||
$XAML.SelectNodes("//*[@Name]") | ForEach-Object { Set-Variable -Name ($_.Name) -Value $XMLForm.FindName($_.Name) -Scope Script }
|
$XAML.SelectNodes("//*[@Name]") | ForEach-Object { Set-Variable -Name ($_.Name) -Value $XMLForm.FindName($_.Name) -Scope Script }
|
||||||
@@ -702,7 +908,7 @@ if ($Icon) {
|
|||||||
} else {
|
} else {
|
||||||
$XMLForm.Icon = [Gui.Utils]::ExtractIcon("shell32.dll", -41, $true) | ConvertTo-ImageSource
|
$XMLForm.Icon = [Gui.Utils]::ExtractIcon("shell32.dll", -41, $true) | ConvertTo-ImageSource
|
||||||
}
|
}
|
||||||
if ($Locale.StartsWith("ar") -or $Locale.StartsWith("fa") -or $Locale.StartsWith("he")) {
|
if ($Locale.StartsWith("ar") -or $Locale.StartsWith("fa") -or $Locale.StartsWith("he")) {
|
||||||
$XMLForm.FlowDirection = "RightToLeft"
|
$XMLForm.FlowDirection = "RightToLeft"
|
||||||
}
|
}
|
||||||
$WindowsVersionTitle.Text = Get-Translation("Version")
|
$WindowsVersionTitle.Text = Get-Translation("Version")
|
||||||
@@ -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
|
||||||
|
37
README.md
37
README.md
@@ -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
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user