PowerShell is a command-line shell and scripting language for managing systems and automating tasks. It has become an essential tool for administrators and power users across many platforms (including Microsoft 365). It offers a robust scripting environment for automating tasks and managing systems.
One common area where PowerShell shines is in administrating and customising SharePoint environments (working with sites, site collections, content types, lists, users and more).
To start using PowerShell for administration tasks, the learning curve is not hugely steep (you can simply copy and paste scripts to perform tasks in many cases) but as with any new tool you are getting used to, there are a good number of dead ends to go down before you get it right.
In this blog, I want to share some tricks I found when using PowerShell with SharePoint for the first time to hopefully help speed up your success if you are using PowerShell as a beginner like me.
Why Use PowerShell With SharePoint?
First up, it's important to ask yourself whether you need to reach for PowerShell? The Modern SharePoint user interface offers lots of customisation. You can use the Admin portal for SharePoint to set up, inspect and remove many elements that underpin your site. So why reach for a scripting language when it’s largely point-and-click already?
There are many occasions where single 'manual' actions fall short of what you need or are impractical at scale. This is where you can consider automating processes using scripts. Examples might be:
- Site provisioning: Setting up sites at scale with regular policies, permissions and structures can be done as one off activities set on repeat for someone. Or you can script them.
- Task Scheduling: You can schedule routine tasks like data archiving, report generation, or other maintenance activities.
- Reporting and Auditing: Generate reports on various SharePoint activities such as user activity, storage usage, or permission settings. This is crucial for compliance and auditing purposes.
Digging into this last point, you can find out a lot of data about your SharePoint site using scripts.
I’m going to dig into just one example of reporting and auditing in this blog. We’ll investigate where a re-usable list structure called a “Content Type” has been implemented across our site using PowerShell. This is useful when you want to remove/add or change the way your lists might be structured and want to know the potential impact before making changes.
How To Run PowerShell From Windows
For running PowerShell scripts, you need an Interface to write and execute them from. Windows provides a native PowerShell interface (type PowerShell into your Search bar and look at the start menu items). There is also something called the PowerShell ISE (integrated Scripting Environment) as well as an IDE (Integrated Development Environment).
If you are familiar with VSCode, there is also a PowerShell plugin you can install to help script and run operations.
While all of these (and more) exist and there are many ways to run your scripts. I focussed on the path of least resistance for a beginner. There may be other better options – I’d love to hear about them – but I know this worked for me so it’s my 2nd tip for now.
The PnP.PowerShell module (more on this later) works best with one particular interface called Power Shell 7. Which can be installed by following the instructions found here: https://learn.microsoft.com/en-gb/powershell/scripting/install/installing-powershell.
This version of PowerShell is recommended due to its cross-platform capabilities and enhanced features. Once you download from the link provided, open it up and you should see a screen much like this one.
If you’re planning on writing and editing scripts that contain more than a few lines. you’ll be well served by also installing Visual Studio Code (VSCode). It’s recommended for its excellent PowerShell extension and debugging features.
I used VSCode to put together and validate the multi-line script used later on and then saved to a temporary folder – from which I then used PowerShell 7 as the environment to run the script from.
You can try running the same script inside VSCode to see what happens. The advantage of using PowerShell 7 is that all the required dependencies and modules already exist so there are no additional elements to install other than those I will go on to mention.
2 Modules To Use With SharePoint In PowerShell (and the second works best)
PowerShell is a scripting language that offers up lot of ‘tools’ that have been already built for you to use. These tools come packaged in what are called modules. Within modules are the operations you can run and use called "cmdlets" – pronounced command-lets.
When working with SharePoint, you generally have three options for PowerShell modules.
Firstly you have SharePoint’s native (i.e. provided by Microsoft) PowerShell module – “Microsoft.Online.SharePoint.PowerShell” – this is for SharePoint Administrators who want to manage SharePoint settings at the organisation level and site collection level. You can read more about this module here:
Secondly, for working with the objects within SharePoint sites, you can use SharePoint’s “Client Side Object Model” (CSOM) in PowerShell by installing Microsoft’s SharePoint Online Client Components SDK.
There is an excellent guide to connecting to CSOM in PowerShell available here:
https://www.sharepointdiary.com/2019/04/connect-to-sharepoint-online-using-csom-powershell.html.
CSOM works quite differently to most PowerShell scripting approaches so can be quite difficult to use.
Then you have what’s called the SharePoint PnP (Patterns and Practices) PowerShell module, which has been developed by third parties to support everyday needs and use cases in and around SharePoint. The latest version of this is called “PnP.PowerShell”.
While each have their use, the PnP.PowerShell module is often preferred over CSOM as it offers a more user-friendly and powerful set of cmdlets, enabling you to perform a wider range of actions more easily. In the use case we chose for the blog, it works like a dream.
Know 'Enough' About Permissions
Before writing and running your first script, if you don’t consider how a script runs….you may be hit time and again with odd looking errors which mention access.
When you run a PowerShell script, there are not only the instructions that get executed, but the whole thing operates in a ‘context’ of the authority it has to perform actions. This means scripts don’t just run. They are granted or ask for permissions right from the get-go and these permissions may be multi-layered depending on what you are looking to achieve. If you forget to do this, many scripts simply won’t run due to inbuilt security on devices and in cloud services.
In the example I'm going to provide, the script not only needs permission to execute on your local machine (which may be restricted by default), it will also need access to an account it can use to work against a SharePoint environment. So be mindful that the script runs under the context of an account executing it both locally and on any services it connects to.
For me to get started in this example, firstly I ran PowerShell 7 and entered this command (I happened to run as an Administrator but we will deal with that in a moment)
Set-ExecutionPolicy RemoteSigned
The command essentially tells PowerShell that it can run local scripts on your machine without restriction. It will still enforce remote scripts (ones you download) to be digitally signed so that the risk of running suspect scripts from third parties remains somewhat limited (Note: Changing the execution policy can expose your system to risks. if in doubt, do a little more research)
The above command sets the execution policy for all users. If you don’t have access to run as an administrator, you can set the policy for yourself only from a non-elevated (i.e. Not using Run As Administrator) PowerShell window using the following command:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Don’t worry about the authentication to SharePoint itself, your script will take care of that in a moment. This is just about your access to execute script on your local machine.
When Ready, You Have Options (Again)
Now you are set up with PowerShell 7 and you have allowed local scripts to be executed, you are ready to execute some PowerShell.
A quick Google search will suggest 2 things.
- You can use VSCode, PowerShell IDE or ISE to do this
- Scripts tend to be multi-line affairs.
So how do we reconcile that to this lovely new PowerShell 7 console we loaded up?
Put simply, you can use any of the mentioned tools to run PowerShell. Especially if they are single line instructions right from the get go.
VSCode for me is the better of the 3 as it offers a robust environment to create, edit, and debug your multiline PowerShell scripts.
You can use it’s built-in terminal to run your multi-line scripts directly, and also utilize its debugging features to step through your code, monitor variable values, and troubleshoot issues.
However, the script we are writing needs modules to run that are more easily accessed via the PowerShell 7 instance we have running. They are just part of the bundle and there is no real additional jiggery pokery to worry about other than what's already been mentioned.
So let’s focus on the use case where we create and edit in VSCode for ease. Save to a local directory and then run from PowerShell 7. I’ll show you how next.
How to Run A PowerShell Script
This bit is easy.
- Save the script I’m about to share to an easily written directory on your local device (like c:\temp).
- Open a PowerShell 7 terminal
- Run the Set-ExecutionPolicy RemoteSigned command (with additional parameters as mentioned if you need)
- Run the Install-Module PnP.PowerShell -Scope CurrentUser command found here to install the PnP.PowerShell module: https://pnp.github.io/powershell/articles/installation.html
- Navigate to the directory where your script resides using commands such as cd .. to return to the root directory of your PC, then cd c:\temp to navigate to the directory where the script resides (you may need to change this)
- If you prefer you can Launch PowerShell 7 from the right-click context menu of the directory in Windows Explorer to start your session in the correct folder.
- Run a script using the command
".\YourScriptName.ps1
” (note: PowerShell scripts have the .ps1 suffix). You can use the script below and save it with the name script.ps1 if you like and it will run against your SharePoint site.
An Example : Get SharePoint Content Types Used in Sites Within Your SharePoint Tenant
Here’s an example for you to use all those tips with to see if you can execute against your SharePoint site (thank you to J Williams for providing this example , which was adapted from the original at https://www.sharepointdiary.com/2017/04/sharepoint-online-find-content-type-usage-using-powershell.html).
Just copy and paste the text. Save it to a file called script.ps1 file in your c:\temp using VSCode as I did and use the script command above.
Replace [tenantname] with your own SharePoint site URL.
One tip to help you: You don’t need to know too much about the script language itself. It helps of course but there are LOTS of examples out there to help you experiment.
The main things to look out for in the above example however are:
- Items with $ before them are variables. They contain objects or data. The right hand side of the line after the = is the object that gets placed within the $variable. Test this by running your script and then typing just the name of any variable into the terminal. e.g $siteUrl . You should get the site URL you placed into this variable echoed back on screen.
- The cmdlets starting with Get-xxxx are doing the real work here. After you use the Connect-PnPOnline instruction, you are able to use its actions within the script e.g. Get-PnPlist to gather a collection of the lists in your site.
- The items with a – after the cmdlet name are called parameters e.g Get-PnPlist -Connection $Connection defines the cmdlet to call, a connection it should use by reference to the variable that contains the connection details. You provide one or more of these to a cmdlet to achieve your desired outcome. A full list of the PnP-Powershell cmdlets and their usage is here.
This should be all you need to get a successful outcome with your script. It took me lots of experimentation and some great help from the Collab365 Academy members (particularly J Williams – thank you !) to get there but I hope it might help you save a few hours in your own journey.
A Final Tip: Get Help Using ChatGPT But Beware!
If you’re stuck, you can always seek advice from ChatGPT. However, please exercise caution when implementing any script suggestions. Ensure you understand the code, as running scripts with improper permissions or settings can cause issues within your SharePoint environment.
I found more dead ends with this approach only because I did not have a good solid understanding of why certain tools would run certain PowerShell modules and others would prompt for installs. I also needed to grasp the permissions ideas to progress. I hope whats been shared can help you but do reach out in the Academy with any ideas to improve this post or steps you’d like to see covered.