Question

I've created several utility modules that all depend upon the Microsoft.SharePoint.PowerShell snapIn.

When run on my machine the scripts all run correctly, I don't have any modules or snapins in my profile for powershell to "default load", however on other machines they profile cannot be guaranteed to be clean.

In my module loader .psd1 file i'm using the following

NestedModules = @( 'Microsoft.SharePoint.PowerShell',
        '.\Modules\CustomModule.psd1')

I use a ps1 file to trigger these module imports that contains the following Import Module command

Import-Module -Name "$dir\.\CustomModules.psd1" -Global -Force -PassThru

If I run things this way I get name conflict errors on the machines where the profile contains the Microsoft.SharePoint.PowerShell snapin, due to the snapin already being loaded.

I know that we can execute PowerShell commands with the -NoProfile argument but this is not a valid solution in our scenario.

I have also tried removing the snapin from the NestedModules section and running the following, in the .ps1 file before the modules get imported but the SnapIn does not show up as being loaded and therefore the module import fails.

if ((Get-PSSnapin | ? {$_.Name -eq 'Microsoft.SharePoint.PowerShell'}) -eq $null)
{
    Write-Host "Adding PSSnapin 'Microsoft.SharePoint.PowerShell'"
    Add-PSSnapin 'Microsoft.SharePoint.PowerShell'  }

How can I re-work this solution to ensure that the snapins will load appropriately and the modules will import successfully regardless of the user profile?

My ideal scenario is the following:

Task.ps1   (The custom task me or other devs are trying to achieve)
     > Calls ImportModules.ps1   (Hides the importing logic of modules and snap-ins)
           > Imports CustomModules.psd1  (Imports all modules, functions, global vars into the runspace)
Was it helpful?

Solution

I would switch away from having the PSD1 file load the snappin via NestedModules. Create a CustomModules.psm1 file and set the ModuleToProcess (or RootModule in v3) to "CustomModules.psm1". Remove the SharePoint dll from NestedModules. Then add something like this to your CustomModules.psm1 file:

function AddSnapin
{
    [CmdletBinding()]
    param(
        [Parameter(Mandatory=$true)]
        [ValidateNotNullOrEmpty()]
        [string[]]
        $Name
    )

    Process {
        foreach ($n in $name)
        {
            if (!(Get-PSSnapin $n -ErrorAction SilentlyContinue)) {
                Add-PSSnapin $n
            }
            else {
                Write-Verbose "Skipping $n, already loaded."
            }
        }
    }
}

AddSnapin Microsoft.SharePoint.PowerShell -Verbose

OTHER TIPS

you can test the presence of the assembly name

$assemblyname = "Microsoft.SharePoint.PowerShell"
if (([appdomain]::currentdomain.getassemblies() | 
      Where {$_ -match $AssemblyName}) -eq $null )
{
  add-pssnapin Add-PSSnapin 'Microsoft.SharePoint.PowerShell'
}

or just load it anyway and ignore the error if it's already loaded:

Add-PSSnapin -Name "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top