Introduction

It's a little tricky to get all SharePoint Online Site or Web features using CSOM and PowerShell script. Doing it in C# is easy because using LINQ expression is easy. Of course, we could do it in PS as well but it's too much code and not for Admin scripters with no development background. Let's see the PowerShell script which retrieves SP online site or web features properties.

Solution

1. Load the CSOM Assemblies:
 a. Microsoft.SharePoint.Client.dll
 b. Microsoft.SharePoint.Client.Runtime.dll
2. Define a function and name it as desired. In our case its Get-xSPOFeature
3. Define three parameters:
 a. URL - Datatype URI
 b. Credential - Decorate with [System.Management.Automation.CredentialAttribute()] and type is PSCredential.
 c. Scope - Accepts only Site and Web [ValidateSet()] attribute is defined.
4. Process Block:
 a. Instantiate the ClientContext Object.
 b. Loop through the Site and Features.
 c. Declare a switch statement and allow users to pick their choice.

Usage

Get-xSPOFeature -Url https://contoso.sharepoint.com/ -Scope SiteFeature
 
 

Note: The above usage is just an example. Since the URL parameter accepts values from pipeline by property name we can combine two cmdlets and get the feature details. For now, we will see few more examples in the output section.

Output

The sample output is illustrated in the below image. Of course, we can select the required property!

Get-xSPOFeature -Url https://contoso.sharepoint.com/ -Scope SiteFeature


Get-xSPOFeature -Url https://contoso.sharepoint.com/ -Scope WebFeature |
Select DisplayName , DefinitionID | Select -First 5


Okay, now let's see a small tip to select properties by tab completion to select properties. Please note we haven't included it in the code. This is just a tip! If you are interested don't hesitate to add it in the code below the [CmdletBindingAttribute()].
Output type attribute works in advanced and simple functions. Just leave it to PowerShell to take care of IT Professional needs…. As always tab completion. 
Get-xSPOFeature -Url https://contoso.sharepoint.com/ -Scope WebFeature | Select DisplayName, DefinitionID



Code


Import-Module C:\Temp\Microsoft.SharePoint.Client.dll
Import-Module C:\Temp\Microsoft.SharePoint.Client.Runtime.dll
function Get-xSPOFeature {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)]
        [uri]
        $Url,
        [Parameter(Mandatory)]
        [System.Management.Automation.CredentialAttribute()]
        [pscredential] 
        $Credential,
        [Parameter(Mandatory,ValueFromPipeline)]
        [ValidateSet("SiteFeature" , "WebFeature")]
        $Scope)
    process {
        $SPOClientContext = [Microsoft.SharePoint.Client.ClientContext]::new($Url)
        $SPOClientContext.Credentials = [Microsoft.SharePoint.Client.SharePointOnlineCredentials]::new($credential.UserName,$credential.Password)
        switch ($Scope) {
            "SiteFeature" {
                $SiteFeatureCollection = $SPOClientContext.Site.Features
                $SPOClientContext.Load($SiteFeatureCollection)
                $SPOClientContext.ExecuteQuery()
                foreach($SiteFeature in $SiteFeatureCollection) {
                    $SiteFeature.Retrieve("DisplayName")
                    $SPOClientContext.Load($SiteFeature)
                    $SPOClientContext.ExecuteQuery()
                    $SPOClientContext.Dispose()
                    $SiteFeature
                }
            }
            "WebFeature" {
                $WebFeatureCollection = $SPOClientContext.Web.Features
                $SPOClientContext.Load($WebFeatureCollection)
                $SPOClientContext.ExecuteQuery()
                foreach($webfeature in $WebFeatureCollection) {
                    $webfeature.Retrieve("DisplayName")
                    $SPOClientContext.Load($webfeature)
                    $SPOClientContext.ExecuteQuery()
                    $SPOClientContext.Dispose()
                    $webfeature
                }
            }
        }
    }
}