SharePoint Online: Find All Custom Actions using PowerShell

Requirement: Find All Custom Actions in SharePoint Online

PowerShell to Get All User Custom Actions in SharePoint Online:

Custom Action is a powerful mechanism to add Customization on SharePoint. I have a requirement to prepare the inventory of all custom actions on a particular site, and here is the PowerShell script to find custom actions on a given site.

#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
  
#Set parameter values
$SiteURL="https://crescent.sharepoint.com/"
 
Try{
    #Get Credentials to connect
    $Cred= Get-Credential
    $Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)
  
    #Setup the context
    $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
    $Ctx.Credentials = $Credentials

    #Get All Custom Actions
    $UserCustomActions= $Ctx.Web.UserCustomActions
    $Ctx.Load($UserCustomActions)
    $Ctx.ExecuteQuery()

    If($UserCustomActions.count -gt 0)
    {
        ForEach($CustomActions in $UserCustomActions)
        {
            Write-Host -f Green "Custom Action Name: '$($CustomActions.Name)' ID: $($CustomActions.ID)"
        }
    }
    Else
    {
        write-host -f Yellow "No Custom Actions Found!"
    }
}
Catch {
        write-host -f Red "Error Getting Custom Actions!" $_.Exception.Message
}

This script lists all user custom actions of the given web. You can change the object to site in order to find all custom actions of the site object. E.g., $UserCustomActions= $Ctx.Web.UserCustomActions to $UserCustomActions= $Ctx.Site.UserCustomActions

PowerShell to Find All Custom Actions in SharePoint Online Site Collection: 

Let’s change the above script a bit to iterate through all subsites from the given site collection to get an inventory of all user custom actions for both site and web objects and export our findings to a CSV file.

#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"

Function Get-SPOCustomActions([String]$SiteURL,[String]$Scope)
{  
    Try{
        #Setup the context
        $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
        $Ctx.Credentials = $Credentials

        #Get the Web and Sub Sites
        $Ctx.Load($Ctx.Web)
        $Ctx.Load($Ctx.Web.Webs)
        $Ctx.ExecuteQuery()

        #Get All Custom Actions based on given scope: Site or Web
        If($Scope -eq "Site")
        {
            $UserCustomActions= $Ctx.Site.UserCustomActions
            Write-host -f Yellow "Searching $Scope Scoped Custom Actions at '$SiteURL'"
        }
        ElseIf($Scope -eq "Web")
        {
            $UserCustomActions= $Ctx.Web.UserCustomActions
            Write-host -f Yellow "Searching $Scope Scoped Custom Actions at '$SiteURL"
        }
        $Ctx.Load($UserCustomActions)
        $Ctx.ExecuteQuery()

        $CustomActionsData = @()
        ForEach($CustomAction in $UserCustomActions)
        {
            Write-Host -f Green "Found a Custom Action: '$($CustomAction.Name)' at : $($SiteURL)"
        
            #Get Custom Action Data
            $CustomActionsData += New-Object PSObject -Property @{
                    'Site URL' = $SiteUrl
                    'Custom Action Title' = $CustomAction.Title
                    'Name' = $CustomAction.Name
                    'ID' = $CustomAction.ID
                    'Group' = $CustomAction.Group
                    'Location' = $CustomAction.Location                
                    'Sequence' = $CustomAction.Sequence
                    'Url' = $CustomAction.Url
                    'Scope' = $CustomAction.Scope
                    'ScriptBlock' = $CustomAction.ScriptBlock
                    'ScriptSrc' = $CustomAction.ScriptSrc 
                    }
        }
        #Export the data to CSV
        $CustomActionsData | Export-Csv $ReportOutput -NoTypeInformation -Append
    
        #Get the Root Web's Custom Actions
        If($Scope -eq "Site")
        {         
            #Call the function to get Root Web's Custom Actions
            Get-SPOCustomActions -SiteURL $SiteURL -Scope "Web"   
        }
        Else
        {
            #Iterate through each subsite of the current web
            ForEach ($Subweb in $Ctx.Web.Webs)
            {
                #Call the function recursively 
                Get-SPOCustomActions -SiteURL $Subweb.url -Scope "Web"
            }
        }
    }
    Catch {
        write-host -f Red "Error Generating Custom Actions Report!" $_.Exception.Message
    }
}

#Set parameter values
$SiteURL="https://crescent.sharepoint.com/"

#Get Credentials to connect
$Cred= Get-Credential
$Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)

$ReportOutput = "C:\Temp\CustomActions.csv"
#Delete the Output Report, if exists
if (Test-Path $ReportOutput) { Remove-Item $ReportOutput }

#Call the function 
Get-SPOCustomActions -SiteURL $SiteURL -Scope "Site" 

Get All Custom Actions using PnP PowerShell

To retrieve all custom actions, use the PnP PowerShell cmdlet Get-PnPCustomAction

#Variable
$SiteURL = "https://Crescent.sharepoint.com"

#Connect to PnP Online
Connect-PnPOnline -Url $SiteURL -Interactive

Get-PnPCustomAction -Scope All

You can set the scope to “Site” or “Web” to retrieve site collection or site-specific custom actions.

Salaudeen Rajack

Salaudeen Rajack - SharePoint Expert with Two decades of SharePoint Experience. Love to Share my knowledge and experience with the SharePoint community, through real-time articles!

Leave a Reply

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