Saturday, February 13, 2016

Powershell script to edit SPO site secondary owner using property bag values

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()
   }