Frage

Ich arbeite an einer Reihe von Powershell-Skripten, die mein Unternehmen zum Übertragen von Daten von und zu Box.com verwenden soll.Das Einzige, was ich einfach nicht herausfinden kann, ist das Hochladen von Dateien.Die Box-API erfordert einen mehrteiligen POST-Vorgang für Uploads, und ich habe hier auf SO einige Antworten gesehen, die darauf hinweisen, dass ich das in Powershell tun sollte (z. B Dieses hier).Aber ich kriege es scheinbar nicht hin.

Hier ist der Code, den ich gerade habe:

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
}

Hier ist die Antwort, die ich zurückbekomme:

{
 "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"
}

Ich habe auch ein paar andere Permutationen ausprobiert, die nicht funktionierten.Ich habe versucht, das zu verwenden -InFile wechseln in Invoke-RestMethod anstatt -Body.Ich habe es auch mit versucht Get-Content -Raw anstelle von [IO.File]::ReadAllBytes.Beide geben einen allgemeineren Fehler zurück: The server encountered an internal error or misconfiguration and was unable to complete your request..

Ich bin mir ziemlich sicher, dass das etwas mit meinem zu tun hat filename Parameter ist nicht korrekt, aber ich bin mir nicht sicher, wie ich das beheben kann.Entsprechend der Box-API, so sollte es in Curl aussehen.Kann mir jemand helfen, dies richtig für Powershell zu übersetzen?

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

Lösung

Es gibt ein paar Dinge, die dies in PowerShell etwas schwierig machen:

  1. Der filename Der Parameter gibt den Namen der Datei an, nicht den Inhalt.
  2. Zur Angabe des Dateinamens und des Ziels ist ein Anfragetext erforderlich.
  3. PowerShell-Leckereien -InFile Und -Body Argumente als sich gegenseitig ausschließend.
  4. PowerShell scheint keine native Unterstützung zu bieten multipart/form-data POSTs, pro Frage auf die Sie verwiesen haben.

Da der Anfragetext erforderlich ist (1,2) – und somit -InFile kann nicht verwendet werden (3) – ich denke, Sie müssen möglicherweise selbst würfeln multipart/form-data Hauptteil (4), der die notwendigen Metadaten und Dateiinhalte enthält. Dieser Blogbeitrag beschreibt eine Methode dafür.Der Inhalt dort ist eine kurze Zeichenfolge (ein Tweet), aber das Prinzip ist dasselbe.

Unten ist ein Fiddler-Trace eines Uploads, den ich gerade mit dem Box Windows SDK durchgeführt habe.Dies zeigt, wie die Anfrage aussehen sollte, wenn sie über die Leitung gesendet wird.Der $BOUNDARY ist eine beliebige, eindeutige Zeichenfolge – eine GUID funktioniert hervorragend.

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--

Hier ist die Antwort, die ich erhalten habe:

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

Andere Tipps

Ich mag vielleicht dumm klingen, aber was passiert, wenn Sie das tun?

$body.Add("filename",  $([IO.File]::ReadAllBytes($SourcePath)))
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top