Install PnP PowerShell and Connect to SharePoint Online
Installation of PnP PowerShell can be done in a single line. It is the connection part that will give problems to someone who uses an old script, as starting from September 2024, app registration is required, which previously wasn’t required.
All the commands were run using PowerShell 7.5.8 version along with PnP.PowerShell 2.12.0. This output was generated by my machine and not by the documentation.
Install the module
Install-Module PnP.PowerShell -Scope CurrentUser
-Scope CurrentUser It gets installed on your profile level and therefore no administrator rights are required for running PowerShell.
If you have PnP installed for some time then you may get this instead of installing
WARNING: Version '2.12.0' of module 'PnP.PowerShell' is already installed at
'C:\Program Files\WindowsPowerShell\Modules\PnP.PowerShell\2.12.0'. To install
version '3.3.0', run Install-Module and add the -Force parameter.
That’s not an error message. The module found an older version of itself, installed system wide and did not want to overwrite it. Use -Force if you still want the newer version to be placed right next to the old one.
To check your current installation use the following command
Get-Module PnP.PowerShell -ListAvailable | Select-Object Name, Version, ModuleBase
Name Version ModuleBase
---- ------- ----------
PnP.PowerShell 2.12.0 C:\Program Files\WindowsPowerShell\Modules\PnP.PowerShell
A good idea to start with, since the syntax of some of the cmdlets was altered from 2.x to 3.x, and more than half the online guides available do not specify which version they refer to.
You need an app registration first
This is the part that catches everyone coming back to an old script. You cannot just connect any more:
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.
The red line is what everyone copies into Google. The solution to the problem is in the yellow warning above the red line that most people ignore when scrolling down.
Register your application once per tenant:
Register-PnPEntraIDAppForInteractiveLogin `
-ApplicationName "PnP.PowerShell" `
-Tenant contoso.onmicrosoft.com `
-Interactive
On 2.x you must include -Interactive or you get an unhelpful “Parameter set cannot be resolved”. I wrote that up separately in Connect-PnPOnline: Specified method is not supported.
Copy the Client ID it gives you at the end. You need it every single time from now on.
Connect
Connect-PnPOnline `
-Url "https://contoso.sharepoint.com/sites/Demo" `
-ClientId "b1539324-4fa0-4bf0-8c45-949d49fbe112" `
-Interactive
Your browser opens, you sign in, and the command finishes with no output at all. That is normal, PnP tells you nothing when it works.
Check it actually connected
Because it says nothing on success, get into the habit of confirming:
Get-PnPWeb | Select-Object Title, Url, Id
Title : PowerShell Demo
Url : https://contoso.sharepoint.com/sites/Demo
Id : cfa3cc52-ce17-4c52-a7b8-89ae0c4f66e6
And if you want to see what you are connected as:
Get-PnPConnection | Select-Object Url, ConnectionType, ClientId
Url : https://contoso.sharepoint.com/sites/demo
ConnectionType : O365
ClientId : a0748433-4fa0-4bf0-8c45-949d49fbe112
The first thing everyone runs, and the first surprise
Get-PnPList | Select-Object Title, ItemCount, Hidden
On a site where I had made exactly four lists, that returned nineteen:
Title ItemCount Hidden
----- --------- ------
appdata 0 True
Composed Looks 18 True
Departments 4 False
Documents 0 False
Master Page Gallery 175 True
Project Documents 9 False
Projects 25 False
Site Pages 1 False
Style Library 0 False
TaxonomyHiddenList 0 True
Theme Gallery 41 True
User Information List 9 True
Web Part Gallery 6 True
Most of those are system lists SharePoint creates for itself. You almost always want:
Get-PnPList | Where-Object { -not $_.Hidden } | Select-Object Title, ItemCount
The same thing happens with folders. Listing a document library gives you a Forms folder you did not create:
Name Type
---- ----
Archive Folder
Contracts Folder
Forms Folder
Reports Folder
The Forms folder contains all the forms pages within the library and exists in each library at each site. In case you are looping over folders in order to do something, filter out this folder; otherwise your script would attempt to process it.
Disconnect when you are done
Disconnect-PnPOnline
Although not strictly necessary, this becomes very helpful when you need to switch between different tenants during a single session.