Migrate Box via API to SharePoint

Migrate Box via API to SharePoint

Issue: As part of a Box migration, tools like ShareGate, and Kernel Migrator can miscopy files at 0KB or have other problems. Admins may also need a lean way to migrate lists of Box files into SharePoint without using third-party tools.

Solution: Custom script to migrate from Box API to SharePoint. It uses a source/destination list of files from Box to the SharePoint site collection. Note that files with ‘[ ]’ have issues with this method due to API/script limitations.

Create folder structure:
a. Logs – to keep the logs created by the PowerShell script.
b. Scan – to keep all CSV files from where the PowerShell script will read the file path.
c. Temp – A folder to temporarily keep the downloaded files from Box API. Those files will be uploaded to SharePoint.

Access Token:
Copy the Access Token and use in PowerShell script. This token is valid for next 60 minutes. You should follow the steps again to generate a new token.

CSV Format:
SiteCollectinURL FilePath

Script:
<# Box to SharePoint Copy Script
create host header including 'Access Token'
Access Token generated through a manual process which will expire in 60 minutes.
Login, try the API https://developer.box.com/reference/get-files-id-content/
#>

$headers = @{
'Authorization' = 'Bearer TOKEN'
'Content' = 'application/json'
}

#Path to read CSV file
$path = "C:\temp\Scans\List of Files.csv"
$csv = Import-Csv -path $path

$SharePointRootSiteURL = "https://SITEURL.sharepoint.com";

#Change site collection URL to upload files
$SiteCollectionURL = "/sites/TargetSite/"

#Path to save log files
$logFilePath = "E:\temp\logs\Private-Log-$(get-date -f yyyy-MM-dd-HHmmss).log"

#Login to the SharePoint site collection
Connect-PnPOnline -Url "https://SITEURL.sharepoint.com/sites/TargetSite" -UseWebLogin

#Create log entries
Write-Output "Reading CSV file: $($path)..." >> $logFilePath;

$count=0
foreach($line in $csv)
{
#Count number of files scanned
$count = $count + 1

try{
#Read columns from csv
$properties = $line | Get-Member -MemberType Properties

#Read file path from csv under 'FilePath' column
$columnvalue = $line | Select -ExpandProperty "FilePath"

#Split the path to extract file name with extension
$arr = $columnvalue.Split("/")
$fileName = $columnvalue.Split("/")[($arr.length)-1]

#Create log entries
Write-Output "File Name: $($fileName)" >> $logFilePath

#Extract target folder path from filepath to upload file in SharePoint
$targetURL = $line | Select -ExpandProperty "FilePath"
$folderPath = $targetURL.Substring(0, $targetURL.lastIndexOf("/"))
$folderPath = $folderPath.replace($SiteCollectionURL,'');

#Create log entries
Write-Output "Folder Path: $($folderPath)" >> $logFilePath

#Folder Path to upload file temporarily on local folder
$PathToSave = 'E:\temp\' + $fileName

#Ceate Box API URL
$RESTURL = 'https://api.box.com/2.0/search?content_types=name&fields=id,size&limit=1&query=' + $fileName + '&type=file'

#Call API
$response =Invoke-RestMethod -Uri $RESTURL -Headers $headers -Method Get

#Convert output to JSON
$output = $response | ConvertTo-Json

#Extract id from JSON output
$entries = $output |ConvertFrom-Json | Select-Object -ExpandProperty "entries"

#Create log entries
Write-Output "File Id from Box: $($entries.id) and Size: $($entries.size)" >> $logFilePath

#Download file from BOX based on ID
$url = 'https://api.box.com/2.0/files/' + $entries.id + '/content'

#Save file from JSON to local folder
Invoke-RestMethod -Uri $url -Headers $headers -Method Get -OutFile $PathToSave

#Create log entries
Write-Output "Local file Path: $($PathToSave)" >> $logFilePath

Write-Output "Uploading to SharePoint..." >> $logFilePath

#Upload file to SharePoint
Add-PnPFile -Folder $folderPath -Path $PathToSave -ErrorAction Stop

#Delete temp file from local folder after uploading to SharePoint
Remove-Item -Path $PathToSave -Force
}
catch{

#Create log entries for Exception
Write-Output "Error: $($Error)" >> $logFilePath
}
}

 

Leave a Reply

Your email address will not be published.