Hiding Fields in a SharePoint Form with PnP and PowerShell [O365]

calendar_month October 5, 2019

I decided to publish the small snippets and scripts I create no longer (only) in my OneDrive… but here. Hiding fields in a SharePoint form with PnP and PowerShell is thus the first article with such content.

The Problem

In the SchemaXml of a field, the visibility within forms can be controlled with ShowInDisplayForm, ShowInNewForm, and ShowInEditForm. At the surface you only have the option to hide the field in the content type. A dedicated show/hide is not possible.

The savvy SharePoint PowerUser used to be able to accomplish this via the SharePoint Manager. Something like this exists for SharePoint Online – the SharePoint Online Client Browser – but it doesn’t save changes.

Which brings us to our problem. As an old SharePoint developer I have several options. I could write a console application (.NET), a UWP application, or a PowerShell script with CSOM. The latter is faster to write, test, and execute – but CSOM in PowerShell isn’t that great. Plus I have to write many lines of code.

PnP and PowerShell

The PnP PowerShell commands for SharePoint have been around for a while. The PnP PS commands provide a wrapper around CSOM to write fewer lines of code and also execute simple commands directly in PowerShell.

Pure CSOM:

$context = New-Object Microsoft.SharePoint.Client.ClientContext($siteUrl)
$context.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($user, (ConvertTo-SecureString $pass -AsPlainText -Force))
$list = $context.Web.Lists.GetByTitle($listTitle)
$field = $list.Fields.GetByTitle($fieldTitle)
$field.Description = "This is my field"
$field.UpdateAndPushChanges($true)
$context.Load($field)
$context.ExecuteQuery()

With PnP:

Connect-PnPOnline -Url $siteUrl
$field = Get-PnPField -List $listTitle -Identity $fieldName
$field.Description = "This is my field"
$field.UpdateAndPushChanges($true)
$field.Context.ExecuteQuery()

Even shorter with Set-PnPField:

Connect-PnPOnline -Url $siteUrl
Set-PnPField -List $listTitle -Identity $fieldName -Values @{Description="This is my field"}

Hiding Fields

Here’s the complete script HideFieldInList.ps1:

Param(
    [parameter(Mandatory=$true)][alias("url")]$siteUrl,
    [parameter(Mandatory=$true)][alias("list")]$listTitle,
    [parameter(Mandatory=$true)][alias("field")]$fieldName,
    [alias("display")]$hideInDisplayForm=$true,
    [alias("new")]$hideInNewForm=$true,
    [alias("edit")]$hideInEditForm=$true
)

Connect-PnPOnline -Url $siteUrl -Credentials (Get-Credential)

$field = Get-PnPField -List $listTitle -Identity $fieldName

if($field.Sealed){ throw 'field is sealed' }
if($field.Hidden){ throw 'field is hidden' }

$field.SetShowInDisplayForm(!$hideInDisplayForm)
$field.SetShowInNewForm(!$hideInNewForm)
$field.SetShowInEditForm(!$hideInEditForm)

try{
    $field.UpdateAndPushChanges($true)
    $field.Context.ExecuteQuery()
} catch {
    throw "error while applying changes for field: $field ... $($_.Exception.Message)"
}
Write-Host "field updated" $field

Usage

Hide in all three forms:

./HideFieldInList.ps1 -url https://contoso.sharepoint.com/sites/Example -list "My List" -field MyField

Hide only in Edit and New form:

./HideFieldInList.ps1 -url https://contoso.sharepoint.com/sites/Example -list "My List" -field MyField -display $false

All use is at your own risk and own responsibility. Have fun with it :)