estradowiec
estradowiec

Reputation: 241

Download artifact from Jenkins using PowerShell

I try download artifact from Jenkins using PowerShell, like this:

$webClient = new-object System.Net.WebClient 
$webClient.Credentials = New-Object System.Net.NetworkCredential ("username", "password")
$url = "http://jenkins/job/jobName/lastSuccessfulBuild/artifact/*zip*/archive.zip" 
$localfilename = "C:\Test\archive.zip"  
$webClient.DownloadFile($url, $localfilename)

I get exception:

Exception calling "DownloadFile" with "2" argument(s): "The remote server retur ned an error: (403) Forbidden." At C:\ps2.ps1:20 char:28 + $webclient.DownloadFile <<<< ($url, $localfilename) + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : DotNetMethodException

If I try download artifact using wget it works:

wget --auth-no-challenge --http-user=username --http-password=password http://jenkins/job/jobName/lastSuccessfulBuild/artifact/*zip*/archive.zip

If I using wget without parameter --auth-no-challenge I get the same error - Forbidden.

Upvotes: 5

Views: 5977

Answers (4)

Stoinov
Stoinov

Reputation: 792

Since Jenkins 2.0, CSRF is enabled by default which requires a session cookie to be provided. In this case you need additional step:

$crumbParams = @{
    Headers = @{'Authorization' = 'Basic ' + [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$($credentials.UserName):$($credentials.GetNetworkCredential().Password)"))}
    Uri = "$baseUri/crumbIssuer/api/json"
    SessionVariable = 'crumbSession'
}
[void] (Invoke-RestMethod @crumbParams)

Note that if you provide your credentials with domain, you might have to use $credentials.GetNetworkCredential().UserName if Jenkins expects only username without the domain. The $baseUri is the Jenkins address including http(s)://.

The previous command will save the session state in $crumbSession, from which you can extract the required cookie header:

$webClient = New-Object System.Net.WebClient
$webClient.Headers.Add([System.Net.HttpRequestHeader]::Cookie, $crumbSession.Cookies.GetCookieHeader($baseUri))
$webClient.Headers.Add([System.Net.HttpRequestHeader]::Authorization, 'Basic ' + [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("$($credentials.UserName):$($credentials.GetNetworkCredential().Password)")))
$webClient.DownloadFile($url, $localfilename)

Upvotes: 0

estradowiec
estradowiec

Reputation: 241

Using this authorization in request header is working great:

# Create web client with authorization header
$webClient = new-object System.Net.WebClient 
$credentialAsBytes = [System.Text.Encoding]::ASCII.GetBytes($userName + ":" + $password)
$credentialAsBase64String = [System.Convert]::ToBase64String($credentialAsBytes);
$webClient.Headers[[System.Net.HttpRequestHeader]::Authorization] = "Basic " + $credentialAsBase64String;

Upvotes: 7

Chunter4
Chunter4

Reputation: 85

I have not tried this on Jenkins yet, but this is what I am using to download a file attached to an issue in Jira (https):

Invoke-WebRequest -uri "https://jira.xyz.com/login.jsp?os_username=$username&os_password=$jiraPassword&os_cookie=true" -UserAgent ([Microsoft.PowerShell.Commands.PSUserAgent]::InternetExplorer) -SessionVariable myWebSession

Invoke-WebRequest -uri $fileUrlPath -LocalOutFilePath $file -method get -UserAgent ([Microsoft.PowerShell.Commands.PSUserAgent]::InternetExplorer) -WebSession $myWebSession

Upvotes: 0

Raf
Raf

Reputation: 10107

Do you have basic auth set up on your Jenkins box? If so try this

$webClient = new-object System.Net.WebClient 
$creds = New-Object System.Net.NetworkCredential ("username", "password")
$url = "http://jenkins/job/jobName/lastSuccessfulBuild/artifact/*zip*/archive.zip" 
$localfilename = "C:\Test\archive.zip"  
$cache = new-object System.Net.CredentialCache
$cache.Add($url, "Basic", $creds)
$webclient.Credentials = $cache
$webClient.DownloadFile($url, $localfilename)

Upvotes: 2

Related Questions