Question

Je travaille sur une série de scripts Powershell que mon entreprise pourra utiliser pour transférer des données vers et depuis Box.com.La seule chose que je n'arrive pas à comprendre, c'est le téléchargement de fichiers.L'API Box nécessite une opération POST en plusieurs parties pour les téléchargements, et j'ai vu quelques réponses ici sur SO indiquant que je devrais pouvoir le faire dans Powershell (comme celui-ci).Mais je n'arrive pas à le faire fonctionner.

Voici le code que j'ai en ce moment :

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
}

Voici la réponse que je reçois :

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

J'ai également essayé quelques autres permutations qui ne fonctionnent pas.J'ai essayé d'utiliser le -InFile entrer Invoke-RestMethod au lieu de -Body.J'ai aussi essayé d'utiliser Get-Content -Raw au lieu de [IO.File]::ReadAllBytes.Les deux renvoient une erreur plus générique : The server encountered an internal error or misconfiguration and was unable to complete your request..

Je suis presque sûr que cela a quelque chose à voir avec mon filename le paramètre n'est pas correct, mais je ne sais pas comment le corriger.Selon le API de boîte, voici à quoi cela devrait ressembler en curl.Quelqu'un peut-il m'aider à traduire correctement ceci pour 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
Était-ce utile?

La solution

Il y a quelques éléments qui rendent cela un peu délicat dans PowerShell :

  1. Le filename Le paramètre spécifie le nom du fichier, pas son contenu.
  2. Un corps de requête est requis afin de spécifier le nom du fichier et la destination.
  3. Gâteries PowerShell -InFile et -Body arguments comme s’excluant mutuellement.
  4. PowerShell ne semble pas prendre en charge nativement multipart/form-data POST, selon le question que vous avez référencé.

Puisque le corps de la requête est requis (1,2) -- et donc -InFile ne peut pas être utilisé (3) -- je pense que vous devrez peut-être rouler le vôtre multipart/form-data corps (4) qui contient les métadonnées nécessaires et le contenu du fichier. Ce billet de blog décrit une méthode pour le faire.Le contenu y est une courte chaîne (un tweet) mais le principe est le même.

Vous trouverez ci-dessous une trace Fiddler d'un téléchargement que je viens d'effectuer à l'aide du SDK Box Windows.Cela montre à quoi devrait ressembler la demande lorsqu'elle traverse le réseau.Le $BOUNDARY est une chaîne arbitraire et unique – un GUID fonctionne très bien.

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

Voici la réponse que j'ai reçue :

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

Autres conseils

Je peux paraître stupide, mais que se passe-t-il lorsque vous faites cela ?

$body.Add("filename",  $([IO.File]::ReadAllBytes($SourcePath)))
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top