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
$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
$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
4 comments
@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
I will try to update the article in a couple of days.
@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.
Thanks Aravind, I will update the script accordingly.