Recently, I had to automate the creation of a SharePoint site structure using the PnP PowerShell cmdlets. So far so good…but after writing some specific cmdlets, my script threw me up a strange error.
To illustrate this issue, let’s consider the following PowerShell script. Apparently, nothing wrong here, just few instructions with basic SharePoint manipulations with the PnP cmdlets on a publishing site:
Connect-SPOnline -Url "https://<your-site>.sharepoint.com/" -Credentials (Get-Credential -UserName "<your_username>" -Message "Please enter your credentials")
$ArticlePageCt = Get-SPOContentType -Identity "Article Page"
Add-SPOContentType -Name "News" -Description "News" -Group "Intranet" -ParentContentType $ArticlePageCt
New-SPOWeb -Title "SubWeb" -Url "SubWeb" -Template STS#0
# This line will never be reached!
Set-SPOWeb -Title "New web title"
However, if you run this script, you will get an error when executing the New-SPOWeb cmdlet:
« format-default : The collection has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly
So what’s the problem here?
PowerShell fails to display an object returned by the cmdlet where some properties have not been initialized. However, if you take a look in your site collection, you will see that the sub web has been created proving that the cmdlet has effectively worked!
Actually this is a known issue but, the solution is a little bit hard to find. Currently, you have to dig down into the PnP GitHub repository to find the correct explanation of what is actually happennig here.
For the complete explanation, it’s here: https://github.com/OfficeDev/PnP-PowerShell/issues/120 (take a look to the Erwin van Hunen’s reply).
This is actually expected behaviour and is due to the way CSOM works. The Client Side Object Model that the cmdlets use behind the scenes do not load all properties by default. This is to reduce the payload that goes over the ‘wire’ and make the server perform faster. PowerShell however wants to resolve all properties when an object is returned and there is where this error message comes from. You can suppress this error message by simply putting the result of the cmdlet in a variable. For instancePowerShell
1 $field = Add-SPOTaxonomyField -GroupName "Test01" etc. etc.
The $field variable you can then simply ignore, or use later in retrieving additional property withPowerShell
1 Get-SPOProperty -ClientObject $field -Property "ThePropertyToLoad"
This would not be so bad if this issue would not result to the following consequences:
- It stops the script execution if the error is not catched. If it happens at the begining of your script, it can be very annoying.
- It induces a false negative error, forcing you to investigate and, if you are not aware of this issue, waste your time by debugging your code or the PnP code trying to desperatly find the cause.
From what I ‘ve seen, this issue appears during specific sequences involving the following PnP cmlets Add-SPOContentType, Add-SPOField, Add-SPOView, Add-SPOTaxonomyField.
To avoid this behavior, the solution is simply to catch the result of the problematic cmdlet, just like this:
# All good here!
Set-SPOWeb -Title "New web title"
Again, this is a known issue. This post is just to avoid you to search too deeply in the PnP GitHub repository issues list and save you a lot of time.
Hope this help!