Trying to download a zip file from a weblink with powershell - powershell

Ok, I am trying to download a file off of a web link that we use with powershell. I am downloading a zip file where the begining of the name is always the same, but the the middle part will change based off of the version number of the zip. I have been able to get the file to download when I use the fully qualified web address and have the file name hard coded into the script. I have tried every version of using the wild cards to get all the most common version of the zip, but it errors out saying that it can't find the file on there server. This is the code that I have already, and any help would be greatly appreciated since I feel like I am at a wall with it.
$url = 'http://blah/blah/blah/My File Name 11.1111.11.zip'
$localFileName = 'C:\temp\MYzip.zip'
Invoke-WebRequest $url -UseDefaultCredentials -OutFile $localFileName

If the site has directory browsing enabled (unlikely unless you have control of the site and can turn it on), you can do this:
$url = 'http://blah/blah/blah/'
$wr = iwr $url
$filename = $wr.Links.href | Where {$_ -match 'My File Name.*?\.zip'}
$wr = iwr "$url/$filename"
If the site doesn't have directory browsing enabled then surely it has a page with a link to the ZIP file on it. Download that page and use the same $wr.Links.href trick to get all the links and look for the one that matches "My File Name.*?.zip".

Related

PowerShell, Invoke-WebRequest for a url that is not pointing at a file, but initiates a file download

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?
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])"
}
}
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."

Downloading a file using PowerShell - Redirected

I have a URL that sends me to a "preparing your download" page, and then triggers a file download.
I need to be able to use PowerShell to script the download of the generated file.
This surely must be possible, but I have no idea how to achieve it.
There is a button that appears once the file is generated "Try again", perhaps it is possible to use that link to download the file, or is there some other way to achieve this?
I found this elsewhere and tried to use it, but it produces an error.
Code:
$destination = "C:\Temp\TeamViewer.exe"
$source=Invoke-WebRequest https://get.teamviewer.com/6******** -MaximumRedirection 0
$sourceadw = $source.Links | where {$_.innerText -eq "Try again"} | select -expand href
Invoke-WebRequest $sourceadw -OutFile $destination
Error:
ErrorImage
Any help would be greatly appreciated! :)

Powershell download to specific folder without knowing file name

I'm creating a Powershell script to download the latest version of a bunch of utilities. For some I know the URL and file name so this works:
$url = "https://download.sysinternals.com/files/SysinternalsSuite.zip"
$file = "SysinternalsSuite.zip"
$webclient.DownloadFile("$url","$storageDir\$file")
For some I just know the URL. For these I just know how to open it in the browser and file file is downloaded to the browsers download location.
$url = "https://toolslib.net/downloads/finish/1-adwcleaner/"
Start-Process "chrome.exe" "$url"
Is there any way to find the name of the file that was downloaded so it can be moved to $storageDir?
Alternately, is there a way to temporarily change a browsers default download location from inside the script and change it back at the end of the script? I'm not locked to any specific browser?

Powershell download file from redirecting url - TeamViewer & Intune

Thank you in advance for anyone taking a look into this.
I'm currently trying to deploy TeamViewer via Intune that only support MSI files for deployment. However, TeamViewer has a feature called account assignment which it comes in form of an executable. Since Intune doesn't allow you deploy exe files, please correct me if I'm wrong. I have resulted in using a PowerShell script that will download the necessary files and then install.
My goal is to have the files stored in the cloud like onedrive or Dropbox. The problem there is the public link doesn't point to the file directly as its a redirect.
For example https://www.dropbox.com/x/xyzd/TeamViewer_Assignment.exe?dl=0 --> https://www.dropbox.com/x/xyzd/TeamViewer_Assignment.exe
or
https://1drv.ms/u/s!Avjfi0upMYg9haNVTMpdoPGdstex --> https://1drv.ms/u/s/teamviewer.exe
if both links were to end with the file extension (.exe), then it would be no problem. But I would like to use Teamviewer links (get.teamviewer.com/myhost redirects https://download.teamviewer.com/u/id12345/TeamViewer.exe hoping this will help a lot more people. As opposed to having a cloud storage account.
https://download.teamviewer.com/u/id12345/TeamViewer.exe is not a permanent link either, and it has an expiration time.
Things I've tried:
$url = "https://get.teamviewer.com/mycustomhost"
$output = "$PSScriptRoot\myhost.exe"
$start_time = Get-Date
Invoke-WebRequest -Uri $url -OutFile $output
Write-Output "Time taken: $((Get-Date).Subtract($start_time).Seconds)
second(s)"
$url = "http://get.teamviewer.com/myhost"
$output = "$PSScriptRoot\myhost.exe"
$start_time = Get-Date
$wc = New-Object System.Net.WebClient
$wc.DownloadFile($url, $output)
#OR
(New-Object System.Net.WebClient).DownloadFile($url, $output)
Write-Output "Time taken: $((Get-Date).Subtract($start_time).Seconds)
second(s)"
$rep=Invoke-WebRequest
http://www.get.teamviewer.com/myhost -MaximumRedirection
0
$rep.Links | where {$_.innerText -eq "click here"} |select -expand href
None of those examples worked I tried other combination from bits and pieces over the net but no go.
You can use the following URI for all of your examples:
https://customdesign.teamviewer.com/download/version_12x/myhost/TeamViewerQS.exe
You can get this URI for your download in Chrome in the following way:
Download TeamViewer
Open the Download History
Right click the entry for the TeamViewer download and copy the download URI.
Edit:
You can parse the download site for the real link with the following command:
$downloadPage = Invoke-WebRequest -Uri https://get.teamviewer.com/myhost
$downloadLink = $request.ParsedHtml.getElementById('MasterBodyContent_btnRetry').href
Now you can use the '$downloadLink' variable to download the executable with any of your scripts. You may have to change this if the download page for TeamViewer changes.
Just search for the id of the 'Try again' button on the download page. Then you can edit my code to get the appropriate element and attribute.

Powershell invoke-webrequest downloading HTML not actual file

I am trying to download a google spreadsheet via an invoke-webrequestin powershell.
My link looks something like this and I can confirm that if I go to the link it prompts me to download the file I want...
$url = https://docs.google.com/spreadsheets/d/XXXXXXXXXXXXXXXX/export?format=csv
I have tried downloading the file via 2 ways:
Invoke-WebRequest $url -OutFile $saveLocation
(New-Object System.Net.WebClient).DownloadFile($url, $saveLocation)
Both of these just download the HTML for the page, and not the actual file.
The spreadsheet I am downloading is 100% public so it is not like I need to be logged into a google account to view it.
I made the test and I can quite safely say that your file is not public.
I have reproduced your issue before making my test sheet public, and I could not afterwards.
Tested with this :
$url = "https://docs.google.com/spreadsheets/d/1OOc5aiG3hh8mrGF4p7NJXKI8KqBSkS2ZjsBXtb4qpz8/export?format=csv"
Invoke-WebRequest $url -OutFile "C:\test.csv"