I am working on a series of Powershell scripts for my company to use to transfer data to and from Box.com. The one thing I just can't figure out is uploading files. The Box API requires a multipart POST operation for uploads, and I've seen a few answers here on SO indicating that I should be able to do that in Powershell (such as this one). But I can't seem to get it working.
Here's the code I have right now:
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
}
Here's the response I get back:
{
"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"
}
I've also tried a couple of other permutations that aren't working. I've tried using the -InFile
switch in Invoke-RestMethod
instead of -Body
. I've also tried using Get-Content -Raw
in place of [IO.File]::ReadAllBytes
. Both of those return a more generic error: The server encountered an internal error or misconfiguration and was unable to complete your request.
.
I'm pretty sure this has something to do with my filename
parameter not being correct, but I'm not sure how to fix it. According to the Box API, here's what it should look like in curl. Can someone help me properly translate this for 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
Navigate to the folder where you save the PS1 script Execute the script by typing “.\UploadDocuments_With Credentials.ps1” as shown in the below screenshot. This script has will upload all the file in “C:\Temp\PS Testing\T” folder as mentioned in the code.
Create Simple PowerShell UI for browsing the location of files with one textbox and two button type (upload & cancel) with help of system.Windows.Forms In Browse button click event, you can perform the browse with the specific file that need to be upload to destination folder using New-Object -TypeName System.Windows.Forms.OpenFileDialog.
I was able to use this code in Powershell to upload a file . Do not worry about the first function get-I contenttype. this is just used for getting the contenttype of the file. not100% sure even if we need this. I hope this works for you as well. You might get error due to bad formatting of "payload".
Upload files from network drive to SharePoint using PowerShell. Log on to Application Server (where you can see Central admin) Open SharePoint 2013 management shell as administrator. Copy/Save above script as “UploadDocuments_onSharePointServer.ps1” (You can change the name if you want there is no ...
There are a couple things that make this a little tricky in PowerShell:
filename
parameter specifies the name of the file, not the contents.-InFile
and -Body
arguments as mutually exclusive.multipart/form-data
POSTs, per the question that you referenced.Since the request body is required (1,2) -- and thus -InFile
can't be used (3) -- I think you might need to roll your own multipart/form-data
body (4) that contains the necessary metadata and file content. This blog post describes a method for doing so. The content there is a short string (a tweet) but the principle is the same.
Below is a Fiddler trace of an upload I just performed using the Box Windows SDK. This shows how the request should look as it goes across the wire. The $BOUNDARY
is an arbitrary, unique string -- a GUID works great.
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--
Here is the response I received:
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", ... }]}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With