Модули PowerShell и оснастки

Я создал несколько служебных модулей, которые все зависят от оснастки Microsoft.SharePoint.PowerShell.

При запуске на моей машине все скрипты работают правильно, у меня нет никаких модулей или оснасток в моем профиле для PowerShell для "загрузки по умолчанию", однако на других машинах их профиль не может быть гарантированно чистым.

В моем файле загрузчика модуля.psd1 я использую следующее

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

Я использую файл ps1 для запуска импорта этих модулей, который содержит следующую команду Import Module

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

Если я запускаю вещи таким образом, я получаю ошибки конфликта имен на машинах, где профиль содержит оснастку Microsoft.SharePoint.PowerShell, поскольку оснастка уже загружена.

Я знаю, что мы можем выполнять команды PowerShell с аргументом -NoProfile, но это не является допустимым решением в нашем сценарии.

Я также попытался удалить оснастку из раздела NestedModules и запустить следующее в файле.ps1 до импорта модулей, но SnapIn не отображается как загруженный, и, следовательно, импорт модуля завершается неудачно.

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

Как я могу переработать это решение, чтобы гарантировать, что оснастки будут загружаться надлежащим образом и модули будут успешно импортироваться независимо от профиля пользователя?

Мой идеальный сценарий следующий:

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)

2 ответа

Решение

Я бы отказался от того, чтобы файл PSD1 загружал snappin через NestedModules. Создайте файл CustomModules.psm1 и установите для ModuleToProcess (или RootModule в v3) значение "CustomModules.psm1". Удалите DLL-библиотеку SharePoint из NestedModules. Затем добавьте что-то вроде этого в файл CustomModules.psm1:

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

Вы можете проверить наличие названия сборки

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

или просто загрузите его и проигнорируйте ошибку, если она уже загружена:

Add-PSSnapin -Name "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue
Другие вопросы по тегам