PowerShell Modules and SnapIns

夙愿已清 提交于 2019-12-08 11:17:34

问题


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)

回答1:


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



回答2:


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


来源:https://stackoverflow.com/questions/14614305/powershell-modules-and-snapins

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!