Transfer Content Ownership of SharePoint Online Content

Hey Guys,
Most of us must have faced a situation in SharePoint world when we had to use Move-SPUser to update SharePoint with users who have moved from one active directory domain to another like if user’s identity has changed from CORPUserID to NewCorpUserID.SP-MoveUser works perfect for most of such scenarios. But there is a related area of content ownership transfer, regd. which not much of the information is available.

I am trying to compare these 2, as Move-SPUser command can’t be used in SharePoint online and content ownership transfer can be used even in a scenario when the employee leaves the organization and it is required that someone else assumes the ownership of all the content created by him/her.

Most of the time currently that is not treated as an issue as just giving contribute permission on the item/list/library allows anyone else to manage those content. But that still doesn’t give those owners of such content.

I have written a PowerShell script which uses CSOM to connect to a SharePoint online tenant and changes the content ownership of all the content that belonged to User A to User B.

Download the latest version Sharepoint Online Management Shell from This Link

Here we go –

#Add references to SharePoint client assemblies and authenticate to Office 365 site – required for CSOM
Add-Type -Path “C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.dll”
Add-Type -Path “C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.Runtime.dll”
Add-Type -Path “C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.Online.SharePoint.Client.Tenant.dll”
        
#Specify tenant admin and URL and connect to it
$User = [email protected]
$SiteURL = “https://mytenant-admin.sharepoint.com”
$Password = Read-Host -Prompt “Please enter your password” -AsSecureString
$Creds = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($User,$Password)
$Context = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
$Context.Credentials = $Creds
#There could be some lists/libraries where you don’t want to change the content ownership… may be because of the reason that it’s not required
$ListsExceptions = @(“Master Page Gallery”,“AppPackages”,“Style Library”, “SiteAssets”, “Composed Looks”, “MicroFeed”)
#Function to return all the Site Collections from the given SharePoint Online Tenant
Function GetAllSPOSiteCollections
{
    $spoTenant= New-Object Microsoft.Online.SharePoint.TenantAdministration.Tenant($Context)
    $spoTenantSiteCollections=$spoTenant.GetSiteProperties(0,$true)
    $Context.Load($spoTenantSiteCollections)
    $Context.ExecuteQuery()
    Return $spoTenantSiteCollections
}
#Function to actually Transfer the ownership from UserA to UserB
Function UpdateOwners($Context, $web)
{
        Write-Host“Inside Web:” $web.Url
        $Context.Load($web)
        $Context.ExecuteQuery()
        #Ensure Old & new Users
        $newUser= $web.EnsureUser([email protected])
        $oldUser= $web.EnsureUser([email protected])
        $Context.Load($newUser)
        $Context.Load($oldUser)
        $Context.ExecuteQuery()
       # $newUser = “{0};#{1}” -f $newUser.ID, $newUser.UserLogin.Tostring()
       
        $SPLists= $web.Lists
        $Context.Load($SPLists)
        $Context.ExecuteQuery()
       
        #Loop through all the lists & libraries
        foreach($SPList in $SPLists)
        {
           
            $Context.Load($SPList)
            $Context.ExecuteQuery()
       
            #If the list is mentioned in the exception above,skip it
            if($ListsExceptions.Contains($SPList.Title))
            {
               
                Write-Host“Skipping Site:” $web.Url“, List:” $SPList.Title“…”-Foreground Yellow
                continue
            }
           
            #Find out all the Person or Group type of fields in that list
            $SPFields= $SPList.Fields
            $Context.Load($SPFields)
            $Context.ExecuteQuery()
            $FieldsToBeUpdated= @()
            foreach($SPfield in $SPList.Fields)
            {
   
                if($SPfield.TypeDisplayName.ToString() -eq“Person or Group”)
                {
                    $FieldsToBeUpdated+= $SPfield.InternalName
                }
            }
            #Get all the items from the list
            $CamlQuery= New-ObjectMicrosoft.SharePoint.Client.CamlQuery
            $CamlQuery.ViewXml = “”
            $SPItems= $SPList.GetItems($CamlQuery)
            $Context.Load($SPItems)
            $Context.ExecuteQuery()
            #Loop through all the items and update all the People or Group type of field with new user ID
            foreach($listItem in$SPItems)
            {
  
               foreach($field in $FieldsToBeUpdated)
               {
                $CurrentUserLookup= $listItem[$field]
               
                $UserLookupid= $CurrentUserLookup| Select LookupID
                if($UserLookupid -eq$null)
                {continue}
                $CurrentUser= $web.GetUserById($UserLookupid.LookupID)
                $Context.Load($CurrentUser)
                $Context.ExecuteQuery()
    
   
                if($CurrentUser.LoginName -eq $olduser.LoginName)
                {
                    Write-Host“Updating Site:” $web.Url“, List:” $SPList.Title“, Field:” $field “from: “$olduser.LoginName “to User: “$newUser.LoginName -ForegroundGreen
                  
                   #Looks like “Author” & “Editor” do not like the format $field, so hardcoding those
                    if($field -eq “Author”)
                    {
                        $listItem[$field] = $newUser
                        $listItem[“Editor”]= $newUser
                    }
                    else
                    {
                         if($field -eq “Editor”)
                         {}
                         else
                         {
                            #Update all other People or Groups type of field
                            $listItem[$field] = $newUser
                         }
                    }
                     $listItem.Update()
                     $Context.ExecuteQuery()
                 }
               }
            }
        }
}
#Get all site collections, loop till each item and update the owners
$AllSiteCollections = GetAllSPOSiteCollections
foreach($SiteURLin $AllSiteCollections)
 {
    Write-Host “Inside Site:” $SiteURL.Url
    #Bind to Site Collection
    $Context= New-ObjectMicrosoft.SharePoint.Client.ClientContext($SiteURL.Url)
    $Context.Credentials =$Creds
   
    $rootweb= $Context.Web
    $Context.Load($rootweb)
    $Context.ExecuteQuery()
   
    UpdateOwners$Context $rootweb
    $AllWebs= $rootweb.Webs
    $Context.Load($AllWebs)
    $Context.ExecuteQuery()
   
       
    foreach($web in $AllWebs)
    {
       UpdateOwners$Context $web
    }
}
And that’s it, all the identified content will have the new user as owner.
Enjoy,
Anupam

You may also like

4 comments

  1. @Anupam – Do you have an updated script? I have been getting below error even after to ’16 hive’ path for dll
    New-Object : Cannot find an overload for “Tenant” and the argument count: “1”.
    At line:19 char:17
    + … $spoTenant= New-Object Microsoft.Online.SharePoint.TenantAdministrati …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (:) [New-Object], MethodException
    + FullyQualifiedErrorId : ConstructorInvokedThrowException,Microsoft.PowerShell.Commands.NewObjectCommand

    1. @Manudeep – Below are the reference to be updated as.

      Add-Type -Path “C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.dll”

      Add-Type -Path “C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.SharePoint.Client.Runtime.dll”

      Add-Type -Path “C:\Program Files\SharePoint Online Management Shell\Microsoft.Online.SharePoint.PowerShell\Microsoft.Online.SharePoint.Client.Tenant.dll”

      You can download the latest version Sharepoint Online Management Shell from the below link
      https://www.microsoft.com/en-in/download/details.aspx?id=35588

      Note : Actual installation path in your machine may vary from the Path which I provided. Pls update the location of the dll’s accordingly.

Leave a Reply

Your email address will not be published. Required fields are marked *