Carica un file in Box.com usando PowerShell
-
26-12-2019 - |
Domanda
Sto lavorando su una serie di script PowerShell per la mia azienda da utilizzare per trasferire i dati da e verso BOX.com. L'unica cosa che non riesco a capire sta caricando i file. L'API Box richiede un'operazione Posta Multipart per caricamenti, e ho visto alcune risposte qui su così indicando che dovrei essere in grado di farlo a PowerShell (come Questo ). Ma non riesco a farlo funzionare.
Ecco il codice che ho adesso:
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
}
.
Ecco la risposta che torno:
{
"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"
}
.
Ho anche provato un paio di altre permutazioni che non funzionano. Ho provato a utilizzare l'interruttore -InFile
in Invoke-RestMethod
anziché -Body
. Ho anche provato a utilizzare Get-Content -Raw
al posto di [IO.File]::ReadAllBytes
. Entrambi di ritorno un errore più generico: The server encountered an internal error or misconfiguration and was unable to complete your request.
.
Sono abbastanza sicuro che questo ha qualcosa a che fare con il mio parametro filename
non essere corretto, ma non sono sicuro di come risolverlo. Secondo il box API , ecco cosa dovrebbe assomigliare a arricciare. Qualcuno può aiutarmi a tradursi correttamente per 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
. Soluzione
Ci sono un paio di cose che lo rendono un po 'complicato a PowerShell:
- .
- Il parametro
filename
specifica il nome del file, non il contenuto. - è necessario un corpo di richiesta per specificare il nome del file e la destinazione.
- PowerShell tratta
-InFile
e argomenti generacodiciTagCodeTagCode come reciprocamente esclusivo. - PowerShell non sembra supportare nativamente i post di
-Body
, per Domanda che hai fatto riferimento.
Poiché è richiesto il corpo della richiesta (1,2) - e quindi non può essere utilizzato multipart/form-data
(3) - Penso che potresti aver bisogno di arrotolare il proprio corpo -InFile
(4) che contiene i metadati e il file necessari soddisfare. Questo post Blog descrive un metodo per farlo. Il contenuto è una corda corta (un tweet) ma il principio è lo stesso.
Di seguito è riportata una traccia del violino di un caricamento che ho appena eseguito utilizzando la casella Windows SDK. Questo mostra come la richiesta dovrebbe apparire come attraversa il filo. Il multipart/form-data
è una stringa arbitraria e unica - un GUID funziona alla grande.
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--
.
Ecco la risposta che ho ricevuto:
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", ... }]}
.Altri suggerimenti
Posso sembrare stupido, ma cosa succede quando lo fai?
$body.Add("filename", $([IO.File]::ReadAllBytes($SourcePath)))
.