简体   繁体   English

从 Windows Powershell 脚本上传到 Artifactory

[英]Uploading to Artifactory from a Windows Powershell script

I've successfully downloaded a file from Artifactory (Generic Repo) via a WebClient object.我已经通过 WebClient 对象从 Artifactory (Generic Repo) 成功下载了一个文件。 I'm having troubles uploading a file via the same method.我在通过相同方法上传文件时遇到问题。 I'm trying to figure out the simplest method for uploading via Powershell to our server.我试图找出通过 Powershell 上传到我们服务器的最简单方法。

Please note that installing other utilities like Curl is not an option at this point.请注意,此时不能选择安装其他实用程序,例如 Curl。 I'm writing automation scripts and want to stick with a basic Windows 2008 r2 server, no installing other utilities since I can't count on them being there across all the servers.我正在编写自动化脚本并希望坚持使用基本的 Windows 2008 r2 服务器,不安装其他实用程序,因为我不能指望它们在所有服务器上都存在。

If someone has an example script utilizing the Rest API, that would be perfect!如果有人有一个使用 Rest API 的示例脚本,那将是完美的!

Example of the download code (this works):下载代码示例(有效):

$SOURCE = "https://artifactory.example.com/artifactory/net-generic-local/APP/BF_1.0.zip"  
$DESTINATION = ".\BF_1.0.zip"  
$AF_USER ="user"  
$AF_PWD ="password"  
$WebClient = New-Object System.Net.WebClient  
$WebClient.Credentials = New-Object System.Net.NetworkCredential($AF_USER,$AF_PWD)  
$WebClient.DownloadFile($SOURCE,$DESTINATION)  

This is an example of the upload code (does not work):这是上传代码的示例(不起作用):

$SOURCE = ".\BF_2.0.zip"  
$DESTINATION = "https://artifactory.example.com/artifactory/net-generic-local/APP/BF_2.0.zip"  
$AF_USER ="user"  
$AF_PWD ="password"  
$WebClient = New-Object System.Net.WebClient  
$WebClient.Credentials = New-Object System.Net.NetworkCredential($AF_USER, $AF_PWD)  
$URI = New-Object System.Uri($DESTINATION)  
$WebClient.UploadFile($URI,$SOURCE)  

This is the error I'm getting from the upload:这是我从上传中得到的错误:

Exception calling "UploadFile" with "2" argument(s): "The remote server returned an error: (405) Method Not Allowed."  
At E:\transient\af_put.ps1:8 char:1  
+ $WebClient.UploadFile($URI,$SOURCE)  
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException  
    + FullyQualifiedErrorId : WebException  

I tried the Invoke-WebRequest option and was able to get this to work:我尝试了 Invoke-WebRequest 选项并且能够让它工作:

$URI = New-Object System.Uri("https://artifactory.example.com/artifactory/net-generic-local/APP/BF_2.0.zip")  
$SOURCE = ".\BF_2.0.zip"  
$AF_USER = "user"  
$AF_PWD = ConvertTo-SecureString "password" -AsPlainText -Force  
$CREDS = New-Object System.Management.Automation.PSCredential ($AF_USER, $AF_PWD)  

Invoke-WebRequest -Uri $URI -InFile $SOURCE -Method Put -Credential $CREDS  

Had to create a PSCrendential object so it would not prompt for the user password.必须创建一个 PSCrendential 对象,这样它就不会提示输入用户密码。 But other then that, this work exactly as I needed.但除此之外,这完全符合我的需要。

The reason for your issue is HTTP method used by UploadFile.您的问题的原因是 UploadFile 使用的 HTTP 方法。 By default UploadFile uses POST, while to upload file to Artifactory you need to use PUT method.默认情况下,UploadFile 使用 POST,而要将文件上传到 Artifactory,您需要使用 PUT 方法。 That is why you get 405 "Method Not Allowed" response.这就是为什么您会收到 405“Method Not Allowed”响应。

To fix this use UploadFile overload with three parameters like shown here: https://msdn.microsoft.com/en-us/library/ms144230(v=vs.110).aspx要修复此使用 UploadFile 重载的三个参数,如下所示: https : //msdn.microsoft.com/en-us/library/ms144230(v= vs.110).aspx

So the correct version of the code will look like:因此,正确版本的代码将如下所示:

$SOURCE = ".\BF_2.0.zip"  
$DESTINATION = "https://artifactory.example.com/artifactory/net-generic-local/APP/BF_2.0.zip"  
$AF_USER ="user"  
$AF_PWD ="password"  
$WebClient = New-Object System.Net.WebClient  
$WebClient.Credentials = New-Object System.Net.NetworkCredential($AF_USER, $AF_PWD)  
$URI = New-Object System.Uri($DESTINATION)
$METHOD = "PUT"  
$WebClient.UploadFile($URI, $METHOD, $SOURCE)  

I don't have Artifactory handy, but you might want to try the Invoke-RestMethod PowerShell cmdlet, available in box from PowerShell v3 and higher.我手边没有 Artifactory,但您可能想尝试Invoke-RestMethod PowerShell cmdlet,它在 PowerShell v3 及更高版本的框中可用。 Here's a sample of how to do that.这是如何做到这一点的示例。

You'll need credentials, and based on their REST documentation, basic authentication of the type we can get with the -Credential param of Invoke-RestMethod should cover us there.您将需要凭据,并且根据他们的 REST 文档,我们可以使用Invoke-RestMethod-Credential参数获得的类型的基本身份验证应该涵盖我们那里。

You'll also need to provide a message $body with your request.您还需要在您的请求中提供消息$body Look at the JSON sample here from their docs , and then edit the $body I've given as a starting point. 从他们的文档中查看此处的 JSON 示例,然后编辑我作为起点给出的$body

$credential = Get-Credential
$body = @{action="Upload";param2="Data";param3="Data";} | ConvertTo-Json 
Invoke-RestMethod -uri "http://localhost:8080/artifactory/api/build" `
  -ContentType "application/json" -method POST -body $body -Credential

I must say, this is one of the more complex examples of a REST API that I've seen, so to make this easier, I would install curl on a machine and use Fiddler to capture a trace successfully uploading a file.我必须说,这是我见过的更复杂的 REST API 示例之一,因此为了更简单,我将在机器上安装 curl 并使用 Fiddler 捕获成功上传文件的跟踪。 To make things even easier, you could also do this using the Artifactory UI from a browser to upload a file, and simple record a trace of the upload step.为了让事情变得更简单,您还可以使用浏览器中的 Artifactory UI 来上传文件,并简单地记录上传步骤​​的痕迹。 Then, grab the JSON in the request and use that as a starting point.然后,获取请求中的 JSON 并将其用作起点。

The JFrog knowledgebase offers an example upload to Artifactory via PowerShell . JFrog 知识库提供了一个通过 PowerShell 上传到 Artifactory 的示例 This example uses Invoke-RestMethod as in FoxDeploy's previous answer, but uses an -InFile parameter and a different content type, as follows:此示例使用了 FoxDeploy 上一个答案中的Invoke-RestMethod ,但使用了-InFile参数和不同的内容类型,如下所示:

Invoke-RestMethod -uri <complete URI to where the artifact will be in Artifactory>
  -Method Put -InFile <path of file to upload> -Credential <PS creds>
  -ContentType "multipart/form-data" -TimeoutSec <in seconds>

My answer is certainly derivative, but this is what worked for me when pushing something to my Artifactory repo from powershell using an API token for authentication:我的答案当然是派生的,但是当使用 API 令牌进行身份验证将某些东西从 powershell 推送到我的 Artifactory 存储库时,这对我有用:

$credential_bytes = [System.Text.Encoding]::UTF8.GetBytes($username + ":" + $api_token)
$credentials = [System.Convert]::ToBase64String($credential_bytes)
$credential_header = "Basic " + $credentials    
Invoke-WebRequest -Uri $artifactory_dest_url -InFile "my_file.zip" -Method Put -Headers @{"Authorization"="$credential_header"}

Sigh.叹。 I regret that I'm using Powershell.我很遗憾我正在使用 Powershell。 What am I doing with my life?我的生命在做什么? Anyway, it works.无论如何,它有效。 Moving on.继续。

Props to FoxDeploy and Maclnos. FoxDeploy 和 Maclnos 的道具。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM