mirror of
https://github.com/pbatard/Fido.git
synced 2025-09-16 22:28:02 +02:00
Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
99f6f246b8 | ||
![]() |
36e9b4420c | ||
![]() |
6d630f83f2 | ||
![]() |
ee0393cb74 | ||
![]() |
a8abb94a16 | ||
![]() |
15a48fe24f | ||
![]() |
e0c1015ade | ||
![]() |
46c399ecd7 | ||
![]() |
445ca5c074 | ||
![]() |
037cd1ad9b |
8
.whitesource
Normal file
8
.whitesource
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"checkRunSettings": {
|
||||
"vulnerableCheckRunConclusionLevel": "failure"
|
||||
},
|
||||
"issueSettings": {
|
||||
"minSeverityLevel": "LOW"
|
||||
}
|
||||
}
|
111
Fido.ps1
111
Fido.ps1
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# Fido v1.15 - Retail Windows ISO Downloader
|
||||
# Copyright © 2019 Pete Batard <pete@akeo.ie>
|
||||
# Fido v1.19 - Retail Windows ISO Downloader
|
||||
# Copyright © 2019-2021 Pete Batard <pete@akeo.ie>
|
||||
# ConvertTo-ImageSource: Copyright © 2016 Chris Carter
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
@@ -30,11 +30,7 @@ param(
|
||||
[string]$Icon,
|
||||
# (Optional) Name of a pipe the download URL should be sent to.
|
||||
# If not provided, a browser window is opened instead.
|
||||
[string]$PipeName,
|
||||
# (Optional) Disable IE First Run Customize so that Invoke-WebRequest
|
||||
# doesn't throw an exception if the user has never launched IE.
|
||||
# Note that this requires the script to run elevated.
|
||||
[switch]$DisableFirstRunCustomize
|
||||
[string]$PipeName
|
||||
)
|
||||
#endregion
|
||||
|
||||
@@ -63,7 +59,11 @@ $code = @"
|
||||
}
|
||||
"@
|
||||
|
||||
Add-Type -MemberDefinition $code -Namespace Gui -UsingNamespace "System.IO", "System.Text", "System.Drawing", "System.Globalization" -ReferencedAssemblies System.Drawing -Name Utils -ErrorAction Stop
|
||||
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
|
||||
} 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
|
||||
@@ -75,6 +75,30 @@ $ko = 0x20000
|
||||
$WindowsVersions = @(
|
||||
@(
|
||||
@("Windows 10", "Windows10ISO"),
|
||||
@(
|
||||
"21H1 (Build 19043.985 - 2021.05)",
|
||||
@("Windows 10 Home/Pro", 2033),
|
||||
@("Windows 10 Education", 2032),
|
||||
@("Windows 10 Home China ", ($zh + 2034))
|
||||
),
|
||||
@(
|
||||
"20H2 (Build 19042.631 - 2020.12)",
|
||||
@("Windows 10 Home/Pro", 1882),
|
||||
@("Windows 10 Education", 1884),
|
||||
@("Windows 10 Home China ", ($zh + 1883))
|
||||
),
|
||||
@(
|
||||
"20H2 (Build 19042.508 - 2020.10)",
|
||||
@("Windows 10 Home/Pro", 1807),
|
||||
@("Windows 10 Education", 1805),
|
||||
@("Windows 10 Home China ", ($zh + 1806))
|
||||
),
|
||||
@(
|
||||
"20H1 (Build 19041.264 - 2020.05)",
|
||||
@("Windows 10 Home/Pro", 1626),
|
||||
@("Windows 10 Education", 1625),
|
||||
@("Windows 10 Home China ", ($zh + 1627))
|
||||
),
|
||||
@(
|
||||
"19H2 (Build 18363.418 - 2019.11)",
|
||||
@("Windows 10 Home/Pro", 1429),
|
||||
@@ -210,10 +234,10 @@ function Select-Language([string]$LangName)
|
||||
($SysLocale.StartsWith("da") -and $LangName -like "*Danish*") -or `
|
||||
($SysLocale.StartsWith("nl") -and $LangName -like "*Dutch*") -or `
|
||||
($SysLocale -eq "en-US" -and $LangName -eq "English") -or `
|
||||
($SysLocale.StartsWith("en") -and $LangName -like "*English*" -and $LangName -like "*inter*") -or `
|
||||
($SysLocale.StartsWith("en") -and $LangName -like "*English*" -and ($LangName -like "*inter*" -or $LangName -like "*ingdom*")) -or `
|
||||
($SysLocale.StartsWith("et") -and $LangName -like "*Eston*") -or `
|
||||
($SysLocale.StartsWith("fi") -and $LangName -like "*Finn*") -or `
|
||||
($SysLocale -eq "fr-CA" -and $LangName -like "*French*" -and $LangName -like "*Canad*") -or `
|
||||
($SysLocale -eq "fr-CA" -and $LangName -like "*French*" -and $LangName -like "*Canad*") -or `
|
||||
($SysLocale.StartsWith("fr") -and $LangName -eq "French") -or `
|
||||
($SysLocale.StartsWith("de") -and $LangName -like "*German*") -or `
|
||||
($SysLocale.StartsWith("el") -and $LangName -like "*Greek*") -or `
|
||||
@@ -385,12 +409,9 @@ function Error([string]$ErrorMessage)
|
||||
Write-Host Error: $ErrorMessage
|
||||
$XMLForm.Title = $(Get-Translation("Error")) + ": " + $ErrorMessage
|
||||
Refresh-Control($XMLForm)
|
||||
$Continue.Content = Get-Translation("Close")
|
||||
Refresh-Control($Continue)
|
||||
$XMLGrid.Children[2 * $script:Stage + 1].IsEnabled = $True
|
||||
$UserInput = [System.Windows.MessageBox]::Show($XMLForm.Title, $(Get-Translation("Error")), "OK", "Error")
|
||||
$script:ExitCode = $Stage
|
||||
$script:Stage = -1
|
||||
$Continue.IsEnabled = $True
|
||||
$script:ExitCode = $script:Stage--
|
||||
}
|
||||
|
||||
function Get-RandomDate()
|
||||
@@ -428,14 +449,11 @@ $MaxStage = 4
|
||||
$SessionId = [guid]::NewGuid()
|
||||
$ExitCode = 100
|
||||
$Locale = "en-US"
|
||||
$DFRCKey = "HKLM:\Software\Policies\Microsoft\Internet Explorer\Main\"
|
||||
$DFRCName = "DisableFirstRunCustomize"
|
||||
$DFRCAdded = $False
|
||||
$RequestData = @{}
|
||||
$RequestData["GetLangs"] = @("a8f8f489-4c7f-463a-9ca6-5cff94d8d041", "getskuinformationbyproductedition" )
|
||||
$RequestData["GetLinks"] = @("cfa9e580-a81e-4a4b-a846-7b21bf4e2e5b", "GetProductDownloadLinksBySku" )
|
||||
# Create a semi-random Linux User-Agent string
|
||||
$FirefoxVersion = Get-Random -Minimum 30 -Maximum 60
|
||||
$FirefoxVersion = Get-Random -Minimum 50 -Maximum 90
|
||||
$FirefoxDate = Get-RandomDate
|
||||
$UserAgent = "Mozilla/5.0 (X11; Linux i586; rv:$FirefoxVersion.0) Gecko/$FirefoxDate Firefox/$FirefoxVersion.0"
|
||||
#endregion
|
||||
@@ -466,20 +484,6 @@ if ($PSVersionTable.PSVersion.Major -lt 3) {
|
||||
exit 102
|
||||
}
|
||||
|
||||
# If asked, disable IE's first run customize prompt as it interferes with Invoke-WebRequest
|
||||
if ($DisableFirstRunCustomize) {
|
||||
try {
|
||||
# Only create the key if it doesn't already exist
|
||||
Get-ItemProperty -Path $DFRCKey -Name $DFRCName
|
||||
} catch {
|
||||
if (-not (Test-Path $DFRCKey)) {
|
||||
New-Item -Path $DFRCKey -Force | Out-Null
|
||||
}
|
||||
Set-ItemProperty -Path $DFRCKey -Name $DFRCName -Value 1
|
||||
$DFRCAdded = $True
|
||||
}
|
||||
}
|
||||
|
||||
# Form creation
|
||||
$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 }
|
||||
@@ -508,11 +512,7 @@ $WindowsVersion.DisplayMemberPath = "Version"
|
||||
|
||||
# Button Action
|
||||
$Continue.add_click({
|
||||
if ($script:Stage++ -lt 0) {
|
||||
Get-Process -Id $pid | Foreach-Object { $_.CloseMainWindow() | Out-Null }
|
||||
return
|
||||
}
|
||||
|
||||
$script:Stage++
|
||||
$XMLGrid.Children[2 * $Stage + 1].IsEnabled = $False
|
||||
$Continue.IsEnabled = $False
|
||||
$Back.IsEnabled = $False
|
||||
@@ -577,14 +577,11 @@ $Continue.add_click({
|
||||
$i = 0
|
||||
$SelectedIndex = 0
|
||||
try {
|
||||
$r = Invoke-WebRequest -UserAgent $UserAgent -WebSession $Session $url
|
||||
$r = Invoke-WebRequest -UseBasicParsing -UserAgent $UserAgent -SessionVariable "Session" $url
|
||||
$pattern = '(?s)<select id="product-languages">(.*)?</select>'
|
||||
$html = [regex]::Match($r, $pattern).Groups[1].Value
|
||||
# Go through an XML conversion to keep all PowerShells happy...
|
||||
if (-not $($r.AllElements | ? {$_.id -eq "product-languages"})) {
|
||||
throw "Unexpected server response"
|
||||
}
|
||||
$html = $($r.AllElements | ? {$_.id -eq "product-languages"}).InnerHTML
|
||||
$html = $html.Replace("selected value", "value")
|
||||
$html = $html.Replace("&", "&")
|
||||
$html = "<options>" + $html + "</options>"
|
||||
$xml = [xml]$html
|
||||
foreach ($var in $xml.options.option) {
|
||||
@@ -602,7 +599,7 @@ $Continue.add_click({
|
||||
}
|
||||
} catch {
|
||||
Error($_.Exception.Message)
|
||||
return
|
||||
break
|
||||
}
|
||||
$script:Language = Add-Entry $Stage "Language" $array "DisplayLanguage"
|
||||
$Language.SelectedIndex = $SelectedIndex
|
||||
@@ -628,18 +625,15 @@ $Continue.add_click({
|
||||
$array = @()
|
||||
try {
|
||||
$Is64 = [Environment]::Is64BitOperatingSystem
|
||||
$r = Invoke-WebRequest -UserAgent $UserAgent -WebSession $Session $url
|
||||
if (-not $($r.AllElements | ? {$_.id -eq "expiration-time"})) {
|
||||
Throw-Error -Req $r -Alt Get-Translation($English[14])
|
||||
}
|
||||
$html = $($r.AllElements | ? {$_.tagname -eq "input"}).outerHTML
|
||||
$r = Invoke-WebRequest -UseBasicParsing -UserAgent $UserAgent -WebSession $Session $url
|
||||
$pattern = '(?s)(<input.*?/>)'
|
||||
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
|
||||
$html = $html.Replace("class=product-download-hidden", "")
|
||||
$html = $html.Replace("type=hidden", "")
|
||||
$html = $html.Replace(">", "/>")
|
||||
$html = $html.Replace(" ", " ")
|
||||
$html = $html.Replace("IsoX86", """x86""")
|
||||
$html = $html.Replace("IsoX64", """x64""")
|
||||
$html = $html.Replace("IsoX86", ""x86"")
|
||||
$html = $html.Replace("IsoX64", ""x64"")
|
||||
$html = "<inputs>" + $html + "</inputs>"
|
||||
$xml = [xml]$html
|
||||
foreach ($var in $xml.inputs.input) {
|
||||
@@ -657,7 +651,7 @@ $Continue.add_click({
|
||||
}
|
||||
} catch {
|
||||
Error($_.Exception.Message)
|
||||
return
|
||||
break
|
||||
}
|
||||
|
||||
$script:Arch = Add-Entry $Stage "Architecture" $array "Type"
|
||||
@@ -694,7 +688,7 @@ $Continue.add_click({
|
||||
}
|
||||
$Continue.IsEnabled = $True
|
||||
if ($Stage -ge 0) {
|
||||
$Back.IsEnabled = $True;
|
||||
$Back.IsEnabled = $True
|
||||
}
|
||||
})
|
||||
|
||||
@@ -718,10 +712,12 @@ $Back.add_click({
|
||||
$Margin.Top -= $dh2
|
||||
$Back.Margin = $Margin
|
||||
$script:Stage = $Stage - 1
|
||||
$XMLForm.Title = $AppTitle
|
||||
if ($Stage -eq 0) {
|
||||
$Back.Content = Get-Translation("Close")
|
||||
} elseif ($Stage -eq 3) {
|
||||
} else {
|
||||
$Continue.Content = Get-Translation("Continue")
|
||||
Refresh-Control($Continue)
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -731,7 +727,4 @@ $XMLForm.Add_Loaded( { $XMLForm.Activate() } )
|
||||
$XMLForm.ShowDialog() | Out-Null
|
||||
|
||||
# Clean up & exit
|
||||
if ($DFRCAdded) {
|
||||
Remove-ItemProperty -Path $DFRCKey -Name $DFRCName
|
||||
}
|
||||
exit $ExitCode
|
||||
|
11
README.md
11
README.md
@@ -58,17 +58,12 @@ for all the architectures available for that specific combination of version + l
|
||||
Requirements
|
||||
------------
|
||||
|
||||
PowerShell 3.0 or later is required. However the script will detect if you are using an older version and point you to
|
||||
PowerShell 3.0 or later is required. However the script should detect if you are using an older version and point you to
|
||||
the relevant PowerShell 3.0 download page if needed (which should only ever occur if you are running a vanilla version
|
||||
of Windows 7).
|
||||
|
||||
Also, because Internet Explorer is being invoked behind the scenes, if you haven't gone through the first time setup for
|
||||
Internet Explorer, you may receive an error about this when running the script. If that is the case, then you should
|
||||
make sure that you manually launch IE at least once and complete the setup.
|
||||
|
||||
Note however that, if you are running the script elevated, you can work around the above annoyance by using the
|
||||
`-DisableFirstRunCustomize` option which basically __temporarily__ creates a key of the same name in the registry __if__
|
||||
it doesn't already exist, to bypass the first time setup error.
|
||||
Note that the current version of the script does not need Internet Explorer to be installed and should also work with
|
||||
PowerShell 7.
|
||||
|
||||
Additional Notes
|
||||
----------------
|
||||
|
Reference in New Issue
Block a user