In SharePoint Online (SPO) we cannot modify the secondary owner using SharePoint Hosted Apps so there is a work around to modify this value using powershell script.
We can save the secondary owner values in property bag and then using powershell we can update secondary owner field.
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
#Log File
$DatePostFix = Get-Date -format "MM-dd-yyyy_hh-mm-ss"
$LogFileName = "SetSecondaryOwner_SPO_" + $DatePostFix + ".csv"
$LastRunDateFileName = "SetSecondaryOwner_SPO_LastRunDate.csv"
# User Credentials
$Username="abc@org.com"
$AdminPassword = Read-Host -Prompt "Enter Password" -AsSecureString
## Site URL - Providing the credentials
$AdminUrl="https://sposite.sharepoint.com"
#Retrieve all site collection infos
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Username, $AdminPassword
Connect-SPOService -Url $AdminUrl -Credential $cred
$sitesCollectionsList = Get-SPOSite
try
{
# Get todays date.
$todayDate = Get-Date
# Get Script last run date
if (!(Test-Path $LastRunDateFileName))
{
"{0}" -f $todayDate.AddDays(-1) |Add-Content $LastRunDateFileName
}
$lastRunFile = Get-Content $LastRunDateFileName
if ([string]::IsNullOrEmpty($lastRunFile)) {
$scriptLastRundate = $todayDate.AddDays(-1).ToString()
}
else
{
$scriptLastRundate = [datetime]$lastRunFile.ToString()
}
#Retrieve and print all sites
foreach ($siteColl in $sitesCollectionsList)
{
try
{
#SPO Client Object Model Context
$ctx=New-Object Microsoft.SharePoint.Client.ClientContext($siteColl.Url)
$ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Username, $AdminPassword)
$site=$ctx.site
$spoRootWeb = $ctx.Web
$ctx.Load($site)
$ctx.Load($spoRootWeb)
$ctx.ExecuteQuery()
#Get the property bag values
$spoAllSiteProperties=$spoRootWeb.AllProperties
$ctx.Load($spoAllSiteProperties)
$ctx.ExecuteQuery()
# Check if Last Review date exist and get the value
$lastReviewdate = ""
if ($spoAllSiteProperties.FieldValues.ContainsKey(‘__reviewedOn_key___’)) {
$lastReviewdate = [datetime]$spoAllSiteProperties[‘__reviewedOn_key___’]
}
# Update Secondary Owner if lastreview date is today's date or script last run date is lesser than the review date
if (!([string]::IsNullOrEmpty($lastReviewdate))) {
if (($scriptLastRundate -lt $lastReviewdate) -or ($lastReviewdate.ToShortDateString() -eq $todayDate.ToShortDateString()))
{
if(($spoAllSiteProperties.FieldValues.ContainsKey(‘__secondary_contact__’)) -and ($spoAllSiteProperties["__secondary_contact__"] -ne ""))
{
$sUser = $site.RootWeb.EnsureUser($spoAllSiteProperties[‘__Secondary_Contact__’]);
$ctx.Load($sUser);
$ctx.ExecuteQuery()
# Update secondary contact
$site.SecondaryContact = $sUser
$site.SecondaryContact.Update();
$ctx.ExecuteQuery();
}
$ctx.Dispose()
}
}
}
Catch [exception]
{
# Logging the exception in log file
"{0},{1}" -f "Error in SetSecondaryOwner SPO script while traversing in each sitecollection. Site URL= $site.Url", $_.Exception.Message |Add-Content $LogFileName
}
}
#Update Last Run Date CSV for script last run date
Clear-Content $LastRunDateFileName
"{0}" -f $todayDate |Add-Content $LastRunDateFileName
}
Catch [exception]
{
# Logging the exception in log file
"{0},{1}" -f "Error in SetSecondaryOwner SPO script.", $_.Exception.Message |Add-Content $LogFileName
}
finally
{
$ctx.Dispose()
}
We can save the secondary owner values in property bag and then using powershell we can update secondary owner field.
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
#Log File
$DatePostFix = Get-Date -format "MM-dd-yyyy_hh-mm-ss"
$LogFileName = "SetSecondaryOwner_SPO_" + $DatePostFix + ".csv"
$LastRunDateFileName = "SetSecondaryOwner_SPO_LastRunDate.csv"
# User Credentials
$Username="abc@org.com"
$AdminPassword = Read-Host -Prompt "Enter Password" -AsSecureString
## Site URL - Providing the credentials
$AdminUrl="https://sposite.sharepoint.com"
#Retrieve all site collection infos
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $Username, $AdminPassword
Connect-SPOService -Url $AdminUrl -Credential $cred
$sitesCollectionsList = Get-SPOSite
try
{
# Get todays date.
$todayDate = Get-Date
# Get Script last run date
if (!(Test-Path $LastRunDateFileName))
{
"{0}" -f $todayDate.AddDays(-1) |Add-Content $LastRunDateFileName
}
$lastRunFile = Get-Content $LastRunDateFileName
if ([string]::IsNullOrEmpty($lastRunFile)) {
$scriptLastRundate = $todayDate.AddDays(-1).ToString()
}
else
{
$scriptLastRundate = [datetime]$lastRunFile.ToString()
}
#Retrieve and print all sites
foreach ($siteColl in $sitesCollectionsList)
{
try
{
#SPO Client Object Model Context
$ctx=New-Object Microsoft.SharePoint.Client.ClientContext($siteColl.Url)
$ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Username, $AdminPassword)
$site=$ctx.site
$spoRootWeb = $ctx.Web
$ctx.Load($site)
$ctx.Load($spoRootWeb)
$ctx.ExecuteQuery()
#Get the property bag values
$spoAllSiteProperties=$spoRootWeb.AllProperties
$ctx.Load($spoAllSiteProperties)
$ctx.ExecuteQuery()
# Check if Last Review date exist and get the value
$lastReviewdate = ""
if ($spoAllSiteProperties.FieldValues.ContainsKey(‘__reviewedOn_key___’)) {
$lastReviewdate = [datetime]$spoAllSiteProperties[‘__reviewedOn_key___’]
}
# Update Secondary Owner if lastreview date is today's date or script last run date is lesser than the review date
if (!([string]::IsNullOrEmpty($lastReviewdate))) {
if (($scriptLastRundate -lt $lastReviewdate) -or ($lastReviewdate.ToShortDateString() -eq $todayDate.ToShortDateString()))
{
if(($spoAllSiteProperties.FieldValues.ContainsKey(‘__secondary_contact__’)) -and ($spoAllSiteProperties["__secondary_contact__"] -ne ""))
{
$sUser = $site.RootWeb.EnsureUser($spoAllSiteProperties[‘__Secondary_Contact__’]);
$ctx.Load($sUser);
$ctx.ExecuteQuery()
# Update secondary contact
$site.SecondaryContact = $sUser
$site.SecondaryContact.Update();
$ctx.ExecuteQuery();
}
$ctx.Dispose()
}
}
}
Catch [exception]
{
# Logging the exception in log file
"{0},{1}" -f "Error in SetSecondaryOwner SPO script while traversing in each sitecollection. Site URL= $site.Url", $_.Exception.Message |Add-Content $LogFileName
}
}
#Update Last Run Date CSV for script last run date
Clear-Content $LastRunDateFileName
"{0}" -f $todayDate |Add-Content $LastRunDateFileName
}
Catch [exception]
{
# Logging the exception in log file
"{0},{1}" -f "Error in SetSecondaryOwner SPO script.", $_.Exception.Message |Add-Content $LogFileName
}
finally
{
$ctx.Dispose()
}