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)
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