|

Find a SharePoint List’s Internal Column Names with PowerShell

Your code references a script that works against a SharePoint list, requests a field based on its visible name, and doesn’t return anything.

That field is named ProjectStatus in your browser. Its internal name isn’t that one.

Tested against an actual SharePoint list using PnP.PowerShell 2.12.0

Every column has two names

Title is what you see on the browser. It is editable by everyone and can include any information.

InternalName is what matters. Once it is set while the creation of the column, it cannot be changed anymore.

That is the difference in one sentence.

$item = Get-PnPListItem -List 'Projects' -Id 1

$item['ProjectStatus']    # internal name
$item['Project Status']   # display name
By internal name 'ProjectStatus' : 'Complete'
By display name 'Project Status' : ''

An empty string, not an error. That is why this is so easy to lose an hour to. The script runs, it just quietly does nothing.

Getting the list

The obvious command gives you far more than you want:

Get-PnPField -List 'Projects'

On a list where I had created exactly five columns:

Total fields          : 90
Hidden                : 61
Inherited from base   : 83
Actually yours        : 5

Ninety. So filter it down to the ones you actually made:

Get-PnPField -List 'Projects' |
    Where-Object { -not $_.FromBaseType -and -not $_.Hidden } |
    Select-Object Title, InternalName, TypeAsString |
    Format-Table -AutoSize
Title          InternalName  TypeAsString
-----          ------------  ------------
Project Status ProjectStatus Choice
Project Owner  ProjectOwner  User
Due Date       DueDate       DateTime
Budget         Budget        Currency
Notes          Notes         Note

FromBaseType is the useful one. It is true for everything SharePoint gave you and false for everything you added.

What happens to spaces

The internal name is clean because it was generated through script. The columns created in the browser are not clean because SharePoint generates the internal name depending on what you entered.

I have created a column with space intentionally:

Add-PnPField -List 'Projects' -DisplayName 'Demo Review Date' `
             -InternalName 'Demo Review Date' -Type DateTime
Title        : Demo Review Date
InternalName : Demo_x0020_Review_x0020_Date
StaticName   : Demo_x0020_Review_x0020_Date

Every space becomes _x0020_. A column called “Date of Last Review” ends up as Date_x0020_of_x0020_Last_x0020_Review, and that is what your script has to use.

This is also why you are better off creating columns with a short name and renaming them afterwards.

Renaming does not change the internal name

I renamed that column and looked again:

Set-PnPField -List 'Projects' -Identity 'Demo Review Date' -Values @{ Title = 'Renamed Review Date' }
Title        : Renamed Review Date
InternalName : Demo_x0020_Review_x0020_Date

The label was renamed. The key remains the same, and will remain the same.

In other words, a column that appears to show ReviewDate now may actually have an underlying name of Temp_x0020_Column based on what someone had inputted two years ago. The only way to determine the internal name is by asking – there is no way you can determine the internal name just from using the browser.

This means that if you want an internal name of ReviewDate for example, then go ahead and create it with that internal name and then rename it to “Date of Last Review.”

.

Built-in columns are worse

Some of the ones you use most have internal names with no relationship to the label at all:

Title        InternalName TypeAsString
-----        ------------ ------------
Attachments  Attachments  Attachments
Created By   Author       User
Content Type ContentType  Computed
Created      Created      DateTime
Modified By  Editor       User
Name         FileLeafRef  File
URL Path     FileRef      Lookup
ID           ID           Counter
Modified     Modified     DateTime
Title        Title        Text

Created By is Author. Modified By is Editor. Those two are the ones everybody hits, and there is nothing on screen that hints at it.

In a document library it gets stranger still:

Title        InternalName    TypeAsString
-----        ------------    ------------
Created By   Author          User
Type         DocIcon         Computed
Modified By  Editor          User
File Size    File_x0020_Size Lookup
Name         FileLeafRef     File
URL Path     FileRef         Lookup

A file’s Name is FileLeafRef. Its path is FileRef. And File Size carries the _x0020_ encoding as a built-in, which tells you Microsoft named it in a browser too.

One thing that will not work at all

I tried to make a column called Cost & Time-Frame to see what an ampersand does:

An error occurred while parsing EntityName. Line 1, position 32.

This time there is no encoding name, but rather a failure. PnP generates field XML internally, and an unencoded ampersand ruins the whole parsing process even before SharePoint gets it. Error message is related to XML parsing, but not to your field, which makes it hard to understand, since you are only three lines into provisioning script.

Please note, this is a limitation of script only. Browser would successfully add the column and encode it for you. This is another rare case where UI does something PowerShell won’t.

The line worth keeping

Get-PnPField -List 'YourList' |
    Where-Object { -not $_.FromBaseType -and -not $_.Hidden } |
    Select-Object Title, InternalName, TypeAsString |
    Sort-Object Title

Run it before you write anything against a list you did not create yourself. Thirty seconds, and it saves the empty-string hour ?

Related posts

Similar Posts