使用Powershell将文件上传到Box.com

时间:2014-04-14 12:21:12

标签: rest powershell box-api

我正在为我公司制作一系列Powershell脚本,用于与Box.com之间传输数据。我无法弄清楚的一件事就是上传文件。 Box API需要上传的多部分POST操作,我在SO上看到了一些答案,表明我应该能够在Powershell中做到这一点(例如this one)。但我似乎无法让它发挥作用。

这是我现在的代码:

Function Post-File {
    Param(
            [Parameter(Mandatory=$True,Position=1)]
            [string]$SourcePath,
            [Parameter(Mandatory=$False,Position=2)]            
            [string]$FolderId = ############
    )

    #Variables for building URIs
    $baseUrl = "https://upload.box.com/api/2.0/files/content"

    #Set Authorization for API requests
    $headers = @{}
    $AccessToken = Refresh-Tokens #A reference to another function that definitely works
    $headers.Add("Authorization", "Bearer $AccessToken")

    #Set POST content
    $body = @{}
    $body.Add("filename",  [IO.File]::ReadAllBytes($SourcePath))
    $body.Add("parent_id", $FolderId)

    #Upload the file
    Invoke-RestMethod -Uri $baseUrl -Method Post -Headers $headers -ContentType "multipart/form-data" -Body $body
}

以下是我回复的回复:

{
 "type":"error",
 "status":400,
 "code":"invalid_request_parameters",
 "help_url":"http://developers.box.com/docs/#errors",
 "message":"Invalid input parameters in request",
 "request_id":"1764475572534bcddfe04b7"
}

我还尝试了其他几种不起作用的排列。我尝试使用-InFile中的Invoke-RestMethod开关代替-Body。我也尝试使用Get-Content -Raw代替[IO.File]::ReadAllBytes。这两个都返回一个更通用的错误:The server encountered an internal error or misconfiguration and was unable to complete your request.

我很确定这与我的filename参数不正确有关,但我不确定如何修复它。根据{{​​3}},这是卷曲中的样子。有人可以帮助我为Powershell正确翻译吗?

https://upload.box.com/api/2.0/files/content \
-H "Authorization: Bearer ACCESS_TOKEN" \
-F filename=@FILE_NAME \
-F parent_id=PARENT_FOLDER_ID

2 个答案:

答案 0 :(得分:7)

在PowerShell中有一些事情让这个有点棘手:

  1. filename参数指定文件的名称,而不是内容。
  2. 需要请求正文才能指定文件名和目的地。
  3. PowerShell将-InFile-Body参数视为互斥。
  4. 根据您引用的question,PowerShell似乎不支持multipart/form-data POST。
  5. 由于请求正文是必需的(1,2) - 因此-InFile不能使用(3) - 我认为您可能需要滚动自己的multipart/form-data正文(4) )包含必要的元数据和文件内容。 This blog post描述了这样做的方法。内容有一个短字符串(推文),但原理是相同的。

    下面是我刚刚使用Box Windows SDK执行的上传的Fiddler跟踪。这显示了请求在线路上的外观。 $BOUNDARY是一个任意的唯一字符串 - GUID效果很好。

    POST https://upload.box.com/api/2.0/files/content HTTP/1.1
    Authorization: Bearer $TOKEN
    Content-Type: multipart/form-data; boundary="$BOUNDARY"
    Host: upload.box.com
    Content-Length: 2118
    Accept-Encoding: gzip, deflate
    
    --$BOUNDARY
    
    Content-Disposition: form-data; name="file"; filename="$FILENAME"
    
    <THE CONTENT OF $FILENAME>    
    
    --$BOUNDARY
    
    Content-Type: text/plain; charset=utf-8
    Content-Disposition: form-data; name="metadata"
    
    {"parent":{"id":"$PARENT_FOLDER_ID"},"name":"$FILENAME"}
    
    --$BOUNDARY--
    

    以下是我收到的回复:

    HTTP/1.1 201 Created
    Date: Mon, 14 Apr 2014 12:52:33 GMT
    Server: Apache
    Cache-Control: no-cache, no-store
    Content-Length: 364
    Connection: close
    Content-Type: application/json
    
    {"total_count":1,"entries":[{"type":"file","id":"$ID","name":"$FILENAME", ... }]}
    

答案 1 :(得分:0)

我可能听起来很愚蠢,但是当你这样做时会发生什么?

$body.Add("filename",  $([IO.File]::ReadAllBytes($SourcePath)))