How To Bulk Update Secondary Admin For My Sites Or OneDrive For Business (ODFB) Using PowerShell

In this article, we will see how to bulk update secondary Admin for My Sites or OneDrive for Business (ODFB) using PowerShell.  
 
In some situations, you might need to add secondary site admin to gain access to a "OneDrive for Business" environment of a user as part of the governance. By default, each user is added as primary & secondary site collection administrators to their personal site or ODFB site collection.

Follow the below steps to see site collections administrators for a MySite.

SP Admin Center - User Profiles - Manage User Profile - Search for a user.

 
When a user is marked for deletion and if Access delegation is enabled in My Site settings of the SP Admin Center, the default action is to transfer the ownership to the Manager or Secondary Owner (in the absence of the Manager) to take control of the files in the absence of the user.

In some cases, no manager is assigned as well as no Secondary Admin. In such case, thesesites or ODFB will become orphans and get deleted after 30 days (default retention period).

However, as shown in the above screen, there is an option to enable My Site Secondary Admin but this only works for the new My Sites. For previously created My sites, it should be added individually which is fine for one or a few but hectic to add for all.
 
Use the below script to bulk update the secondary admin for all My Sites.
 
At a high level, below are the steps performed in the script.
  • Declare variable (configure variable according to your tenant)
  • Connect to SharePoint Online & Context 

    • Create People Manager object to retrieve profile data

  • Connect to Azure Active Directory

    • Get User profiles. In the code I have provided two commands -- one to retrieve all licensed users and other to fetch a single user. You should comment the code based on your need.

  • Load user profile using profile manager and retrieve PersonalSpace URL (My site URL)
  • Set secondary admin
  • Export to CSV file.
  1. #Pre-Requisites, Install below modules  
  2. #Sharepoint online Management Shell : https://www.microsoft.com/en-us/download/details.aspx?id=35588  
  3. #Azure Active Directory http://connect.microsoft.com/site1164/Downloads/DownloadDetails.aspx?DownloadID=59185  
  4. #SharePoint Online Client Components SDK https://www.microsoft.com/en-us/download/details.aspx?id=42038  
  5.   
  6. Clear-Host    
  7. #Specify tenant admin and URL    
  8. $AdminAccount = 'admin@company.com'  
  9. $TenantURL = 'https://company-admin.sharepoint.com'    
  10.  
  11. #Specify the secondary admin account and the url for the onedrive site  
  12. $Secondaryadmin = 'Secondaryadmin@company.com'    
  13. $MySiteURL = 'https://company-my.sharepoint.com'   
  14.  
  15. #Use this varable to apply seconday site collection for a specific user  
  16. $User = 'targetuser@company.com'  
  17.  
  18. #Location to save the report  
  19. $UserProfileOutPut = 'D:\MyWokingFolder\Report\AllProfiles.csv'    
  20.  
  21. #Attention: sometimes folder path may be 15 or 16. Browse the folder and verify the availability of the dlls  
  22. #Add references to SharePoint online client component assemblies     
  23. Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll'    
  24. Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll'    
  25. Add-Type -Path 'C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.UserProfiles.dll'    
  26. Write-Host "Loading SharePoint Assemblies..." -ForegroundColor Yellow    
  27.   
  28. Write-Host "Connecting to SharePoint Online Service and Context..." -ForegroundColor Yellow    
  29. $Password = Read-Host -Prompt 'Please enter your password' -AsSecureString    
  30. $Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $AdminAccount, $Password    
  31. $Creds = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($AdminAccount,$Password)    
  32.    
  33. #Bind to Site Collection    
  34. $Context = New-Object Microsoft.SharePoint.Client.ClientContext($TenantURL)    
  35. $Context.Credentials = $Creds    
  36. Write-Host "Connected to SharePoint Online Context..." -ForegroundColor Yellow    
  37.    
  38. #Create People Manager object to retrieve profile data    
  39. $PeopleManager = New-Object Microsoft.SharePoint.Client.UserProfiles.PeopleManager($Context) -ErrorAction Inquire    
  40. Write-Host "Loading People Manager..." -ForegroundColor Yellow    
  41.  
  42. #Connect to Office 365 tenant  
  43. try    
  44. {    
  45.     Connect-MsolService -Credential $Credentials -ErrorAction Inquire    
  46.     Write-Host "Connected to SharePoint Online Service..." -ForegroundColor Yellow    
  47. }    
  48. catch    
  49. {    
  50.     Write-Host "Unable to Connect to SharePoint Online...Existing the Script."    
  51.     return    
  52. }    
  53. #Use below code to apply seconday site collection for all licensed users  
  54. $Users = Get-MsolUser -All | where {$_.isLicensed -eq $true}  
  55.  
  56. #Use below code to apply seconday site collection for a specific user  
  57. #$Users = Get-MsolUser -All | where {$_.UserPrincipalName -eq $User}  
  58.   
  59.   
  60. Write-Host "Collecting Users Information from SharePoint Online..." -ForegroundColor Yellow    
  61.     
  62. $Headings = ""    
  63. $boolCreateHeadings = $true    
  64.     
  65. Connect-SPOService -Url $TenantURL -Credential $Credentials  
  66.   
  67. Foreach ($User in $Users)    
  68. {    
  69.     $ClaimsUserFormat = 'i:0#.f|membership|'+ $User.UserPrincipalName    
  70.     $UserProfile = $PeopleManager.GetPropertiesFor($ClaimsUserFormat)    
  71.     $Context.Load($UserProfile)    
  72.     $Context.ExecuteQuery()    
  73.     #Allow profiles only with PersonalSpace URL  
  74.     If ($UserProfile.UserProfileProperties['PersonalSpace'] -ne $null)    
  75.     {    
  76.         $PersonalSpace = $UserProfile.UserProfileProperties['PersonalSpace'];  
  77.         $PersonalSpace = $MySiteURL + $PersonalSpace  
  78.         $temp = Set-SPOUser -Site $PersonalSpace -LoginName $secondaryadmin -IsSiteCollectionAdmin $true  
  79.         Write-Host "Added secondary admin to the site ($PersonalSpace)"   
  80.   
  81.         if($boolCreateHeadings)    
  82.         {    
  83.             Write-Host "Loading CSV Headings..." -ForegroundColor Green    
  84.             $Headings = '" FirstName "," LastName "," UserName "," PersonalSpace "'    
  85.             $Headings -join "," | Out-File -Encoding default -FilePath $UserProfileOutPut    
  86.             $boolCreateHeadings = $false    
  87.         }    
  88.         $Properties = '"' + $UserProfile.UserProfileProperties["FirstName"] + '",' + '"' + $UserProfile.UserProfileProperties["LastName"] + '",' + '"' + $UserProfile.UserProfileProperties["UserName"] + '",' + '"' + $UserProfile.UserProfileProperties["FirstName"] + '",' + '"' + $UserProfile.UserProfileProperties["PersonalSpace"] + '"';    
  89.         #Export to CSV.  
  90.         $Properties -join "," | Out-File -Encoding default -Append -FilePath $UserProfileOutPut    
  91.         Write-Host "User Profile Written to CSV $UserProfileOutPut" -ForegroundColor Yellow          
  92.     }  
  93. }    
  94. Write-Host "Successfully assigned seconday site collection admin.All profiles have been Written to $UserProfileOutPut" -ForegroundColor Green  
 To run the script without errors, the below prerequisites must be met.
Output Screen when it is run to update secondary admin for a specific user - 

 
References to some issues.
  • Execution of scripts is disabled on this system

    • Set the execution policy to remote signed using below command
Set-ExecutionPolicy RemoteSigned
  • New-Object: Cannot find an overload for "PeopleManager" and the argument count: "1".

    • Ensure SharePoint Online Client components SDK are loaded, refer this.
I hope you find this informative.