Hello SharePoint fellows,
Today, I want to share with you something that will probably remain as my quickest bug fix ever: Add 3 characters to fix a bug which was not a typo.
A few months ago, I wrote a post about SharePoint maintenance tasks using PowerShell script and SharePoint PnP Powershell where I presented a script I wrote to migrate the content type applied to a bunch of documents to another content type.
In that same post I wrote:
Whenever I code something, I tend to (over-)split it into reusable and generic parts, sometines I never re-use them… but you never know, one day, maybe…
I knew I would reuse that script someday! In a totally different context (change of existing SharePoint structure and used Content Types), I had to reuse it.
In this case however, I have dozens of Content Types to migrate. Still developer and still lazy as I am, I do not want to reenter the command dozens of times.
Then, I wrote another script where I crafted, using Excel, the commands with the proper arguments
Run the script, proud of the accomplished job before is is actually done !
But BOOM ! Some ugly red messages appear !
What’s wrong with the script ?
The error message states than I am trying to access an indexed property of $item which is null. The script hasn’t changed even a bit since the last time I used it and it worked ! (Does is sound like one of these developer lame excuses ? I admit… but still).
What’s funky with the $item variable ?
Something I knew, but kind of forgot when I wrote this script is that PowerShell automatically unboxes a single item array to that item. If only a single document has the specified source content type, the $itemsToUpdate variable will actually contain the item itself instead of an array.
In this case, when I write:
$item = $itemsToUpdate[$i]
It makes no sense since a SharePoint ListItem has no indexed properties, so $item is null.
Wait a minute, if it is not an array, why didn’t it crash ?
Because, just like in my sample above, a common way to check the result array is not empty is to check its Count property. Before PowerShell 3.0, the Count property was not working if the result was the unboxed single item, which made the scripts crash on that simple check. Since PowerShell 3.0, it has been solved by providing this Count property even for single item results (Check this for more info).
You can see, in the screenshots, the intellisense of PowerShell ISE doesn’t suggest the Count property, however, I can read it and it contains a value.
It is not a bug
, it’s a feature !
No, seriously, while the red messages could make think there is a bug in the script, it was originally designed to migrate the content type of a collection of documents to another one, and that’s the only way I used it and tested it (It is a script to help me doing stuff quicker, I did not spend much time on testing,… Please don’t blame me !). I never tested that script to work on a single document.
In this new context, I run multiple commands, one for each Content Type and without a clue of the Content Types that are (or are not) in use and how many times.
Enough with the excuses, time to fix it !
Yeah, I meant “improve it”, PowerShell and its magic allow us to improve this script with a very small change. Use the array constructor on the result @ ( ).
We have to surround the call of the Get-PnPListItem cmdlet with the @ ( ) operator, this will make sure the result is an array, even if it is the automatically boxed single item.
So here is the adapted code
And that’s how, with only 3 added characters, I improved (or bug-fixed) my script!
Here is the complete improved script
I hope this tip will help you as well someday!