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


90

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

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

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

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

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

Ответы:


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
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.