Entra ID

Connect-PnPOnline: Every Way to Authenticate, and When to Use Each

In this post, I am going to go through every way Connect-PnPOnline can authenticate, which ones still work after the September 2024 changes, and which one you should use for what.

There are more than you think. On PnP.PowerShell 2.12.0 there are fifteen. You only need three of them.

See the list for your own version

Do not trust a blog post for this, including this one. The parameter sets change between releases and the documentation online describes whichever version was current when it was written. Ask your own machine:

Get-Command Connect-PnPOnline -Syntax

Or just the authentication-related parameters:

(Get-Command Connect-PnPOnline).Parameters.Keys |
    Where-Object { $_ -match 'Interactive|WebLogin|Device|Certificate|Secret|Managed|Token' } |
    Sort-Object

On 2.12.0 that gives:

AccessToken
CertificateBase64Encoded
CertificatePassword
CertificatePath
ClientSecret
DeviceLogin
Interactive
ManagedIdentity
UserAssignedManagedIdentityAzureResourceId
UserAssignedManagedIdentityClientId
UserAssignedManagedIdentityObjectId
UseWebLogin

The three you will actually use

Interactive – you, at a keyboard, signing in through a browser. This is the normal one.

Connect-PnPOnline `
    -Url "https://contoso.sharepoint.com/sites/Demo" `
    -ClientId "11111111-2222-3333-4444-555555555555" `
    -Interactive

Certificate – a scheduled script with nobody watching. No prompts, no password.

Connect-PnPOnline `
    -Url "https://contoso.sharepoint.com/sites/Demo" `
    -ClientId "11111111-2222-3333-4444-555555555555" `
    -Tenant contoso.onmicrosoft.com `
    -CertificatePath "C:\certs\PnP.pfx" `
    -CertificatePassword (ConvertTo-SecureString "yourpassword" -AsPlainText -Force)

Managed identity – running inside Azure Automation or an Azure Function. No secret to store anywhere, which is why it is the best option when you can use it.

Connect-PnPOnline -Url "https://contoso.sharepoint.com/sites/Demo" -ManagedIdentity

That is the whole decision. Interactive when you are there, certificate when you are not, managed identity when you are in Azure.

What stopped working in September 2024

Two things, and they produce the same unhelpful error.

Interactive with no ClientId:

Connect-PnPOnline -Url "https://contoso.sharepoint.com/sites/Demo" -Interactive
WARNING: Connecting with -Interactive used the PnP Management Shell multi-tenant
App Id for authentication. As of September 9th, 2024 this option is not available
anymore.

Specified method is not supported.

Username and password:

$cred = Get-Credential
Connect-PnPOnline -Url "https://contoso.sharepoint.com/sites/Demo" -Credentials $cred
WARNING: As of September 9th, 2024 the option to use the PnP Management Shell app
registration for authentication is not available anymore.

Specified method is not supported.

Both were leaning on the shared PnP Management Shell app registration that Microsoft deleted. Register your own and both come back to life – I covered that in Connect-PnPOnline: Specified method is not supported.

-UseWebLogin still works, and it is the only one that needs nothing

This surprised me. I expected it to be gone:

Connect-PnPOnline -Url "https://contoso.sharepoint.com/sites/Demo" -UseWebLogin
WARNING: Consider using -Interactive instead, which provides better functionality.

And then it connects. No ClientId, no app registration, nothing.

It works because -UseWebLogin never used the PnP Management Shell app in the first place. It signs you in with browser cookies, so the app being deleted did not affect it.

The important thing to note is that this is not a recommendation. It is deprecated, the warning is telling you so, it does not carry a Microsoft Graph token, and it will go eventually. But if you have inherited a broken script, need it working in the next ten minutes, and cannot get an app registration approved today, this is your bridge.

Then go and register the app properly.

Device login needs one extra parameter

Device login prints a code, you enter it at microsoft.com/devicelogin on any device, and the script continues. It is what you use on a machine with no browser, or over a remote session.

If you pass -ClientId you must also pass -Tenant, or you get this:

Please specify -Tenant with either the tenant id or hostname.
Unable to connect using provided arguments

So:

Connect-PnPOnline `
    -Url "https://contoso.sharepoint.com/sites/Demo" `
    -ClientId "11111111-2222-3333-4444-555555555555" `
    -Tenant contoso.onmicrosoft.com `
    -DeviceLogin

The rest

The other parameter sets are real but narrow:

  • -AccessToken – you already got a token some other way and just want PnP to use it.
  • -ClientSecret – app-only with a secret instead of a certificate. Works for some endpoints, but certificates are the supported path for SharePoint.
  • -EnvironmentVariable – reads the client ID from an environment variable so it is not sitting in your script.
  • -OSLogin – uses the account you are already signed into Windows with.
  • -AzureADWorkloadIdentity – for workloads running in Kubernetes.
  • -SPOManagementShell and -CurrentCredentials – legacy, do not start anything new with these.

If you are writing something new, use interactive while you build it and switch to a certificate when you schedule it. That covers almost everything 🙂

Connect-PnPOnline: Specified Method Is Not Supported

You run a PnP PowerShell script that worked fine for years, and you get this:

Connect-PnPOnline: Specified method is not supported.

Or, depending on which version of the module you are on, this one:

AADSTS700016: Application with identifier '31359c7f-bd7e-475c-86db-fdb8c937548e'
was not found in the directory.

Both mean the same thing. Nothing is wrong with your script. The app registration it was quietly relying on does not exist any more.

What happened

Until September 2024, PnP PowerShell shipped with a multi-tenant Entra ID app called PnP Management Shell, and every tenant could use it without registering anything. That is the app ID in the error above. The PnP team announced on 21 August 2024 that it was going away, and deleted it on 9 September 2024.

So Connect-PnPOnline -Url ... -Interactive with no -ClientId has nothing to authenticate against. You now need your own app registration in your own tenant.

This is a good change, even though it broke everyone’s scripts on the same day. That shared app had far more permissions than any one script needed.

The fix – register your own app

PnP gives you a cmdlet for this, so you do not have to click through the Entra portal. Run this once per tenant:

Register-PnPEntraIDAppForInteractiveLogin `
    -ApplicationName "PnP.PowerShell" `
    -Tenant contoso.onmicrosoft.com `
    -Interactive

The one to watch here is -Interactive. On PnP.PowerShell 2.x you must include it, or you get this instead:

Register-PnPEntraIDAppForInteractiveLogin: Parameter set cannot be resolved
using the specified named parameters.

Which is not a helpful message when you are already fixing a different error. Check what you are on with Get-Module PnP.PowerShell -ListAvailable, and if you are ever unsure of the parameters for your version, Get-Command Register-PnPEntraIDAppForInteractiveLogin -Syntax tells you rather than the documentation, which describes whichever version is current.

You will then see a warning that no permissions were specified so defaults are being used, a line confirming the app was created with its ID, and a 30 second pause while Entra ID catches up before the consent window opens. Sign in and accept.

When it finishes it prints a Client ID – copy that, you need it every time you connect from now on.

The important thing to note is you need to be a Global Administrator or Application Administrator to run this, because it is creating an app registration and granting consent. If you are not, this is the point where you go and talk to whoever is.

Then connect like this:

Connect-PnPOnline `
    -Url "https://contoso.sharepoint.com/sites/Demo" `
    -ClientId "11111111-2222-3333-4444-555555555555" `
    -Interactive

That is it. Every script you have needs that one extra parameter.

If your script runs unattended

Interactive login is no good for anything scheduled. For that you want app-only with a certificate:

Register-PnPEntraIDApp `
    -ApplicationName "PnP.PowerShell.Unattended" `
    -Tenant contoso.onmicrosoft.com `
    -OutPath C:\certs `
    -DeviceLogin

That writes a certificate to C:\certs. Then:

Connect-PnPOnline `
    -Url "https://contoso.sharepoint.com/sites/Demo" `
    -ClientId "11111111-2222-3333-4444-555555555555" `
    -Tenant contoso.onmicrosoft.com `
    -CertificatePath "C:\certs\PnP.PowerShell.Unattended.pfx" `
    -CertificatePassword (ConvertTo-SecureString -String "yourpassword" -AsPlainText -Force)

Keep that certificate somewhere sensible. Anyone who has the file and the password has whatever permissions you granted the app.

Two things that catch people out

You still get an error after registering. Nine times out of ten the app is missing a permission, or the permission is there but nobody clicked Grant admin consent. Open the app in Entra admin center > App registrations > API permissions and check for the warning triangle.

Both cmdlets only add a small default set of permissions. If your script does something beyond reading sites, add what you need explicitly:

Register-PnPEntraIDAppForInteractiveLogin `
    -ApplicationName "PnP.PowerShell" `
    -Tenant contoso.onmicrosoft.com `
    -SharePointDelegatePermissions "AllSites.FullControl" `
    -GraphDelegatePermissions "User.Read.All"

Register once, put the Client ID somewhere your scripts can read it, and you are back to writing PowerShell instead of fixing it 🙂

If you are updating old scripts, my earlier post on copying SharePoint Online web part settings with PnP PowerShell is one of the ones I had to go back and fix – the connection line is the only part that changed.