Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SPSite throw an exception if it executed after Script with "Add-PSSnapin Microsoft.SharePoint.PowerShell" code inside. #566

Closed
DenisK87 opened this issue Apr 7, 2017 · 5 comments

Comments

@DenisK87
Copy link

DenisK87 commented Apr 7, 2017

Details of the scenario you try and problem that is occurring:
If SPSite resource is executed after Script resource with "Add-PSSnapin Microsoft.SharePoint.PowerShell" it throw an exception:

PowerShell DSC resource MSFT_SPSite failed to execute Test-TargetResource functionality with error message: An item with the same key has already been added

The DSC configuration that is using the resource:
Script Script1
{
TestScript = {
return $false
}
SetScript = {
if ((Get-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null ) {
Add-PSSnapin Microsoft.SharePoint.PowerShell
}
}
GetScript = { }
}

SPSite TestAppSite
{
DependsOn = "[Script]Script1"
Url = "https://sharepoint.com/sites/TestSite"
OwnerAlias = "DOMAIN\LOGIN"
Name = "Test site"
Template = "STS#0"
PsDscRunAsCredential = $installCredentials
}

Version of the Operating System and PowerShell the DSC Target Node is running:
Windows Server 2012 R2, PowerShell 5.1, SharePoint 2016

Version of the DSC module you're using:
1.6.0.0

@BrianFarnhill
Copy link
Contributor

Thanks for reporting this Denis - the fact that you are calling it before another script resource that loads the snapin doesn't/shouldn't matter. When we load the snapin we do it with this script:

$baseScript = @"
    if (`$null -eq (Get-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue)) 
    {
        Add-PSSnapin Microsoft.SharePoint.PowerShell
    } 
"@

Now each resource runs in its own runspace so loading it multiple times shouldn't make a difference, but we always test to see if it is loaded before we load it, so we'll never load it twice.

So working backwards from there, we're going to need to see the verbose logs from this one executing so we can figure out which line its likely failing at. Are you able to share the verbose output from that resource when you run it so I can confirm where this goes?

@BrianFarnhill BrianFarnhill added the needs investigation The issue needs to be investigated by the maintainers or/and the community. label Apr 9, 2017
@DenisK87
Copy link
Author

Hi, Brian.

Thanks for your response. Yes, I've uploaded archive with logs and DSC scripts files.
Issue566Logs.zip

I'll also copy logs here:

Perform operation 'Invoke CimMethod' with following parameters, ''methodName' = SendConfigurationApply,'className' = MSFT_DSCLocalConfigurationManager,'namespaceName' = 
root/Microsoft/Windows/DesiredStateConfiguration'.
An LCM method call arrived from computer ServerName with user sid S-1-5-21-1389408205-2497641658-4038869163-4233.
[ServerName]: LCM:  [ Start  Set      ]
[ServerName]: LCM:  [ Start  Resource ]  [[Script]UploadAppToLibrary]
[ServerName]: LCM:  [ Start  Test     ]  [[Script]UploadAppToLibrary]
[ServerName]: LCM:  [ End    Test     ]  [[Script]UploadAppToLibrary]  in 0.7340 seconds.
[ServerName]: LCM:  [ Start  Set      ]  [[Script]UploadAppToLibrary]
[ServerName]:                            [[Script]UploadAppToLibrary] Performing the operation "Set-TargetResource" on target "Executing the SetScript with the user supplied credential".
[ServerName]: LCM:  [ End    Set      ]  [[Script]UploadAppToLibrary]  in 1.0780 seconds.
[ServerName]: LCM:  [ End    Resource ]  [[Script]UploadAppToLibrary]
[ServerName]: LCM:  [ Start  Resource ]  [[SPSite]TestAppSite]
[ServerName]: LCM:  [ Start  Test     ]  [[SPSite]TestAppSite]
[ServerName]:                            [[SPSite]TestAppSite] Testing site collection https://***
[ServerName]:                            [[SPSite]TestAppSite] Getting site collection https://***
[ServerName]:                            [[SPSite]TestAppSite] Executing as the local run as user DOMAIN\LOGIN
[ServerName]: LCM:  [ End    Test     ]  [[SPSite]TestAppSite]  in 0.6410 seconds.
PowerShell DSC resource MSFT_SPSite  failed to execute Test-TargetResource functionality with error message: An item with the same key has already been added. 
    + CategoryInfo          : InvalidOperation: (:) [], CimException
    + FullyQualifiedErrorId : ProviderOperationExecutionFailure
    + PSComputerName        : ServerName.com
 
[ServerName]: LCM:  [ End    Set      ]
The SendConfigurationApply function did not succeed.
    + CategoryInfo          : NotSpecified: (root/Microsoft/...gurationManager:String) [], CimException
    + FullyQualifiedErrorId : MI RESULT 1
    + PSComputerName        : ServerName.com
 
Operation 'Invoke CimMethod' complete.
Time taken for configuration job to complete is 3.277 seconds

I'm not sure, but may be this error is connected to case, described here
Add-PSSnapin both in “second level” and “third level” modules

Thanks.

@BrianFarnhill
Copy link
Contributor

ok, so maybe you might be on to something here. I would expect to see the verbose line from the start of our test function before the error, so the only place this can be faulting has got to be where we are loading the snap in. So lets go through the stuff you have here.

In the linked example, the issue is that you are genuinely loading it twice. I can see that the code here is mimicking what we do in our module, but the issue there is that in Module3Function you end up reloading the module because it has already been loading by the script invoker in Module2Function - just that the Get-PSSnapin doesn't return it properly (which is something we saw very early on), so we have to make the assumption that anything that mimics the Module3Function will be loaded where the snapin is already loaded, so it shouldn't make a call to load the snapin ever.

So extrapolate that out to what we do in SharePointDsc and I think what I would do for your script block is to do things like we do and use "Invoke-SPDscCommand" to run your set script code, and not load the snapin there at all. So something like this:

SetScript = {
    Invoke-SPDscCommand -ScriptBlock {
        [Do whatever you need to here]
    }
}

Now this will load the snapin for you the way we do, which we know works from one resource to the next with no issues, so it should be able to do the same. We haven't publicly documented how to call Invoke-SPDscCommand but I'm willing to open it up and make it a publicly usable approach for exactly this scenario. So let me know how that goes and we can go from there.

@DenisK87
Copy link
Author

Hi, Brian.

Workaround with Invoke-SPDscCommand is working for me. Now I have no errors during script execution. Thanks a lot.

@BrianFarnhill
Copy link
Contributor

Closing the loop on this, I've formally documented this in the wiki

@SteveL-MSFT SteveL-MSFT added this to Needs investigation in powershell/dscresources May 14, 2019
@ykuijs ykuijs removed the needs investigation The issue needs to be investigated by the maintainers or/and the community. label Sep 19, 2019
@SteveL-MSFT SteveL-MSFT removed this from Needs investigation in powershell/dscresources Nov 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants