Skip to content

PnP PowerShell Compatibility Guide

Last Updated: 2026-04-16 Cesivi Server Version: v281.0+ Document Status: Official Guidance Current Module: CesiviPnP 3.29 (fork of PnP.PowerShell 3.29)


Overview

Cesivi Server supports PnP PowerShell via CesiviPnP — a fork of PnP.PowerShell 3.29 that uses Cesivi.Client instead of Microsoft.SharePoint.Client. This approach eliminates the closed-source CSOM client-side limitations that caused ~30 test skips in earlier versions.

Quick Answer: - ✅ CesiviPnP (recommended): Fork of PnP.PowerShell 3.29, net481, 427P/0F/4S - ⚠️ PnP.PowerShell 3.x (upstream): May work via -AccessToken, not officially tested - ⚠️ PnP PowerShell 1.x/2.x (legacy): Partially compatible, not recommended


What Is CesiviPnP?

CesiviPnP is a fork of PnP.PowerShell 3.29 maintained alongside Cesivi Server. Key differences:

  • Uses Cesivi.Client instead of Microsoft.SharePoint.Client (eliminates CSOM client bugs)
  • Targets net481 (same as the rest of the PnP/CSOM test suite)
  • Runs in isolated AppDomain to prevent static state accumulation between test classes
  • Zero failures — 427P/0F/4S across 39 test classes

Test Coverage (v281.0)

Metric Value
Tests Passing 427
Tests Failing 0
Tests Skipped 4 (1 auto-paging design, 3 Forms-folder/multi-request gaps — tracked)
Test Classes 39
Cmdlet Coverage 224/224 cmdlets (100% of applicable)

Installation

CesiviPnP is built as part of the Cesivi solution:

# Build CesiviPnP module
dotnet build Cesivi.PnP/Cesivi.PnP.csproj

# Module output: bin/Debug/net481/CesiviPnP.psd1

Connection Example

# Import CesiviPnP module
Import-Module "path/to/CesiviPnP.psd1"

# Obtain access token from Cesivi Azure AD mock
$tokenResponse = Invoke-RestMethod -Method Post `
    -Uri "http://localhost:5000/oauth2/v2.0/token" `
    -Body @{
        grant_type    = "client_credentials"
        client_id     = "12345678-1234-1234-1234-123456789012"
        client_secret = "mock-secret"
        scope         = "http://localhost:5000/.default"
    }

# Connect with access token
$accessToken = ConvertTo-SecureString $tokenResponse.access_token -AsPlainText -Force
Connect-PnPOnline -Url "http://localhost:5000" -AccessToken $accessToken

# Use cmdlets normally
Get-PnPWeb
Get-PnPList
Get-PnPListItem -List "Documents"

Helper Function

function Connect-CesiviPnP {
    param(
        [string]$Url = "http://localhost:5000",
        [string]$ClientId = "12345678-1234-1234-1234-123456789012",
        [string]$ClientSecret = "mock-secret"
    )

    $tokenResponse = Invoke-RestMethod -Method Post `
        -Uri "$Url/oauth2/v2.0/token" `
        -Body @{
            grant_type    = "client_credentials"
            client_id     = $ClientId
            client_secret = $ClientSecret
            scope         = "$Url/.default"
        }

    $accessToken = ConvertTo-SecureString $tokenResponse.access_token -AsPlainText -Force
    Connect-PnPOnline -Url $Url -AccessToken $accessToken
    Write-Host "Connected to $Url via CesiviPnP" -ForegroundColor Green
}

Connect-CesiviPnP
$web = Get-PnPWeb
Write-Host "Web Title: $($web.Title)"

Supported Authentication

  • Access Token (-AccessToken) — Via Cesivi OAuth2 mock (recommended)
  • OAuth 2.0 Client Credentials — Service-to-service authentication
  • Username/Password (-Credentials) — NTLM/Basic fallback

Running CesiviPnP Tests

# Run all 33+ PnP test classes with process isolation
bash Scripts/run-pnp-test-batch.sh

# Expected result: 427P/0F/4S — 33+ classes

Individual Test Classes

bash Scripts/test-watchdog.sh 180 Cesivi.Tests.PnP/Cesivi.Tests.PnP.csproj

Filter by Category

dotnet test --filter "FullyQualifiedName~PnpListTests"
dotnet test --filter "FullyQualifiedName~PnpWebTests"
dotnet test --filter "FullyQualifiedName~PnpUserGroupTests"

Cmdlet Coverage Matrix

Fully Supported Categories (100%)

Category Cmdlets Status
Web Get/Set-PnPWeb, Get/Add/Remove-PnPSubWeb ✅ Full
Lists Get/New/Remove-PnPList, Set-PnPList ✅ Full
List Items Get/Add/Set/Remove-PnPListItem ✅ Full
Files Get/Add/Remove-PnPFile, Copy/Move-PnPFile ✅ Full
Folders Get/Add/Remove-PnPFolder ✅ Full
Fields Get/Add/Remove-PnPField, Set-PnPField ✅ Full
Content Types Get/Add/Remove-PnPContentType, Set-PnPContentType ✅ Full
User/Groups Get/New/Remove-PnPGroup, Get/Add/Remove-PnPGroupMember ✅ Full
Permissions Get/Set/Remove-PnPListPermission, Get/Set-PnPUser ✅ Full
Views Get/Add/Remove-PnPView, Set-PnPView ✅ Full
Features Enable/Disable/Get-PnPFeature ✅ Full
Property Bags Get/Set/Remove-PnPPropertyBagValue ✅ Full
Navigation Get/Add/Remove-PnPNavigationNode ✅ Full
Provisioning Get/Apply-PnPProvisioningTemplate ✅ Full
Search Submit-PnPSearchQuery, Invoke-PnPSearchIndexing ✅ Full
Taxonomy Get/New/Remove-PnPTermGroup, Get/New/Remove-PnPTermSet ✅ Full
Recycle Bin Get/Restore/Remove-PnPRecycleBinItem ✅ Full
Alerts Get/Add/Remove-PnPAlert ✅ Full
Webhooks Get/Add/Remove-PnPWebhookSubscription ✅ Full
Role Definitions Get/Add/Remove-PnPRoleDefinition ✅ Full
Publishing Get/Add-PnPPublishingPage, Enable-PnPFeature (publishing) ✅ Full
Site Policies Get/Set-PnPSitePolicy ✅ Full

Partially Supported

Category Status Notes
Workflow ⚠️ Basic Start/stop workflow, not full workflow manager
Managed Metadata ⚠️ Basic Term store operations, not full enterprise MMS
User Profiles ⚠️ Basic Get/Set profile properties
Site Templates ⚠️ Partial Save/Apply-PnPProvisioningTemplate with common templates

Not Supported

Category Notes
SharePoint Online-only cmdlets SPO-specific admin operations
Modern sites (Teams/Communication) Cesivi targets classic SharePoint
Power Platform integration No Power Apps/Flow connectors
Microsoft Graph cmdlets Not implemented

Known Limitations

Auto-Paging Behavior (1 test SKIPPED — By Design)

Cmdlet: Get-PnPListItem -PageSize N Behavior: PnP auto-fetches ALL pages regardless of -PageSize. This is PnP library design, not a bug. Workaround: Filter client-side after retrieval.

Folder PropertyBag with ServerRelativeUrl

Cmdlets: Set-PnPPropertyBagValue -Folder, Get-PnPPropertyBagValue -Folder Root Cause: GetFolderByServerRelativePath() doesn't add ObjectIdentityQuery — CSOM protocol limitation. Workaround: Use web-level PropertyBag operations instead.

Disable-PnPFeature After Enable in Same Session

Root Cause: CSOM-cached feature collection doesn't reflect REST-activated features in same session. Workaround: Create a new PnP connection between Enable and Disable operations.


Frequently Asked Questions

Q: What happened to PnP PowerShell 1.x/2.x support?

CesiviPnP supersedes both. CesiviPnP is based on PnP.PowerShell 3.29 (the current upstream), with Cesivi.Client as the CSOM backend. Earlier attempts to support 1.x/2.x had significant limitations (low coverage, client bugs, Azure AD dependency). CesiviPnP achieves 427P/0F/4S — far better than any earlier attempt.

Q: Can I use upstream PnP.PowerShell 3.x directly?

You may be able to connect using -AccessToken (Cesivi provides OAuth2 mock endpoints). However, the upstream module uses Microsoft.SharePoint.Client which has known static state bugs. Results will vary. CesiviPnP is the supported path.

Q: What OAuth2 endpoints does Cesivi provide?

  • POST {url}/oauth2/v2.0/token — Client credentials flow
  • GET {url}/.well-known/openid-configuration — OpenID metadata
  • GET {url}/oauth2/v2.0/keys — JWKS endpoint

Q: How does CesiviPnP handle authentication?

CesiviPnP uses the same OAuth2 mock that all Cesivi tests use. Pass -AccessToken to Connect-PnPOnline. The token is obtained via client credentials flow against {url}/oauth2/v2.0/token.

Q: What about CSOM directly (without PnP)?

CSOM via Cesivi.Client achieves 100% (580P/0F/7S). Use CSOM for operations not covered by PnP cmdlets. See CSOM Details.

Q: What if I need specific cmdlets not yet implemented?

Options: 1. Use CSOM directly — PnP cmdlets are wrappers around CSOM 2. Use REST API — most operations available via /_api/ 3. Check _docs/features/PNP_POWERSHELL.md for detailed cmdlet list


Resources

  • CesiviPnP Test Suite: Cesivi.Tests.PnP/ — 39 test classes
  • Batch Runner: Scripts/run-pnp-test-batch.sh
  • PnP Area Guide: _project/areas/pnp/INDEX.md
  • Cmdlet Matrix: _docs/features/PNP_CMDLET_MATRIX.md (if exists)
  • Known Limitations: _docs/KNOWN_LIMITATIONS.md
  • Upstream PnP: https://github.com/pnp/powershell

Document Version: 282.0 Last Updated: 2026-04-16 (PLAN-1036 - MASTERPLAN v282.0) Author: Cesivi Server Team