Welp, this is embarrassing. ¯\_(ツ)_/¯
I’ve been writing PowerShell scripts for SharePoint for a very long time now.
And several times in every project, I find myself wanting to select just a specific subset of columns for use or display… or something.
And every time, like a doofus, I Get-PnPListItem, then iterate around each Item, picking out individual fields from FieldValues, and adding to a PSCustomObject.
Like this:
Get-PnPListItem -List Lists/MyList | % { [PSCustomObject]@{"Column1"=$_.FieldValues.Column1; "Column2"=$_.FieldValues.Column2; } }
And so on.
For years.
Like I say, like a doofus.
Anyway. Last week, I was wondering if I could improve on that. I mean, at least I’m not one of those guys who has to invoke Add-Member for each field for each item. You know who you are.
Anyway.
The completely-obvious-in-hindsight approach I can now share with you is this: You can cast FieldValues as a HashTable.

Get-PnPListItem -List Lists/MyList | % { [HashTable] $_.FieldValues } | Select Column1, Column2;
If you ever need to pull out a people column, MMS or lookup, you’ll need to use an expression. Something like this should do:
Get-PnPListItem -List Lists/MyList | % { [HashTable] $_.FieldValues } | Select Column1, Column2, @{"Name"="Person1";"Expression"={$_.Person1.LookupValue}};
I can’t believe I’ve been playing this game on idiot mode for so long.
Here’s a slightly optimised version that obviates the Where-Object (%):
[HashTable[]] (Get-PnPListItem -List Lists/MyList).FieldValues | Select Column1, Column2, @{"Name"="Person1";"Expression"={$_.Person1.LookupValue}};
SMH.