PowerShell: Sync SharePoint Libraries to OneDrive

Recently, I was completed a migration moving data from Share Drives to SharePoint. The organization was not ready to embrace SharePoint in all it’s awesomeness and wanted to continue using their SharePoint like Share Drives. Against my better judgement, I complied.

Once the content migrated to SharePoint libraries, the content needed to be synced to OneDrive so it displays as a folder in the user’s file explorer. It was deemed too cumbersome for users to sync libraries themselves. So we needed a solution….

Solution:

Through GPO, schedule a task that will copy and execute a PowerShell script when the user logs on. The script will sync all SharePoint libraries needed for that user.

The script below maps each library listed one at a time. OneDrive cannot map more than one library at a time (tried and failed). So I added a pause / sleep in the script that will check if the folder has been created for that library on the user’s machine. Once the folder has been created, it is safe to move on to the next library.

To use this script, you need to replace the following variable values with your data: webURL, webTitle, listTitle, tenantName
You also need to replace siteId, webId and listId. These you can get using PnP. Technically it can be included in the same script but then each user will need to have PnP modules installed. To avoid this, first I got the Ids using PnP and then added the Ids to the mapping script that the users can run without PnP.

<#------------------------Library 1----START------------------------------#>

$webURL = "WEB URL" 
$webtitle = "SITE TITLE"
$listtitle = "SITE URL" 
$tenantName = "TENANT"
$upn = ("$env:username@$env:userdnsdomain").ToLower() 
$path = $env:USERPROFILE + '\' + $tenantName + '\' + "$webtitle - $listtitle" 


if(test-path $path) {
    #nothing happens
} else { #if path does not exist we create one


$hyphen = '%2D'
$at = '%40'
$dot = '%2E'
$underscore = '%5F'

$siteid = "SITEID"
$webid = "WEBID"
$listid = "LISTID"

$finalurl = "odopen://sync/?siteId=$siteid&webId=$webid&listId=$listid&userEmail=$upn&webUrl=$webURL&webtitle=$webtitle&listtitle=$listtitle" 

$finalurl = $finalurl.Replace('-', $hyphen).Replace('@',$at).Replace('.', $dot).replace('_', $underscore).replace(' ', '%20')

 while(!(test-path $path)) {
        start $finalurl
        start-sleep 1;
    }
    Start-Sleep 1;

}

<#----------------Library1----END----------------------------------#>

<#----------------------Library2----START--------------------------#>

$webURL = "WEB URL" 
$webtitle = "SITE TITLE"
$listtitle = "SITE URL" 
$tenantName = "TENANT"
$upn = ("$env:username@$env:userdnsdomain").ToLower() 
$path = $env:USERPROFILE + '\' + $tenantName + '\' + "$webtitle - $listtitle" 


if(test-path $path) {
    #nothing happens
} else { #if path does not exist we create one


$hyphen = '%2D'
$at = '%40'
$dot = '%2E'
$underscore = '%5F'

$siteid = "SITEID"
$webid = "WEBID"
$listid = "LISTID"

$finalurl = "odopen://sync/?siteId=$siteid&webId=$webid&listId=$listid&userEmail=$upn&webUrl=$webURL&webtitle=$webtitle&listtitle=$listtitle" 

$finalurl = $finalurl.Replace('-', $hyphen).Replace('@',$at).Replace('.', $dot).replace('_', $underscore).replace(' ', '%20')

 while(!(test-path $path)) {
        start $finalurl
        start-sleep 1;
    }
    Start-Sleep 1;

}

<#----------------------------Library2----END---------------------------#>

Note: You can add as many libraries as you need to the script by copying and pasting from one of the library snippets (from start to finish line) and replacing the variables for the additional library details.

Here is the script for getting the Ids. If you do not have PnP modules installed, remove the # before the first to lines to un-comment them.

#Install-PackageProvider -Namemp NuGet -Force
#Install-Module SharePointPnPPowerShellOnline -SkipPublisherCheck -AllowClobber -Force -Confirm:$false

$cred = Get-Credential

$sitecollection = "SITE Collection URL"
$webtitle = "Site Title"
$listtitle = "Library Title"

$hyphen = '%2D'
$at = '%40'
$dot = '%2E'
$underscore = '%5F'

Connect-PnPOnline $sitecollection -credentials $cred

$siteid = (Get-PnPSite -Includes Id | select id).id.guid
Write-Host "site id " $siteid
$webs = @()
$webs += Get-PnPWeb
$webs += Get-PnPSubWebs -Recurse

$web = $webs | ? {$_.title -eq $webtitle}
$weburl = $web.url
$webid = $web.id.guid
Write-Host "web id " $webid

$listid = (get-pnplist -Web $web -Identity $listtitle).id.guid
Write-Host "list id " $listid