Есть ли способ подавить какие-либо интерактивные приглашения в сценарии PowerShell?

13

При написании сценариев PowerShell я заметил, что когда некоторые командлеты сталкиваются с проблемами, они вызывают интерактивное приглашение, примером которого является Remove-Item в непустом каталоге. Это смертельно опасно, когда я пытаюсь автоматизировать задачи. Я бы предпочел, чтобы действие просто завершилось неудачей и либо выдало исключение, либо вернуло неверный код возврата, чтобы весь сценарий не был заблокирован в ожидании ответа.

Есть ли способ заставить PowerShell автоматически завершиться сбоем, в отличие от поиска пользовательского ввода в действиях?

Chuu
источник
Я думаю, что вы должны переименовать свой вопрос "Как я могу Remove-Itemбыстро потерпеть неудачу?"
Джей Базузи,
1
Это не относится именно к Remove-Item, это просто иллюстративный пример. Есть много других командлетов, которые будут блокировать ожидание пользовательского ввода в правильных условиях.
Chuu

Ответы:

5

Решение, предложенное Eris, эффективно запускает другой экземпляр PowerShell. Альтернативный способ сделать это с более простым синтаксисом - это выполнить оболочку для другого экземпляра powershell.exe.

powershell.exe -NonInteractive -Command "Remove-Item 'D:\Temp\t'"
Дамиан Пауэлл
источник
2
Мне очень нравится это решение, но оно возвращает ночные кошмары написания надежных хранимых процедур на TSQL до TRY / CATCH, что требует буквального окружения каждого запроса с образцом обнаружения ошибок.
Чуу
4

Смотрите Get-Help about_Preference_Variables:

$ ConfirmPreference
------------------
    Определяет, будет ли Windows PowerShell автоматически запрашивать у вас
    подтверждение перед запуском командлета или функции.

...

Нет: Windows PowerShell не запрашивает автоматически.
                         Чтобы запросить подтверждение конкретной команды, используйте
                         Подтвердите параметр командлета или функции.

Так:

> $ConfirmPreference = 'None'
Джей Базузи
источник
Я нашел это, чтобы увидеть проблему, которую я должен был установить. $ ConfirmPreference = 'Low'
Гай Томас,
Это не похоже на работу. Remove-Item в каталоге по-прежнему выдает сообщение после установки $ ConfirmPreference значения «Нет» или «Низкий»
Chuu
Работает на Remove-ADUser(Server 2012R)
velkoon
2

Хорошо, это действительно некрасиво, но святые пятна горчицы это "работает".

Вопросы:

  • Я не разобрался, как продолжить после первой ошибки
  • В этом случае он удаляет простые файлы, затем останавливается на первой папке
  • Я не понял, как заставить этот командлет работать, если я добавлю параметр UseTransaction
  • Это будет работать только для простого случая (команды, которые мало что делают с текущей средой). Я не проверял ничего сложного

    $MyPS = [Powershell]::Create()
    $MyPS.Commands.AddCommand("Remove-Item")
    $MyPS.Commands.AddParameter("Path", "D:\Temp\t")
    $MyPS.Invoke()

Выход:

Commands                                                                                                                 
--------                                                                                                                 
{Remove-Item}                                                                                                            
{Remove-Item}                                                                                                            
Exception calling "Invoke" with "0" argument(s): "A command that prompts the user failed because the host program or the 
command type does not support user interaction. The host was attempting to request confirmation with the following 
message: The item at D:\Temp\t has children and the Recurse parameter was not specified. If you continue, all children 
will be removed with the item. Are you sure you want to continue?"
At line:19 char:1
+ $MyPS.Invoke()
+ ~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : CmdletInvocationException
Эрис
источник
Причина, по которой я не пометил это как решение, заключается в том, что я не нашел времени для его тестирования. Кто-нибудь развертывал или тестировал этот код помимо автора?
Чуу
0

Все вышеперечисленные решения не помогли мне, когда я создавал каталог, а это означало, что мне было предложено оканчивать все директории, которые создавал мой скрипт, что было много. То, что работало для меня, было приложено | Out-null для передачи результатов в Out-Null

New-Item -ItemType Directory -Path $directory -Force:$true | Out-Null

Обратите внимание, что $ Directory - это строка с полным путем к каталогу, который вы хотите создать. Надеюсь, это сэкономит кому-то время: P

Крис Спраг
источник
-1

Я предлагаю две техники

а) Добавить -force

б) Добавить -errorAction silently continue

Вот как я исследую, какие командлеты поддерживают определенный параметр

Get-Command | where { $_.parameters.keys -contains "erroraction"}
Гай Томас
источник
Одна из причин, по которой я пошел по этому пути, заключается в том, что я обычно хочу сделать противоположность -force, то есть что-то вроде -alwaysbackoff. Я обнаружил, что большинство команд, которые поддерживают -force, похоже, не имеют возможности откатиться назад.
Chuu
1
Как в стороне, удобная аббревиатура для -errorAction SilentlyContinueэто -ea 0.
Джей Базузи