I can download the Google Chrome installer easily as follows:
Invoke-WebRequest "http://dl.google.com/chrome/install/latest/chrome_installer.exe" -OutFile "$env:Temp\chrome_installer.exe"
However, for Opera, I want specifically the latest 64-bit version. On the download page at https://www.opera.com/download
there is a handy link to that:
https://download.opera.com/download/get/?partner=www&opsys=Windows&arch=x64
When I click on the "64 bit" link, it automatically starts the download of the latest executable, but using Invoke-WebRequest
on that url does not download the file:
Invoke-WebRequest "https://download.opera.com/download/get/?partner=www&opsys=Windows&arch=x64" -OutFile "$env:Temp\opera_installer.exe"
How can I manipulate a url like this to:
- Download the file as if I clicked on the link on the download page?
- Get the name of the file that is downloaded (as I see that the full file version is in the file downloaded)?
- Redirect that download to a destination of my choosing?
CodePudding user response:
To access the installers you could use the following URI:
https://get.opera.com/pub/opera/desktop/
Depending on the version you want you can do:
Invoke-WebRequest "https://get.opera.com/pub/opera/desktop/92.0.4561.43/win/Opera_92.0.4561.43_Setup_x64.exe" -OutFile "$env:Temp\opera_installer.exe"
Working with link mentioned above you could do something like this:
#Set source URI
$uri = "https://get.opera.com/pub/opera/desktop/"
#As the links are sorted by version the last link is the newest version
(Invoke-WebRequest -uri $uri).links[-1] | %{
#Parse string to link and as we want the Windows version add 'win/', filter for 'Setup_x64\.exe$'
$uri = [Uri]::new([Uri]$uri, $_.href).AbsoluteUri 'win/'
(Invoke-WebRequest $uri).links | ?{$_.href -match 'Setup_x64\.exe$'} | %{
#Build new Uri, download file and write it to disk
$uri = [Uri]::new([Uri]$uri, $_.href)
Invoke-WebRequest -Uri $uri -OutFile "C:\tmp\$($uri.Segments[-1])"
}
}
CodePudding user response:
It looks like the download URL you found isn't just a chain of straight redirects but involves a JavaScript file that dynamically builds the ultimate target URL, so Invoke-WebRequest
cannot be used with it.
However, building on Toni's helpful answer, you can do some - simple - web scraping to determine the latest version number and to derive the download URL from it:
$VerbosePreference = 'Continue'
$downloadRootUrl = 'https://get.opera.com/pub/opera/desktop/'
$downloadTargetFile = 'Opera_Setup.exe'
# Get the version listing and match the *last* <a> element's href attribute,
# assumed to contain the latest version number.
Write-Verbose "Determining latest version via $downloadRootUrl..."
if ((Invoke-RestMethod $downloadRootUrl) -notmatch '(?s)^. <a href="([^/"] ). $') {
throw "Could not determine latest version."
}
# Extract the version number, via the automatic $Matches variable.
$latestVersion = $Matches[1]
# Construct the full download URI based on the version number.
$downloadUrl = $downloadRootUrl ('{0}/win/Opera_{0}_Setup_x64.exe' -f $latestVersion)
Write-Verbose "Downloading installer from $downloadUrl..."
& {
# Temporarily silence the progress stream, because in Windows PowerShell
# its display slows things down significantly.
$ProgressPreference = 'SilentlyContinue'
try {
Invoke-RestMethod -ErrorAction Stop -OutFile $downloadTargetFile $downloadUrl
} catch {
throw $_
}
}
Write-Verbose "Installer for version $latestVersion successfully downloaded to $downloadTargetFile."