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.
[CmdletBinding()]
Param (
[Parameter(Mandatory=$true)]
[string] $Path,
[Parameter(Mandatory=$true)]
[string] $FolderID
)
$BoxCLIPath = "C:\Program Files\@boxcli\bin"
if(-not (Get-Module Posh-SYSLOG)) {
Import-Module -Name Posh-SYSLOG
}
Set-Location -Path $BoxCLIPath
$AccessToken = .\box tokens:get
$UploadURL = "https://upload.box.com/api/2.0/files/content"
$Headers = @{
"Authorization" = "Bearer $AccessToken"
}
$files = Get-ChildItem -Path $Path
foreach ($file in $files) {
$FilePath = $file.Fullname
$FileContent = [System.IO.File]::ReadAllBytes($FilePath)
$Boundary = [System.Guid]::NewGuid().ToString()
$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--
"@
$Headers["Content-Type"] = "multipart/form-data; boundary=$Boundary"
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)"
}
}