Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I download a protected file using PowerShell?

I am trying to download a file using PowerShell 3.0 from my TeamCity build server. I have configured TeamCity to use NTLM authentication but I cannot download the file directly and get redirected to login.

I am trying to use the following PowerShell code to download the file.

$artifacts = "http://teamcity/repository/download/bt1/.lastSuccessful/%7Bbuild.number%7D.zip"
Invoke-WebRequest -Uri $artifacts -UseDefaultCredentials

My response from the request is a redirection to the login page.

like image 363
Aaron Weiker Avatar asked Jan 09 '13 16:01

Aaron Weiker


People also ask

How do you unlock a file in PowerShell?

The Unblock-File cmdlet lets you open files that were downloaded from the internet. It unblocks PowerShell script files that were downloaded from the internet so you can run them, even when the PowerShell execution policy is RemoteSigned. By default, these files are blocked to protect the computer from untrusted files.

Can PowerShell download files from a URL?

PowerShell can download files from the Internet and your local network to your computer. Learn how to use PowerShell's Invoke-WebRequest and Start-BitsTransfer cmdlets to download files here.

How do I download a package from PowerShell?

The Install-Package cmdlet installs a software package and its dependencies. Install-Package uses parameters to specify the packages Name and Source. The Credential parameter uses a domain user account with permissions to install packages. The command prompts you for the user account password.


1 Answers

Here is the code for the final solution.


$artifacts = "http://teamcity/repository/download/bt1/.lastSuccessful/%7Bbuild.number%7D.zip"
$login = "http://teamcity/ntlmLogin.html"
$dest = "Artifacts.zip"

$TeamCitySession = New-Object Microsoft.PowerShell.Commands.WebRequestSession
Invoke-WebRequest -Uri $login -WebSession $TeamCitySession -UseDefaultCredentials -UseBasicParsing
Invoke-WebRequest -Uri $artifacts -WebSession $TeamCitySession -UseBasicParsing -OutFile $dest

In order to figure out what was happening I needed to use Fiddler to trace what a successful request looks like and also trace what was happening in PowerShell. In order to do that I had to make my PowerShell request use it. The following is how I turned on Fiddler tracing from within PowerShell.

Invoke-WebRequest -Uri $artifacts -UseDefaultCredentials -Proxy http://localhost:8888/

By adding the -Proxy argument to the command it told he command to use Fiddler as a proxy server.

From here I saw that TeamCity was redirecting me to the login page. Since I have NTLM authentication turned on there is a special page that you browse to in order to login. So what I wanted to do from here was to visit this login page and then download the file using the cookies that I get back as TeamCity uses a cookie to track authentication status.

It also turns out that the Invoke-WebRequest cmdlets also allow you to connect them using a web session. There are two ways of accomplishing this using either the -WebSession or the -SessionVariable parameter. After some trial and error it turns out that if you use the -SessionVariable parameter it will overwrite the session variable after each request, so that it doesn't actually share the state. Clearly this is not the behavior I am looking for. Instead I had to use the -WebSession parameter and then I could chain together the login and the download of the file. Once I did this then everything started working.

like image 180
Aaron Weiker Avatar answered Nov 15 '22 06:11

Aaron Weiker