PnP PowerShell Scripts for SharePoint Developers

Every time I need to set up a new SharePoint site, list, or library, I don’t want to click through the UI ten times just to add a few columns. I want a script I can run once, change a couple of values, and be done in under a minute.

That’s exactly what this post is about. I’m putting together a growing collection of PnP PowerShell scripts that any SharePoint developer can pick up and use directly on their own SharePoint site. You just swap out the site URL, client ID, tenant name, or a couple of parameters, and the script does the rest. No rewriting from scratch, no guessing at cmdlet syntax.

A lot of people I talk to don’t have this kind of script library handy. They end up rewriting the same Connect-PnPOnline, New-PnPList, or Add-PnPField commands from scratch every time, or worse, doing it manually through the browser. So instead of writing one script and moving on, I’m building this into a living reference: creating sites, creating lists and libraries, adding columns of different types, and even seeding sample data so you can test your setup without typing in dummy rows by hand.

Every script here is ready to copy, paste, and run directly on your SharePoint site. Just plug in your own site URL and client ID, and you’re good to go. I’ll keep adding new scripts to this post as I use them in real projects, so bookmark it.

PnP PowerShell Script: Create SharePoint List with Multi-Select Choice Column

As a developer, if you want to create a SharePoint list with a multi-select choice column, then use the script below:

<#
=====================================================================
 Script   : Create-CandidateList.ps1
 Purpose  : Creates a SharePoint Online list named "Candidates" with a
            multi-select Choice column (JobLocation) and populates it
            with sample candidate records.
 Module   : PnP.PowerShell
=====================================================================
#>

# ----------------------------[ CONNECTION ]---------------------------
$ClientID = "655a839c-8659-bbbbbbb-cccc-bbbbbbbbb"
$SiteUrl  = "https://tsinfotechnologies.sharepoint.com/sites/SPGuides"

Connect-PnPOnline -Url $SiteUrl -ClientId $ClientID -Interactive

# ----------------------------[ VARIABLES ]----------------------------
$ListName = "Candidates"

$Choices = @(
    "Texas",
    "Washington",
    "England",
    "Victoria",
    "Scotland",
    "Ireland",
    "California",
    "Florida",
    "Brasilia",
    "Ontario"
)

# --------------------------[ CREATE THE LIST ]------------------------
$List = Get-PnPList -Identity $ListName -ErrorAction SilentlyContinue

if ($null -eq $List) {
    Write-Host "Creating list '$ListName'..." -ForegroundColor Cyan
    $List = New-PnPList -Title $ListName -Template GenericList -OnQuickLaunch
    Write-Host "List '$ListName' created successfully." -ForegroundColor Green
}
else {
    Write-Host "List '$ListName' already exists. Skipping creation." -ForegroundColor Yellow
}

# ------------------[ RENAME TITLE COLUMN (OPTIONAL) ]-----------------
# The default 'Title' column will hold the candidate name.
Set-PnPField -List $ListName -Identity "Title" -Values @{ Title = "Candidate Name" }

# --------------[ CREATE MULTI-CHOICE COLUMN: JobLocation ]------------
$Field = Get-PnPField -List $ListName -Identity "JobLocation" -ErrorAction SilentlyContinue

if ($null -eq $Field) {
    Write-Host "Creating 'JobLocation' multi-choice column..." -ForegroundColor Cyan

    Add-PnPField -List $ListName `
                 -DisplayName "JobLocation" `
                 -InternalName "JobLocation" `
                 -Type MultiChoice `
                 -Choices $Choices `
                 -AddToDefaultView

    Write-Host "'JobLocation' column created with multiple selections enabled." -ForegroundColor Green
}
else {
    Write-Host "'JobLocation' column already exists. Skipping creation." -ForegroundColor Yellow
}

# ----------------------[ SAMPLE CANDIDATE RECORDS ]-------------------
$Candidates = @(
    @{ Name = "Michael Johnson";   Locations = @("Texas", "California") },
    @{ Name = "Jennifer Martinez"; Locations = @("Florida", "Ontario", "Texas") },
    @{ Name = "Christopher Davis"; Locations = @("Washington") },
    @{ Name = "Ashley Wilson";     Locations = @("England", "Scotland", "Ireland") },
    @{ Name = "Matthew Anderson";  Locations = @("Victoria", "Ontario") },
    @{ Name = "Emily Thompson";    Locations = @("California", "Washington", "Florida") },
    @{ Name = "Daniel Rodriguez";  Locations = @("Brasilia", "Texas") },
    @{ Name = "Sarah Brown";       Locations = @("Ireland", "England") },
    @{ Name = "Joshua Miller";     Locations = @("Ontario", "Victoria", "Scotland") },
    @{ Name = "Amanda Garcia";     Locations = @("Florida") },
    @{ Name = "Andrew Taylor";     Locations = @("Texas", "Washington", "California") },
    @{ Name = "Jessica White";     Locations = @("Scotland", "Brasilia") },
    @{ Name = "Ryan Harris";       Locations = @("California") },
    @{ Name = "Megan Clark";       Locations = @("England", "Victoria") },
    @{ Name = "Brandon Lewis";     Locations = @("Ontario", "Florida", "Ireland") }
)

Write-Host "`nAdding candidate records..." -ForegroundColor Cyan

foreach ($Candidate in $Candidates) {
    try {
        Add-PnPListItem -List $ListName -Values @{
            "Title"       = $Candidate.Name
            "JobLocation" = $Candidate.Locations
        } | Out-Null

        Write-Host ("  [OK] {0}  ->  {1}" -f $Candidate.Name, ($Candidate.Locations -join ", ")) -ForegroundColor Green
    }
    catch {
        Write-Host ("  [FAIL] {0} : {1}" -f $Candidate.Name, $_.Exception.Message) -ForegroundColor Red
    }
}

Write-Host "`nAll done! '$ListName' list is ready with $($Candidates.Count) records." -ForegroundColor Cyan

# -------------------------[ DISCONNECT ]------------------------------
Disconnect-PnPOnline

It will create a SharePoint list like in the screenshot below:

PnP PowerShell script examples

PnP PowerShell Script: Create a SharePoint List (With Person or Group (single & multiple) column) and Add 10 Records

Below is a single, self-contained script. It connects, creates the Project Tracker list, adds the Person and Person-multi columns, resolves the five users, and then inserts 10 items with randomly assigned managers and members.

One important technical note: Add-PnPField -Type User creates a single person column, but there is no UserMulti value in the FieldType enum. To get a multiple person column you must create it from field XML with Mult="TRUE". The script handles this correctly.

<#
    Creates the "Projects Tracker" list in SharePoint Online and
    populates it with 10 sample records using PnP PowerShell.

    Columns:
        Title           (Text)
        ProjectManager  (Person or Group - single)
        ProjectMembers  (Person or Group - multiple)
#>

#region Configuration ---------------------------------------------------------

$ClientID = "655a839c-8659-3322-3333-44444444444444"
$SiteUrl  = "https://tsinfotechnologies.sharepoint.com/sites/SPGuides"
$ListName = "Projects Tracker"

$UserEmails = @(
    "user1@tsinfotechnologies.onmicrosoft.com",
    "user2@tsinfotechnologies.onmicrosoft.com",
    "bijay@tsinfotechnologies.onmicrosoft.com",
    "preeti@tsinfotechnologies.onmicrosoft.com",
    "asit@tsinfotechnologies.onmicrosoft.com"
)

$ProjectTitles = @(
    "Website Redesign",
    "SharePoint Migration",
    "Power Automate Rollout",
    "Intranet Governance Review",
    "Teams Adoption Program",
    "Document Retention Policy",
    "Power BI Reporting Hub",
    "Security Baseline Audit",
    "Customer Portal Upgrade",
    "Knowledge Base Cleanup"
)

$ErrorActionPreference = "Stop"

#endregion

#region Connect ---------------------------------------------------------------

Write-Host "`nConnecting to $SiteUrl ..." -ForegroundColor Cyan

Connect-PnPOnline -Url $SiteUrl -ClientId $ClientID -Interactive

Write-Host "Connected." -ForegroundColor Green

#endregion

#region Create the list -------------------------------------------------------

Write-Host "`nChecking for the '$ListName' list ..." -ForegroundColor Cyan

$List = Get-PnPList -Identity $ListName -ErrorAction SilentlyContinue

if ($null -eq $List) {

    $List = New-PnPList `
        -Title $ListName `
        -Template GenericList `
        -OnQuickLaunch

    Write-Host "List '$ListName' created." -ForegroundColor Green
}
else {
    Write-Host "List '$ListName' already exists. Reusing it." -ForegroundColor Yellow
}

#endregion

#region Add the Person columns ------------------------------------------------

# --- ProjectManager : single person ---------------------------------------
$ManagerField = Get-PnPField `
    -List $ListName `
    -Identity "ProjectManager" `
    -ErrorAction SilentlyContinue

if ($null -eq $ManagerField) {

    Add-PnPField `
        -List $ListName `
        -DisplayName "Project Manager" `
        -InternalName "ProjectManager" `
        -Type User `
        -AddToDefaultView | Out-Null

    Write-Host "Column 'Project Manager' created." -ForegroundColor Green
}
else {
    Write-Host "Column 'Project Manager' already exists." -ForegroundColor Yellow
}

# --- ProjectMembers : multiple people -------------------------------------
# There is no 'UserMulti' value in the FieldType enum, so this column
# must be created from field XML using Mult="TRUE".

$MembersField = Get-PnPField `
    -List $ListName `
    -Identity "ProjectMembers" `
    -ErrorAction SilentlyContinue

if ($null -eq $MembersField) {

    $MembersFieldXml = @"
<Field Type="UserMulti"
       DisplayName="Project Members"
       Name="ProjectMembers"
       StaticName="ProjectMembers"
       List="UserInfo"
       ShowField="ImnName"
       UserSelectionMode="PeopleOnly"
       UserSelectionScope="0"
       Mult="TRUE"
       Required="FALSE" />
"@

    Add-PnPFieldFromXml `
        -List $ListName `
        -FieldXml $MembersFieldXml | Out-Null

    Write-Host "Column 'Project Members' created." -ForegroundColor Green

    # Add it to the default view
    $DefaultView = Get-PnPView -List $ListName | Where-Object { $_.DefaultView }

    if ($null -ne $DefaultView) {
        $ViewFields = @($DefaultView.ViewFields)

        if ($ViewFields -notcontains "ProjectMembers") {
            $DefaultView.ViewFields.Add("ProjectMembers")
            $DefaultView.Update()
            Invoke-PnPQuery
        }
    }
}
else {
    Write-Host "Column 'Project Members' already exists." -ForegroundColor Yellow
}

#endregion

#region Confirm the schema ----------------------------------------------------

Write-Host "`nList schema:" -ForegroundColor Cyan

Get-PnPField -List $ListName |
    Where-Object { $_.InternalName -in @("Title", "ProjectManager", "ProjectMembers") } |
    Select-Object Title, InternalName, TypeAsString |
    Format-Table -AutoSize

#endregion

#region Resolve the users -----------------------------------------------------

Write-Host "Resolving users ..." -ForegroundColor Cyan

$ResolvedUsers = @(
    foreach ($Email in $UserEmails) {
        try {
            New-PnPUser -LoginName $Email -ErrorAction Stop
        }
        catch {
            Write-Warning "Could not resolve '$Email'. $($_.Exception.Message)"
        }
    }
)

if ($ResolvedUsers.Count -eq 0) {
    throw "No users could be resolved. Cannot continue."
}

Write-Host "Resolved $($ResolvedUsers.Count) of $($UserEmails.Count) users." -ForegroundColor Green

$ResolvedUsers |
    Select-Object Id, Title, Email, LoginName |
    Format-Table -AutoSize

#endregion

#region Add 10 records --------------------------------------------------------

Write-Host "Adding 10 list items ..." -ForegroundColor Cyan

$Created = @()

for ($i = 0; $i -lt 10; $i++) {

    $Title = $ProjectTitles[$i]

    # Random project manager
    $Manager = Get-Random -InputObject $ResolvedUsers

    # Random 2 to 3 members (must be an array, never a delimited string)
    $MemberCount = Get-Random -Minimum 2 -Maximum ([Math]::Min(4, $ResolvedUsers.Count + 1))

    $Members = @(
        $ResolvedUsers |
            Get-Random -Count $MemberCount |
            ForEach-Object { $_.LoginName }
    )

    try {
        $NewItem = Add-PnPListItem `
            -List $ListName `
            -Values @{
                Title          = $Title
                ProjectManager = $Manager.LoginName
                ProjectMembers = $Members
            } `
            -ErrorAction Stop

        $Created += [pscustomobject]@{
            Id      = $NewItem.Id
            Title   = $Title
            Manager = $Manager.Title
            Members = $MemberCount
        }

        Write-Host ("  [{0,2}] {1,-32} PM: {2}" -f $NewItem.Id, $Title, $Manager.Title) `
            -ForegroundColor Green
    }
    catch {
        Write-Warning "Failed to create '$Title'. $($_.Exception.Message)"
    }
}

#endregion

#region Summary ---------------------------------------------------------------

Write-Host "`n$($Created.Count) of 10 items created successfully.`n" -ForegroundColor Cyan

$Created | Format-Table -AutoSize

Write-Host "Verifying from SharePoint ...`n" -ForegroundColor Cyan

Get-PnPListItem -List $ListName -Fields "Title", "ProjectManager", "ProjectMembers" |
    ForEach-Object {
        $Manager = $_["ProjectManager"]
        $Members = @($_["ProjectMembers"])

        [pscustomobject]@{
            Id      = $_.Id
            Title   = $_["Title"]
            Manager = if ($Manager) { $Manager.LookupValue } else { "" }
            Members = ($Members | ForEach-Object { $_.LookupValue }) -join "; "
        }
    } |
    Format-Table -AutoSize -Wrap

Write-Host "Done. View the list at:" -ForegroundColor Green
Write-Host "$SiteUrl/Lists/$($ListName -replace ' ','')`n"

Disconnect-PnPOnline

#endregion

Once you will execute the above script, it will create a SharePoint Online list like the below:

Projects tracker list pnp powershell script

Conclusion

That’s the script collection so far. Each one is built the same way: connect once, plug in your site URL and client ID, and run it directly on your SharePoint site. No extra setup, no digging through documentation halfway through your workday.

I’ll keep expanding this post as I come across more scenarios worth automating, so if there’s a specific SharePoint setup task you keep repeating manually, drop it in the comments, and I’ll add a script for it. Bookmark this page since it’s going to keep growing.

You may also like the following tutorials:

Power Apps functions free pdf

30 Power Apps Functions

This free guide walks you through the 30 most-used Power Apps functions with real business examples, exact syntax, and results you can see.

Live Webinar

SharePoint Integration Power Apps Form With Repeating Table [Invoice Management System]

Learn how to build an invoice management system using SharePoint integration and a repeating table.

📅 2nd September 2026 – 10:00 AM EST | 7:30 PM IST

Download User registration canvas app

DOWNLOAD USER REGISTRATION POWER APPS CANVAS APP

Download a fully functional Power Apps Canvas App (with Power Automate): User Registration App