This topic shows a simple script module to extend SharePoint PnP and add your own custom methods. I have prepared couple of methods, read the site permissions and add list item attachments. The assumption is you have already connected to the site with Connect-PnPOnline command.

Here are the steps to create a custom script module in PowerShell

  1. Create a file with .psm1 extenstion (I named it as PnPX.psm1)
  2. Goto C:\Program Files\WindowsPowerShell\Modules and create a folder. The folder name and file name should be same.. hence the folder name would be PnPX
  3. Prepare your method (for ex: Get-PnPPermissions)

You can add more methods on the same file.

Please ensure you connected to PnPOnline before running any command.

Get-PnPPermissions - Fetches site permissions

Set-PnPListItemAttachment - Adds list item attachment. Pass ListItem and FilePath as parameters. No error handling. (for ex: if attachment exists with same name)

New-PnPListCustomTemplate - Creates new list from custom template. The assumption is the custom template is already available in "List Templates"

Note: When you make changes to the code on this file please run Import-Module PnPX -Force to ensure the changes are reflected in current session.


Function Get-PnPPermissions([switch]$IncludeLimitedAccess) 
    $ctx = (Get-PnPSite).Context 
    $web = $ctx.Web 
    $properties = @{Name=''Type = ''; PermissionLevels = ''} 
    $objectTemplate = New-Object -TypeName PSObject -Property $properties 
    $permissionCollection = $web.RoleAssignments | %{ 
        $roles = ($_.RoleDefinitionBindings | Select -ExpandProperty Name) -join ", " 
        $objectCurrent = $objectTemplate.PSObject.Copy() 
        $objectCurrent.Name = $_.Member.Title 
        $objectCurrent.Type = $_.Member.PrincipalType 
        if($IncludeLimitedAccess) { 
            $objectCurrent.PermissionLevels = $roles 
        else {             
            $roles = $roles -replace ", Limited Access""" 
            $roles = $roles -replace "Limited Access, """ 
            $roles = $roles -replace "Limited Access""" 
            $objectCurrent.PermissionLevels = $roles 
    if(-Not $IncludeLimitedAccess) { 
        $permissionCollection = $permissionCollection | ?{$_.PermissionLevels -ne ""} 
    $permissionCollection | Sort-Object Name | ft –AutoSize 
Function Set-PnPListItemAttachment 
    $fileName = Split-Path $FilePath -Leaf 
    $fileStream = New-Object IO.FileStream($filePath,[System.IO.FileMode]::Open) 
    $attachmentInfo = New-Object -TypeName Microsoft.SharePoint.Client.AttachmentCreationInformation 
    $attachmentInfo.FileName = $fileName 
    $attachmentInfo.ContentStream = $fileStream 
    $attchedFile = $Item.attachmentFiles.Add($attachmentInfo) 
    Invoke-PnPQuery #-ErrorAction Ignore 
Function New-PnPListCustomTemplate($TemplateName$ListName#ListName is optional 
    $ctx = Get-PnPContext 
    $site = (Get-PnPSite) 
    $web = (Get-PnPWeb) 
    $listTemplates = $site.GetCustomListTemplates($web) 
    $ctx.Load($listTemplates# or $site.Context.Load 
    $listTemplate = $listTemplates | ? Name -eq $TemplateName 
    $listCreationInfo = New-Object Microsoft.SharePoint.Client.ListCreationInformation     
    $listCreationInfo.Title = if($ListName -ne $null) { $ListName } else { $TemplateName } 
    $listCreationInfo.ListTemplate = $listTemplate 
 Sample output