Remove OneDrive sites in bulk
Recently I worked with a client who wanted absolutely nothing to do with OneDrive, this details my cleanup.
Recently I worked with a client who wanted absolutely nothing to do with OneDrive after migrating all data to Competitor_302 and appropriate retention period. Users still had M365 licenses for various business cough Excel cough needs, but OneDrive was persona non grata.
First thing was editing Sharepoint so that personal sites are no longer created. Which is done via the old admin settings and making sure the below is unchecked.


So that stops creation, let's look at removal.
#Requires -Modules ExchangePowerShell
Import-Module Microsoft.Online.SharePoint.Powershell -UseWindowsPowerShell -DisableNameChecking
#Tenant Admin Site
$AdminSiteURL="https://{tenantname}-admin.sharepoint.com"
$OwnerEmail = {adminUPN}
Connect-SPOService -Url $AdminSiteURL
$sites = Get-SPOSite -IncludePersonalSite $true -Limit All | Where-Object { $_.Url -like "*-my.sharepoint.com/personal/*" }
Connect-IPPSSession -UserPrincipalName $OwnerEmail
[array]$HoldURLs = $sites
ForEach ($HoldURL in $HoldURLs) {
Try {
$site = $HoldURL.url
$Holds = Invoke-HoldRemovalAction -Action GetHolds -Sharepointlocation $site
if ($null -ne $Holds) {
ForEach ($Hold in $Holds) {
Invoke-HoldRemovalAction -Action RemoveHold -Sharepointlocation $site -Holdid $Hold -force
}
}
} catch {
}
}
Disconnect-IPPSSession
ForEach ($site in $sites) {
try {
Write-Host "Removing site: $($site.Url)"
if ($site.LockState -ne "Unlock") {
Set-SPOSite -Identity $site.Url -LockState Unlock
}
if ($site.Owner -ne $OwnerEmail) {
Set-SPOSite -Identity $site.Url -Owner $OwnerEmail -NoWait
}
Remove-SPOSite -Confirm:$false -Identity $site.Url -NoWait
} catch {
Write-Host "Failed to remove site: $($site.Url)"
}
}
Disconnect-SPOService
I'm running this in pwsh
/ Powershell 7.x hence the -UseWindowsPowershell
switch when importing the Sharepoint Online module. Update $AdminSiteURL
to reflect your tenants URL and $OwnerEmail
to be the UPN of the admin you are running the script with.
Then what the above does is check the Security & Compliance Powershell module for any holds for each personal site found, removing them. This can take up to 4 hours to be reflected.
Finally the bulk of the removal, iterating through each site and making sure the lockstate is in the correct state and that the user running the script has permission to modify the site before attempting. Running as-is I found removal occurred at around 250 sites/hour. Running in a foreach-object -parallel
can speed up the process.
So that stopped new personal site creation and removed existing. Then apply a new Office Customization without OneDrive to deploy to new users and a detect/remediation to uninstall existing OneDrive.
Hopefully this is useful to someone, as it was a particularly odd request for me. I did attempt to use graph's mydrive user endpoint, but even after cleaning those up I would still see the sites via SPO so just went that route entirely.