Как проверить, загружена ли оснастка PowerShell перед вызовом Add-PSSnapin

90

У меня есть группа сценариев PowerShell, которые иногда запускаются вместе, иногда по одному. Каждый из скриптов требует загрузки определенной оснастки.

Прямо сейчас каждый скрипт вызывает Add-PSSnapin XYZв начале.

Теперь, если я запускаю несколько сценариев подряд, следующие сценарии выдают:

Невозможно добавить оснастку XYZ Windows PowerShell, потому что она добавлена ​​случайно. Проверьте имя оснастки и повторите попытку.

Как я могу проверить каждый сценарий перед вызовом Add-PSSnapin, чтобы убедиться, что оснастка уже загружена?

Joshuapoehls
источник

Ответы:

133

У вас должно получиться сделать это примерно так, когда вы запрашиваете Snapin, но говорите PowerShell не выводить ошибку, если не может ее найти:

if ( (Get-PSSnapin -Name MySnapin -ErrorAction SilentlyContinue) -eq $null )
{
    Add-PsSnapin MySnapin
}
Скотт Саад
источник
Ага! Это именно то, что мне было нужно, спасибо! Я пробовал нечто подобное в своих экспериментах, но я не знал о -ErrorAction SilentlyContinue.
joshuapoehls
2
SilentlyContinue вызван тем, что Get-PSSnapin не возвращает значение NULL, если не находит оснастку по умолчанию. Это ошибки.
Rich
1
Для ленивых: в этой статье представлен полный пример кода, как проверить, зарегистрирована ли оснастка перед ее загрузкой.
Herzbube
21

Скотт уже дал вам ответ. Вы также можете загрузить его в любом случае и игнорировать ошибку, если она уже загружена:

Add-PSSnapin -Name <snapin> -ErrorAction SilentlyContinue
Шэй Леви
источник
6
Это также будет продолжаться незаметно, если оснастка не загрузилась по другим причинам, например, не была установлена. Это может затруднить диагностику проблем для людей, использующих ваш скрипт.
Грэм Эмброуз
Хорошо, в этом случае мы можем сначала проверить, зарегистрирована ли оснастка.
Шей Леви,
4

Удивительно, но никто не упомянул собственный способ для скриптов указывать зависимости: #REQUIRES -PSSnapin Microsoft.PowerShell...директиву comment / preprocessor. Точно так же вам может потребоваться повышение прав с помощью -RunAsAdministratorмодулей с -Modules Module1,Module2и конкретной версии Runspace.

Узнайте больше, набрав Get-Help about_requires

Алексей
источник
Мне кажется, что это «правильный» способ сделать это.
Grax32
1
Проблема, с которой я столкнулся, заключается в том, что Powershell возвращает ошибку, если необходимая оснастка не загружена, и я предполагаю, что все хотели бы, чтобы оснастка была загружена, если это не так.
Дуэйн Дрискилл
1
Модули новее, и при необходимости автоматически загружаются именно модули, а не PSSnapins, вы правы. Но, по крайней мере, ничего не будет сломано или засорено запуском той части скрипта, которая работает без оснастки.
Alexey
3

Я попробовал пример кода @ ScottSaad, но у меня это не сработало. Я не выяснил, почему, но проверка была ненадежной, иногда успешной, а иногда нет. Я обнаружил, что использование Where-Objectфильтрации Nameсвойства работает лучше:

if ((Get-PSSnapin | ? { $_.Name -eq $SnapinName }) -eq $null) {
    Add-PSSnapin $SnapinName 
}

Код любезно предоставлен этим .

Энди МакКлаггэдж
источник
1

Скотт Саадс работает, но мне это кажется более быстрым. Я не измерял его, но кажется, что он загружается немного быстрее, так как никогда не выдает сообщения об ошибке.

$snapinAdded = Get-PSSnapin | Select-String $snapinName
if (!$snapinAdded)
{
    Add-PSSnapin $snapinName
}
Кьетил Итрехус
источник