PowerShell Script to Copy All OneDrive Files to Another User

Published by Nyau Wai Hoe - Updated on

In this guide, we will show you a PowerShell script that can help you copy all OneDrive files from one user to another. This is especially useful when someone leaves a company, and their files need to go to another user. This process is important to maintain the organization’s data continuity and make sure that important files remain intact. This script will copy the files, recreate the same folder structures, and take care of some common errors.

Also see: How to Check Office 365 User License Using PowerShell

PowerShell Script to Copy All OneDrive Files to Another User

Before you start

To make this script work, you’ll need a few things set up in PowerShell:

  1. The MSOnline module to manage Azure Active Directory.
  2. The SharePointPnPPowerShellOnline module to let you work with SharePoint Online.
  3. The SharePoint Online Management Shell, for managing SharePoint Online site collections.

To get the MSOnline module, type this:

Install-Module MSOnline

For the SharePointPnPPowerShellOnline module, use this command:

Install-Module SharePointPnPPowerShellOnline

Install MSOnline SharePoint PnP PowerShell Online Module

And for the SharePoint Online Management Shell, do this:

  1. Go to the SharePoint Online Management Shell download page.
  2. Hit the “Download” button.
  3. After downloading, run the installer and follow the steps to install it.

Once you’ve got everything you need, you’re ready to run the script.

How to move OneDrive files to a new user with PowerShell

This PowerShell script automates moving all files and folders from one user’s OneDrive to another within Office 365. It’s very helpful for admins who need to handle files when someone leaves the company or just to move things around.

Move OneDrive data and files to another user

$departingUserEmail = Read-Host "Enter the email address of the user who is leaving"
$destinationUserEmail = Read-Host "Enter the email address of the destination user"
$adminUsername = Read-Host "Enter the username of the Global Admin account"

$adminCredentials = Get-Credential -Credential $adminUsername
Connect-MsolService -Credential $adminCredentials

$initialDomain = Get-MsolDomain | Where-Object {$_.IsInitial -eq $true}
$sharePointAdminURL = "https://$($initialDomain.Name.Split(".")[0])-admin.sharepoint.com"

$departingUserUnderscore = $departingUserEmail -replace "[^a-zA-Z]", "_"
$destinationUserUnderscore = $destinationUserEmail -replace "[^a-zA-Z]", "_"

$departingOneDriveSite = "https://$($initialDomain.Name.Split(".")[0])-my.sharepoint.com/personal/$departingUserUnderscore"
$destinationOneDriveSite = "https://$($initialDomain.Name.Split(".")[0])-my.sharepoint.com/personal/$destinationUserUnderscore"
Write-Host "`nEstablishing connection to SharePoint Online" -ForegroundColor Blue
Connect-SPOService -Url $sharePointAdminURL -Credential $adminCredentials

Write-Host "`nGranting administrative access to $adminUsername on both OneDrive site collections" -ForegroundColor Blue
Set-SPOUser -Site $departingOneDriveSite -LoginName $adminUsername -IsSiteCollectionAdmin $true
Set-SPOUser -Site $destinationOneDriveSite -LoginName $adminUsername -IsSiteCollectionAdmin $true

Write-Host "`nConnecting to $departingUserEmail's OneDrive using SharePoint Online PNP module" -ForegroundColor Blue
Connect-PnPOnline -Url $departingOneDriveSite -Credentials $adminCredentials

Write-Host "`nRetrieving display name of $departingUserEmail" -ForegroundColor Blue
$departingUser = Get-PnPSiteCollectionAdmin | Where-Object {$_.loginname -match $departingUserEmail}

if ($departingUser -contains $null) {
    $departingUser = @{
        Title = "Departing User"
	}
}

$departingOneDrivePath = "/personal/$departingUserUnderscore/Documents"
$destinationOneDrivePath = "/personal/$destinationUserUnderscore/Documents/$($departingUser.Title)'s Files"
$destinationOneDriveSiteRelativePath = "Documents/$($departingUser.Title)'s Files"

Write-Host "`nFetching all items from $($departingUser.Title)" -ForegroundColor Blue
$items = Get-PnPListItem -List Documents -PageSize 1000

$largeItems = $items | Where-Object {[long]$_.fieldvalues.SMTotalFileStreamSize -ge 261095424 -and $_.FileSystemObjectType -contains "File"}
if ($largeItems) {
    $largeExport = @()
    foreach ($item in $largeItems) {
        $largeExport += "$(Get-Date) - Size: $([math]::Round(($item.FieldValues.SMTotalFileStreamSize / 1MB),2)) MB Path: $($item.FieldValues.FileRef)"
        Write-Host "File size exceeds limit: $($item.FieldValues.FileRef)" -ForegroundColor DarkYellow
	}
    $largeExport | Out-file C:\LargeFiles.txt -Append
    Write-Host "A list of files exceeding the size limit from $($departingUser.Title) has been exported to C:\LargeFiles.txt" -ForegroundColor Yellow
}
$rightSizeItems = $items | Where-Object {[long]$_.fieldvalues.SMTotalFileStreamSize -lt 261095424 -or $_.FileSystemObjectType -contains "Folder"}

Write-Host "`nConnecting to $destinationUserEmail's OneDrive using SharePoint PNP PowerShell module" -ForegroundColor Blue
Connect-PnPOnline -Url $destinationOneDriveSite -Credentials $adminCredentials

Write-Host "`nFiltering items by folders" -ForegroundColor Blue
$folders = $rightSizeItems | Where-Object {$_.FileSystemObjectType -contains "Folder"}

Write-Host "`nCreating directory structure" -ForegroundColor Blue
foreach ($folder in $folders) {
	$path = ('{0}{1}' -f $destinationOneDriveSiteRelativePath, $folder.fieldvalues.FileRef).Replace($departingOneDrivePath, '')
	Write-Host "Creating folder in $path" -ForegroundColor Green
	$newFolder = Ensure-PnPFolder -SiteRelativePath $path
}

Write-Host "`nCopying files" -ForegroundColor Blue
$files = $rightSizeItems | Where-Object {$_.FileSystemObjectType -contains "File"}
$fileErrors = ""
foreach ($file in $files) {
	$destPath = ("$destinationOneDrivePath$($file.fieldvalues.FileDirRef)").Replace($departingOneDrivePath, "")
	Write-Host "Copying $($file.fieldvalues.FileLeafRef) to $destPath" -ForegroundColor Green
	$newFile = Copy-PnPFile -SourceUrl $file.fieldvalues.FileRef -TargetUrl $destPath -OverwriteIfAlreadyExists -Force -ErrorVariable errors -ErrorAction SilentlyContinue
	$fileErrors += $errors
}
$fileErrors | Out-File C:\fileErrors.txt

Write-Host "`nRevoking administrative access for $adminUsername on OneDrive site collections" -ForegroundColor Blue
Set-SPOUser -Site $departingOneDriveSite -LoginName $adminUsername -IsSiteCollectionAdmin $false
Set-SPOUser -Site $destinationOneDriveSite -LoginName $adminUsername -IsSiteCollectionAdmin $false

Write-Host "`nProcess completed!" -ForegroundColor Green

Quick summary of the script

The following is a quick summary of what the script actually does, how it helps to move files from one person’s OneDrive to another’s in Office 365, from the top line to the bottom.

Gathering information

First off, you’ll be asked for the emails of the user leaving and the one receiving the files, plus the admin username.

Powershell copy onedrive to another user

Connecting to SharePoint online

Next, it uses the admin’s info to connect to Microsoft’s services and sets up the right URLs for the OneDrive sites.

Getting into the OneDrive sites

The script makes sure the admin can get into both OneDrive sites to move things around.

Finding and sorting files

Then, it jumps into the leaving user’s OneDrive, grabs all their stuff, and sorts it by size and type.

Moving the files over

After connecting to the receiving user’s OneDrive, it starts moving files and making sure everything goes in the right places.

Cleaning up

When it’s all done, it removes the admin’s access to the sites to keep everything secure.

This script can save you a lot of time if you are an admin who needs to deal with multiple OneDrive accounts, especially when someone has just left the company. Just copy the script into PowerShell, and enter the required details such as email addresses and the users you want to move from and to, and you’re good to go.

One last thing

It’s always a good idea to test the script in a safe environment, say on some OneDrive accounts that don’t matter, before using it for real tasks, just to make sure it works as you want it to and for your needs.


Nyau Wai Hoe
Nyau Wai Hoe is the Founder and Chief Editor of WindowsDigitals.com. With a degree in software engineering and over 12 years of experience in the tech support industry, Nyau has established himself as an expert in the field, with a primary focus on the Microsoft Windows operating system. As a tech enthusiast, he loves exploring new technologies and leveraging them to solve real-life problems.

Share via
Copy link