Fatih Pense's Blog
My Office 365 PowerShell Adventure to fix Personal SharePoint URL
Friday, January 31st, 2020
We started using Office 365. I created a user for myself. Then I wanted to try different migration options and created another user with the same username.
I didn’t know that I would have a slightly different personal OneDrive URL. That is because the old user URL lives on some time even after you delete the user.
The URL had a small “1” at the end. At first, I thought it was fine. However, as time went on my annoyance grew bigger and bigger.
https://example-my.sharepoint.com/:x:/r/personal/fatih_pense_example_com1/_layouts/15/Doc.aspx?sourcedoc=.....xlsx&action=default&mobileredirect=true
How can you solve this issue on the server-side?
You can change the URL of SharePoint sites but there is no way to change the personal URL.
I have tried creating a new user and the personal URL of the new user was fine! So this can be the first step! If only I can just move all my data to the new user… At this point, the only important data is mail and OneDrive files. I can use the client to move files for OneDrive. For email data exporting & importing .pst files can be an option. I didn’t want to sync all my emails to the client and sync it back to the server again.
Note that, unfortunately Teams chats won’t migrate. It is a good idea to change your old user account’s name to “DELETED”. Otherwise people will send messages to your old account. :)
After some research, it seems there is a way to do that server-side. Let’s write the steps:
- Rename your old account to e.g. [email protected] from the admin console. Remove aliases!
- Create a new user from the admin console.
- You first disable the old mailbox. (fatih.pense2)
- And restore the new mailbox from the old mailbox using the MailboxRestoreRequest feature.
- You can delete the old user account from the admin console.
First, we connect to Exchange Online using a PowerShell window. (docs)
$credential = Get-Credential
$exchangeSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://outlook.office365.com/powershell-liveid/" -Credential $credential -Authentication "Basic" -AllowRedirection
Import-PSSession $exchangeSession -DisableNameChecking
Now you can use Exchange specific commands! You can use the documentation for Exchange PowerShell for example Get-MailboxRestoreRequest cmdlet.
Disable-Mailbox -Identity "fatih.pense2" -Archive
New-MailboxRestoreRequest -SourceMailbox "[email protected]" -TargetMailbox "[email protected]" -AllowLegacyDnMismatch:$True;
MailboxRestoreRequest works like a job. So you have to check it from time to time.
Get-MailboxRestoreRequest | Get-MailboxRestoreRequestStatistics -IncludeReport | select -expand PercentComplete
To get a detailed report:
Get-MailboxRestoreRequest | Get-MailboxRestoreRequestStatistics -IncludeReport | Format-List > C:\temp\AllRestoreReports.txt
You can also filter the jobs by status and then apply commands to them!
Get-MailboxRestoreRequest
Get-MailboxRestoreRequest -Status Failed | Remove-MailboxRestoreRequest
Get-MailboxRestoreRequest -Status Queued | Get-MailboxRestoreRequestStatistics -IncludeReport | Format-List > C:\temp\AllRestoreReports.txt
I had to run the job multiple times after failures. It only syncs missing emails. It took several hours for 3-4 GB data, but in the end, it worked.
After the whole process completes. You can check all personal URLs with this script from Microsoft Documentation.
$TenantUrl = "https://<EXAMPLE>-admin.sharepoint.com/"
$LogFile = [Environment]::GetFolderPath("Desktop") + "\OneDriveSites.log"
Connect-SPOService -Url $TenantUrl
Get-SPOSite -IncludePersonalSite $true -Limit all -Filter "Url -like '-my.sharepoint.com/personal/'" | select Url | Out-File $LogFile -Force
Write-Host "Done! File saved as $($LogFile)."
#https://docs.microsoft.com/en-us/onedrive/list-onedrive-urls
It is the first time I have used PowerShell scripts this much. I think Microsoft’s design decisions are good. Piping commands with structured data and documenting them to reduce errors is a nice idea.
I also like Unix’s “everything is string, accept it and move on!” approach. The only problem is that I have always tried to avoid bash because of seemingly irregular syntax. There are a lot of alternatives for the Unix shell, but bash is the universal one we should compare with PowerShell. Interestingly, “BNF grammar for bash” seems small. But maybe I should learn German instead…