pnp / PnP-PowerShell

SharePoint PnP PowerShell CmdLets
https://pnp.github.io/powershell
Other
991 stars 662 forks source link

The collection has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested. #1370

Open trillian74 opened 6 years ago

trillian74 commented 6 years ago

Notice: many issues / bugs reported are actually related to the PnP Core Library which is used behind the scenes. Consider carefully where to report an issue:

  1. Are you using Apply-SPOProvisioningTemplate or Get-SPOProvisioningTemplate? The issue is most likely related to the Provisioning Engine. The Provisioning engine is not located in the PowerShell repo. Please report the issue here: https://github.com/officedev/PnP-Sites-Core/issues.
  2. Is the issue related to the cmdlet itself, its parameters, the syntax, or do you suspect it is the code of the cmdlet that is causing the issue? Then please continue reporting the issue in this repo.
  3. If you think that the functionality might be related to the underlying libraries that the cmdlet is calling (We realize that that might be difficult to determine), please first double check the code of the cmdlet, which can be found here: https://github.com/OfficeDev/PnP-PowerShell/tree/master/Commands. If related to the cmdlet, continue reporting the issue here, otherwise report the issue at https://github.com/officedev/PnP-Sites-Core/issues

Reporting an Issue or Missing Feature

When i'm running set-pnplistitem at the end of a more complex script i get the The collection has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested. message... when i run the pnp operation locally it works

Expected behavior

I expect the set-pnplistitem to work as documented

Actual behavior

When i'm running set-pnplistitem at the end of a more complex script i get the The collection has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested. message... when i run the pnp operation locally it works

Steps to reproduce behavior

As mentioned the funny thing is that when i run this script alone it works, but when i run this in the script it fails...

I do see that there are others with similar problems, but i think i've tried them all and no luck

`$contactsUrl = "https://tenant.sharepoint.com/addresslists/"

Connect-PnPOnline -Url $contactsUrl -Credentials $UserCredential $connection = Get-PnPConnection $list = Get-PnPList -Identity "Contacts" -ErrorAction SilentlyContinue -Connection $connection $list

$contacts | ForEach-Object { try { $item = Set-PnPListItem -List $list -Identity $.ID -ContentType $.ContentType -Values @{"ExchangeID" = $.ExchangeID; "Update" = $true} -Connection $connection $item } catch { $.EMail + "Error updating listitem" }

}

Disconnect-PnPOnline`

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 requested.

Which version of the PnP-PowerShell Cmdlets are you using?

What is the version of the Cmdlet module you are running?4

Binary 2.22.18... SharePointPnPPowerShellOnline {Add-PnPApp, Add-PnPClientSidePage, Add-PnPClientSidePageSection, Add-PnPClientSideText...} (you can retrieve this by executing Get-Module -Name *pnppowershell* -ListAvailable)

How did you install the PnP-PowerShell Cmdlets?

erwinvanhunen commented 6 years ago

Hi!

Just to make sure, if you run

$item = Set-PnPListItem -List $list -Identity $.ID -ContentType $.ContentType -Values @{"ExchangeID" = $.ExchangeID; "Update" = $true} -Connection $connection
$item

outside of a script you receive no error message? But as part of a script you receive that error? The error is due to CSOM not loading all properties by default, specifically properties pointing to a collection of values (like permissions, fields, etc.). If you access one of those properties in the $item in your script you might have explicitly request them from the server with the Get-PnPProperty cmdlet, alternatively, where appropriate (not all cmdlets support this), using an -Includes parameter.

trillian74 commented 6 years ago

Sorry for the bad explaining, but the situation is that at the end of a powershell script i need to update som values in a sharepoint list... the code that i use works if i manually "run selection", but when i execute this as a part of the totalscript i get this error... So i mean that there is nothing wrong with my syntax and the cmd-lets work, but not...

Here is more of the script `try {

$contacts = (Get-PnPListItem -List Contacts -Query "1").FieldValues | Sort-Object { $_."Modified" -as [datetime] }

"Phase #0 trim email"

$contacts |
    ForEach-Object {
    $_.EMail.Trim(" ").Replace(" ", "")
    "***" + $_.EMail + "***"
}

$contacts |
    ForEach-Object {
    # Alot of EXCHANGE STUFF
}
# Phase #2 – import the "rest of the contact information” that include contact properties 

$contacts |
    ForEach-Object {
    #More exchange stuff
}
#phase 3 update listitems with alias

$connection = Get-PnPConnection 
$list = Get-PnPList -Identity "Contacts" -ErrorAction SilentlyContinue -Connection $connection
$list
$contacts | ForEach-Object {
    # $_.ExchangeID
    try {
        $item = Set-PnPListItem -List $list -Identity $_.ID -ContentType $_.ContentType  -Values @{"ExchangeID" = $_.ExchangeID; "Update" = $true} -Connection $connection -ErrorAction SilentlyContinue
        $item
    }
    catch {
        $_.EMail + "Error updating listitem" 
    }
}

} finally {

Disconnect-PnPOnline
Remove-PSSession $Session  

}

`

erwinvanhunen commented 6 years ago

Right. Okay, so the error you're seeing is effectively not 'really' an error. It's the way CSOM (which is the underlying technology of the Cmdlets) work. To restrict the amount of data that goes over the wire, CSOM explicitly requires a developer/user to specify which property of an object should be loaded. PowerShell however assumes that all the properties of an object are available by default (which is normally the case, with the exception of when one is using CSOM).

It's hard to see when looking at your script where it goes wrong as such... Would it be possible that the moment the error occurs you execute:

$error[0].Exception.Stacktrace
suz7777 commented 5 years ago

i am having the same issue - $error[0].Exception.Stacktrace returns nothing - $error is null. All of my unattended scripts are running into this and it causes them to exit with an error - in turn this causes lots of false positives in our system

$PowerShellOnlineLocation = "E:\0-install\SharePointPnPPowerShellOnline\3.4.1812.2"
Import-Module ($PowerShellOnlineLocation + "\SharePointPnPPowerShellOnline.psd1")
..
try {
    Connect-PnPOnline -Url https://XYXz.sharepoint.com/teams/SITENAME -Credentials $O365Credentials
    Add-PnPFile -Path $global:OutputExcelFile -Folder "Shared%20Documents/AD%20Lockout%20Reports"

    Write-Host "here"
} catch {
    Write-Host "error"
    $error[0].Exception.Stacktrace
}
write-host "end"

-output


WARNING: The names of some imported commands from the module 'SharePointPnP.PowerShell.Online.Commands' include unapproved verbs that might make them less discoverable. To find the commands with unapproved verbs, run the Import-Module command again with the Verbose parameter. For a list of approved verbs, type Get-Verb.

here
end
The collection has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested.
At :line:0 char:0
suz7777 commented 5 years ago

i just tried the latest release and i get the same issue

$PowerShellOnlineLocation = "E:\0-install\SharePointPnPPowerShellOnline\3.6.1902.2"

WARNING: The names of some imported commands from the module 'SharePointPnP.PowerShell.Online.Commands' include unapproved verbs that might make them less discoverable. To find the commands with unapproved verbs, run the Import-Module command again with the Verbose parameter. For a list of approved verbs, type Get-Verb.

here
end
The collection has not been initialized. It has not been requested or the request has not been executed. It may need to be explicitly requested.
At :line:0 char:0
suz7777 commented 5 years ago

I have confirmed the issue exists when I load the 2013 and sharepoint online versions of PNP at the same time. (we do this often for migrations)… if I drop 2013 PNP and use classic CSOM for the on premise calls – this issue does not appear.

erwinvanhunen commented 5 years ago

The general recommendation is to only use -one- version of PnP PowerShell at the same time. If you need to access different versions of SharePoint at the same time, the recommendation is to the PnP PowerShell version that addresses the lowest version of SharePoint as you will be able to use that version also to access the higher version of SharePoint. E.g. if you want to access both 2013 and Online, use PnP PowerShell for SharePoint 2013. The downside of this approach is however that you will not get the latest and greatest functionality. For instance, the SP 2013 version of PnP PowerShell has no support for modern pages.

There are differences between the versions of CSOM that are used behind the scenes for SharePoint. E.g. if you use a higher version of CSOM to access a lower version of SharePoint you can run into issues as that version of CSOM tries to access properties that might not exist, hence the error messages.

There is unfortunately nothing we as PnP can do about this, we're bound to using the same APIs as everyone else...

Regarding the warning you see when issueing Import-Module: it can be suppressed by specifying the -DisableNameChecking parameter on the import-module cmdlet. There is a cmdlet, Apply-PnPProvisioningTemplate that uses an 'unapproved' verb, (Apply-). It's nothing blocking and in general the recommendation to only use an approved verb, but this is more for usability reasons than for technical reasons.

suz7777 commented 5 years ago

thanks for the update... switching around (and being careful with CSOM) has solved our issue for now - i posted here so that the original reporter can take a look and see if that was the issue in his case. I was working with code handed to me from a client and it took a while to track this one down. As to the warning, agreed - i just didn't put in the example code here.

ben79git commented 5 years ago

I'm running into the exact same issue here, and I cant seem to find a way round. I have a rather large script that one of it final functions is to write to a list using add-pnplistitem. On its own the command runs fine, but as soon as its part of a larger script I get the same issue as detailed above.

I've tried the variable trick with no luck, and I'm stuck to think what I can do next. The item is written to the list successfully, but the script bombs out, so anything proceeding that command isnt run.

Does anyone have any ideas on how to get round this? I'm running 3.8.1904.0.

Thanks

loiterash commented 5 years ago

I was also facing similar issue and Get-PnPProperty worked for me.

My Code was breaking in loop as highlighted below:

$Connection = Get-PnPConnection $PnPList = Get-PnPList -Identity "Swap Schedule" $ListFields = $PnPList.Fields foreach($field in $ListFields){ Write-Output $field.Title }

Working Code, I just made one more call to fetch the specific property and it worked:

$Connection = Get-PnPConnection $PnPList = Get-PnPList -Identity "Swap Schedule" $ListFields = Get-PnPProperty -ClientObject $PnPList -Connection $Connection -Property "Fields" foreach($field in $ListFields){ Write-Output $field.Title }

Thanks

PaulBendall commented 4 years ago

I think I have worked out what is going on and I think the reason it is confusing is that it isn't consistent with most other PowerShell cmdlets. As @erwinvanhunen described not all values are returned by the underlying call to CSOM, casting to a variable is a red herring.

get-pnplist | select-object -first 1 | get-member The command returns 97 properties, but many of these are in effect reference points, so let's use the example property Fields which has a definition of Microsoft.SharePoint.Client.FieldCollection Fields {get;}

get-pnplist | select-object -first 1 | select fields

We get the error message : "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 requested.

Fields or the values of this property don't exist instead, we need to specifically INCLUDE them in our request by using the INCLUDES parameter of the cmdlet, for example:

get-pnplist -Includes Fields | select-object -first 1 | select fields

Now you get an array of Field IDs in fact the above would be better if we changed the last select to select -expandproperty Fields as you get the Field Name as well as ID

Hope this helps to explain the issue. The solution/workaround from @loiterash is also valid and usable it just requires an additional cmdlet to be used

derhallim commented 3 years ago

@trillian74 @erwinvanhunen How did you get a reference to ExchangeId and IndexId? I have a scenario where I want to provision multiple events web part, but each one points to a different site. When I exported the event web part I saw the ExchangeId and IndexId, what do these values represent and how do we set these values dynamically based in order to point to these different sites at runtime?