Skip to main content

Goal: Iterate through folder and get list of files. Upload files to box folder, and if successful, remove the file. Service running as a scheduled task in Windows Server 2022 to run Powershell script nightly.



I cannot get a response from box files:upload when its successful. Any Suggestions?

Hello ✋,



First, is Box Drive an option? Using our pre-built solution takes cares of this type of use case most often. It will sync all content from the local folder up to the cloud, as well as make sure the local version is up to date for folks on the machine using the file. It doesn’t request parsing through the list, as it does all that for you automatically.



If Box Drive is not an option for some reason, I would recommend using one of our higher level Box SDKs in Python or Node as an example. Direct powershell is great for some less critical automations - like folder/user provisioning, but it is not great for error handling/retries.



Are you using the Box CLI in tandem with Powershell or just Powershell directly? The CLI might help because it will do the direct/chunked upload choice for you.



Do you never get a response? Or only sometimes?



Thanks,


Alex, Box Developer Advocate 🥑


Solution: Use a combination of Powershell and @boxcli.



Box Drive was not an option, as I needed to run it as a service account without


logging into the machine. I set it up as a Scheduled Task.



Action: Start a program

Program: Powershell

Arguments: -File "Drive:\Path\Send-BoxFiles.ps1" -Path Drive:\PathToFiles\ -FolderId 123456789012



I installed @boxci into its default location. The application I’m using is configured


for JWT authentication, so in the Box Developers Panel, I downloaded the app settings


as a json and stored them on the server. Through powershell, I logged in as the service account


that will be running the scheduled task and configured the environment.



runas /user:service_account powershell

cd 'C:\Program Files\@boxcli\bin'

.\box configure:environments:add Drive:\Path\config.json



From there, the only command I could get to output to a variable was the creation


of the token, which was fortunate because I was able to perform all other operations


natively in powershell. A copy of the script I used is below. It’s crude but over time


I’ll add in checks and balances, and more logging. Parameters allow you to use the same


script with different users/environments, and paths.



aCmdletBinding()]

Param (

>Parameter(Mandatory=$true)]

rstring] $Path,



>Parameter(Mandatory=$true)]

rstring] $FolderID

)



# Set the Box CLI executable path

$BoxCLIPath = "C:\Program Files\@boxcli\bin"



if(-not (Get-Module Posh-SYSLOG)) {

Import-Module -Name Posh-SYSLOG

}



# Set your Box API access token

Set-Location -Path $BoxCLIPath

$AccessToken = .\box tokens:get



# Construct the URL to upload the file

$UploadURL = "https://upload.box.com/api/2.0/files/content"



# Construct the authorization header

$Headers = @{

"Authorization" = "Bearer $AccessToken"

}



# Get list of files

$files = Get-ChildItem -Path $Path



# Process each file individually

foreach ($file in $files) {

$FilePath = $file.Fullname



# Read the file content

$FileContent = eSystem.IO.File]::ReadAllBytes($FilePath)



# Construct the boundary for multipart form data

$Boundary = aSystem.Guid]::NewGuid().ToString()



# Construct the multipart form data

$FormData = @"

--$Boundary

Content-Disposition: form-data; name="attributes"

Content-Type: application/json



{"name": "$(Split-Path $FilePath -Leaf)", "parent": {"id": "$FolderID"}}



--$Boundary

Content-Disposition: form-data; name="file"; filename="$(Split-Path $FilePath -Leaf)"

Content-Type: application/octet-stream



$($FileContent -join "`r`n")



--$Boundary--

"@



# Set the content type header

$Headerse"Content-Type"] = "multipart/form-data; boundary=$Boundary"



# Upload the file to Box

try {

$Response = Invoke-RestMethod -Uri $UploadURL -Method Post -Headers $Headers -Body $FormData

Send-SyslogMessage -Server syslog.local -Severity Informational -Facility kern -ApplicationName Send-BoxFiles -Message "File Upload Success $file $$($Response.entries.id)]"

Remove-Item -Path $file.FullName

} catch {

Send-SyslogMessage -Server syslog.local -Severity Informational -Facility kern -ApplicationName Send-BoxFiles -Message "$($_.Exception.Message)"

}

}


Reply