PnP PowerShell: Getting Started Guide (Including GCC High)
If you’ve searched for “connect-pnponline,” you’re probably staring at a PowerShell prompt right now. You need to manage SharePoint sites, update list permissions, provision pages, configure Teams settings, or automate something that clicking through the SharePoint admin center is too slow for.
Microsoft’s documentation gives you the cmdlet reference. What it doesn’t give you is a straight answer on which authentication method to use, how app registration works after the September 2024 breaking change, or how to make any of it work in GCC High. That’s what this guide is for.
This is the third in our PowerShell connectivity series — if you also work with Microsoft Graph or Exchange Online, see our Connect-MgGraph guide and Connect-ExchangeOnline guide.
What Is PnP PowerShell (and Do You Need It?)
People confuse PnP PowerShell with the SharePoint Online Management Shell. They’re different tools for different jobs.
SharePoint Online Management Shell (Connect-SPOService): Tenant-level admin. Site collection provisioning, external sharing policies, tenant settings. Connects to contoso-admin.sharepoint.com. About 200 cmdlets. Windows only.
PnP PowerShell (Connect-PnPOnline): Site-level operations. Lists, libraries, permissions, pages, search, taxonomy, provisioning templates. Also covers Teams, Planner, and Microsoft Graph. 700+ cmdlets. Cross-platform — Windows, macOS, Linux.
Quick decision: if you’re managing tenant settings, use SPO Management Shell. If you’re managing sites and content, use PnP PowerShell. Most people need PnP.
Install the Module
Prerequisite: PowerShell 7.4 or later. Not Windows PowerShell 5.1 — that’s a common mistake. The last version that supported 5.1 was v1.12.0, which is no longer maintained.
Check if you already have it:
Get-Module PnP.PowerShell -ListAvailable If that returns nothing, install it:
Install-Module PnP.PowerShell -Scope CurrentUser If you have an older version installed and things aren’t working, update first:
Update-Module PnP.PowerShell -Scope CurrentUser PnP PowerShell works on Windows, macOS, and Linux — anywhere PowerShell 7.4+ runs.
Register Your Own App (Required Since September 2024)
This is the section most guides are missing. On September 9, 2024, Microsoft deleted the multi-tenant “PnP Management Shell” Entra ID app. If you’re following a guide that tells you to consent to the PnP Management Shell app, that guide is outdated. You must register your own single-tenant app registration now.
Two automated paths, depending on your use case:
For interactive use (recommended):
Register-PnPEntraIDAppForInteractiveLogin -ApplicationName "PnP PowerShell" `
-Tenant contoso.onmicrosoft.com This creates the app, configures redirect URIs, adds default permissions, and prompts you for consent.
For app-only / certificate-based auth:
Register-PnPEntraIDApp -ApplicationName "PnP Automation" `
-Tenant contoso.onmicrosoft.com `
-OutPath c:certs `
-DeviceLogin This creates the app, generates certificate files (.pfx + .cer), and configures app-only permissions.
Manual setup (if you prefer the portal):
- Entra ID → App registrations → New registration
- Note the Application (client) ID
- Authentication → Add platform → Mobile and desktop → Add
http://localhostas a redirect URI - API permissions → Add SharePoint permissions (delegated or application)
- Grant admin consent
API permissions by scenario:
| Scenario | Permissions |
|---|---|
| Read SharePoint content | Sites.Read.All (SharePoint) |
| Manage SharePoint content | Sites.FullControl.All (SharePoint) |
| Granular site access (app-only) | Sites.Selected (SharePoint) + per-site grants |
| Teams / Planner / Groups | Add Microsoft Graph permissions as needed |
Note: SharePoint Sites.Selected is different from Microsoft Graph Sites.Selected — they’re independent permissions and granting one doesn’t imply the other.
Interactive Authentication
This is what you use when you’re sitting at your desk running commands manually:
Connect-PnPOnline -Url "https://contoso.sharepoint.com/sites/MySite" `
-Interactive `
-ClientId "your-app-id" A browser opens. You sign in. MFA is handled automatically. You’re connected.
Three things to note:
-ClientIdis required. There’s no default PnP Management Shell app anymore.-Urlis the specific SharePoint site you’re connecting to — not the tenant admin URL.- Each PnP connection is scoped to one site. To work with a different site, connect again.
To verify your connection:
Get-PnPConnection Other interactive options:
-DeviceLogin— for headless servers or SSH sessions. Sign in on another device with a code.-OSLogin— Windows-native Web Account Manager SSO (Windows 10 1703+). Uses the logged-in Windows identity.-Credentials— username and password directly. Doesn’t support MFA — avoid unless you have a specific reason.
Certificate-Based Authentication (For Automation)
The recommended method for scheduled scripts, Azure Functions, and CI/CD pipelines. No browser, no human, no secrets to leak.
Generate a Certificate
$cert = New-PnPAzureCertificate -OutPfx ./PnPAutomation.pfx -OutCert ./PnPAutomation.cer Upload the .cer file to your app registration under Certificates & secrets > Certificates > Upload certificate.
Connect
Connect-PnPOnline -Url "https://contoso.sharepoint.com/sites/MySite" `
-ClientId "your-app-id" `
-Tenant "contoso.onmicrosoft.com" `
-CertificatePath "./PnPAutomation.pfx" No browser prompt. No interactive sign-in. The certificate authenticates the app directly.
Three Ways to Reference the Certificate
| Method | Parameter | Platform |
|---|---|---|
| File path (.pfx) | -CertificatePath | All platforms |
| Windows cert store | -Thumbprint | Windows only |
| Base64 string | -CertificateBase64Encoded | All platforms (good for env vars / Key Vault) |
Important: Client secrets are not supported for PnP PowerShell app-only auth. Certificates are required.
Managed Identity (Azure Only)
If your script runs in Azure — Automation Account, Azure Function, Azure VM — managed identities are the cleanest option:
Connect-PnPOnline -Url "https://contoso.sharepoint.com/sites/MySite" -ManagedIdentity That’s it for system-assigned managed identities. For user-assigned:
Connect-PnPOnline -Url "https://contoso.sharepoint.com/sites/MySite" `
-ManagedIdentity `
-UserAssignedManagedIdentityClientId "your-client-id" Important: You need to assign SharePoint API permissions to the managed identity via PowerShell — you can’t do it through the portal. Same pattern as assigning Graph permissions to a managed identity.
If You’re in GCC High
Everything above works in GCC High with two critical additions: the -AzureEnvironment flag and .sharepoint.us URLs.
Key Differences from Commercial
| Commercial | GCC High | |
|---|---|---|
| SharePoint URL | contoso.sharepoint.com | contoso.sharepoint.us |
| Admin URL | contoso-admin.sharepoint.com | contoso-admin.sharepoint.us |
| Authentication | login.microsoftonline.com | login.microsoftonline.us |
| Graph endpoint | graph.microsoft.com | graph.microsoft.us |
| Tenant domain | contoso.onmicrosoft.com | contoso.onmicrosoft.us |
Interactive in GCC High
Connect-PnPOnline -Url "https://contoso.sharepoint.us/sites/MySite" `
-Interactive `
-ClientId "your-app-id" `
-Tenant "contoso.onmicrosoft.us" `
-AzureEnvironment USGovernmentHigh Without -AzureEnvironment USGovernmentHigh, the module tries to authenticate against the commercial endpoint. Your GCC High credentials won’t work there. You’ll get an error that looks like an auth failure when it’s really just pointing at the wrong cloud.
Certificate-Based in GCC High
Connect-PnPOnline -Url "https://contoso.sharepoint.us/sites/MySite" `
-ClientId "your-app-id" `
-Tenant "contoso.onmicrosoft.us" `
-CertificatePath "./PnPAutomation.pfx" `
-AzureEnvironment USGovernmentHigh Managed Identity in GCC High
Connect-PnPOnline -Url "https://contoso.sharepoint.us/sites/MySite" `
-ManagedIdentity `
-AzureEnvironment USGovernmentHigh The AzureEnvironment Values
| Cloud | -AzureEnvironment Value |
|---|---|
| Commercial | Production (default) |
| GCC | USGovernment |
| GCC High | USGovernmentHigh |
| DoD | USGovernmentDoD |
Every Module Has Its Own Flag
This is where government cloud PowerShell gets confusing. Every Microsoft PowerShell module has a different parameter name and different values for the same concept. Here’s the cheat sheet:
| Module | Parameter | GCC High Value |
|---|---|---|
| PnP PowerShell | -AzureEnvironment | USGovernmentHigh |
| Microsoft Graph | -Environment | USGov |
| Exchange Online | -ExchangeEnvironmentName | O365USGovGCCHigh |
| Azure (Az) | -Environment | AzureUSGovernment |
| SharePoint Online Mgmt | -Url | https://contoso-admin.sharepoint.us |
Five modules, four different parameter names, four different values. Nobody publishes this table, so you end up guessing or searching each module’s docs individually.
Critical GCC High Gotcha: Client Secrets Don’t Work
If you try app-only auth with a client secret in GCC High, you’ll get:
AADSTS900382: Confidential Client is not supported in Cross Cloud request
Certificate-based auth is the only reliable path for app-only in GCC High. This isn’t a PnP limitation — it’s an Entra ID restriction in government cloud environments.
App Registrations in GCC High
When you create the app registration, you create it in the Azure Government portal (portal.azure.us), not the commercial portal. The process is identical, but the app exists in the government cloud. If you accidentally create the app in the commercial portal, you’ll get AADSTS700016: Application not found — the app exists in a different cloud than your tenant.
You can also use the PnP cmdlet:
Register-PnPEntraIDApp -ApplicationName "PnP Automation" `
-Tenant contoso.onmicrosoft.us `
-OutPath c:certs `
-DeviceLogin `
-AzureEnvironment USGovernmentHigh PowerShell Profile Tip
If you work in GCC High daily, set the environment as a default so you never forget it:
# Add to your PowerShell profile ($PROFILE)
$PSDefaultParameterValues['Connect-PnPOnline:AzureEnvironment'] = 'USGovernmentHigh' Now every Connect-PnPOnline call in that shell session defaults to GCC High. Combine this with the same trick for Microsoft Graph and Exchange Online to cover all three modules.
Common Errors and Fixes
“AADSTS65001: The user or administrator has not consented to use the application”
You’re trying to use the old PnP Management Shell multi-tenant app — it was deleted in September 2024. Register your own app registration and use the -ClientId parameter.
“AADSTS900382: Confidential Client is not supported in Cross Cloud request”
Client secret + GCC High. This combination doesn’t work. Switch to certificate-based auth.
“The module could not be loaded” / “Connect-PnPOnline is not recognized”
You’re on Windows PowerShell 5.1 (needs 7.4+), or the module isn’t installed. Run pwsh --version to verify you’re in PowerShell 7, then Install-Module PnP.PowerShell -Scope CurrentUser.
“AADSTS50076: Due to a configuration change… you must use multi-factor authentication”
You’re using -Credentials (username/password) with an account that requires MFA. Switch to -Interactive or -DeviceLogin.
“403 Forbidden” after connecting
Missing SharePoint API permissions or admin consent not granted on your app registration. Check that you’ve added the right SharePoint permissions and clicked “Grant admin consent” in the portal.
“AADSTS700016: Application with identifier ‘xxx’ was not found”
Your app registration doesn’t exist in the tenant you’re connecting to. In GCC High, this almost always means you created the app in the commercial portal (portal.azure.com) instead of the government portal (portal.azure.us). Verify at portal.azure.us.
Disconnecting
When you’re done:
Disconnect-PnPOnline PnP PowerShell can only maintain one connection at a time. If you need to connect to a different site or tenant, either disconnect first or just run a new Connect-PnPOnline — it replaces the existing connection automatically.
Which Method Should You Use?
| Scenario | Method | Why |
|---|---|---|
| Ad-hoc admin tasks | Interactive (-Interactive) | Simple, MFA supported |
| Scheduled scripts on a server | Certificate-based (-CertificatePath) | No secrets, no human needed |
| Azure Automation / Functions | Managed Identity | Zero credential management |
| Headless server / SSH session | Device code (-DeviceLogin) | Sign in on another device |
| Granular per-site access | Certificate + Sites.Selected | Least privilege for automation |
If you’re in GCC High, add -AzureEnvironment USGovernmentHigh to every single one of these. And use .sharepoint.us URLs.
Need help connecting PnP PowerShell to GCC High, building SharePoint automation for your government tenant, or migrating to GCC High in the first place? That’s what we do. Whether it’s CMMC compliance consulting, managed compliance services, or hands-on PowerShell automation, we work in government cloud environments every day.