Могу ли я настроить ошибку «не распознается как имя командлета» в Powershell?

Допустим, я сделал опечатку в командной строке:

whih foo

Powershell возвращает:

whih : The term 'whih' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ whih mocha
+ ~~~~
+ CategoryInfo          : ObjectNotFound: (whih:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException

Длинное сообщение полезно для сценариев, но для использования интерактивной оболочки я хотел бы заключить его в нечто более короткое, например:

'whih' isn't a cmdlet, function, script file, or operable program.

Можно ли обернуть ошибку и изменить ее на что-то более короткое?


person mikemaccana    schedule 02.08.2018    source источник
comment
Должен спросить, но я предполагаю, что блок попытки - это не то, что (предназначено для этой цели) вы хотите, и вы хотите изменить фактическую версию сообщения.   -  person Matt    schedule 02.08.2018
comment
@Matt Это верно, как уже упоминалось, он предназначен для интерактивного использования. Так что да, я не хочу заключать каждую команду в блок try. Просто ищу что-то для $profile   -  person mikemaccana    schedule 02.08.2018


Ответы (1)


Да, вы можете перехватить CommandNotFoundException с помощью CommandNotFoundAction!

$ExecutionContext.InvokeCommand.CommandNotFoundAction = {
  param($Name,[System.Management.Automation.CommandLookupEventArgs]$CommandLookupArgs)  

  # Check if command was directly invoked by user
  # For a command invoked by a running script, CommandOrigin would be `Internal`
  if($CommandLookupArgs.CommandOrigin -eq 'Runspace'){
    # Assign a new action scriptblock, close over $Name from this scope 
    $CommandLookupArgs.CommandScriptBlock = {
      Write-Warning "'$Name' isn't a cmdlet, function, script file, or operable program."
    }.GetNewClosure()
  }
}
person Mathias R. Jessen    schedule 02.08.2018
comment
Так проще, чем я думал. - person Matt; 02.08.2018
comment
Проксирование Format-Default или поиск языкового файла / данных, связанных с этим сообщением. Я понятия не имел, что можно сделать такой спусковой крючок. - person Matt; 02.08.2018
comment
@ Мэтт ах, это и умно, и ужасно нецелесообразно: P - person Mathias R. Jessen; 02.08.2018
comment
Верно. Однако это единственный вариант, о котором я мог подумать. Теперь мне нужно изучить, что вы здесь сделали, чтобы увидеть, как еще я могу это использовать :) - person Matt; 02.08.2018
comment
@Matt напишет мне на твиттер (или gitter), если тебе нужно больше вдохновения;) - person Mathias R. Jessen; 02.08.2018
comment
Нравится +1. Всегда ли перед $Name ставится глагол Get-? - person ; 02.08.2018
comment
@LotPings только тогда, когда поисковый запрос не в форме Verb-Noun (ошибка CommandDiscovery API возникает после попытки дважды, один раз как есть, один раз с добавлением Get-) - person Mathias R. Jessen; 02.08.2018
comment
@LotPings PowerShell применяет программные псевдонимы ко всем командам без глагола как Get-. Вы можете увидеть это, набрав service в командной строке. - person Maximilian Burszley; 02.08.2018
comment
Отличный ответ и отлично работает. Зачем .GetNewClosure() это необходимо? Спасибо! - person mikemaccana; 03.08.2018
comment
Также: это также влияет на скрипты ps1. Есть ли способ вызвать его только при интерактивном использовании? - person mikemaccana; 03.08.2018
comment
@mikemaccana .GetNewClosure() необходимо закрыть над переменной $Name. Обновленный ответ на оба ваших вопроса - person Mathias R. Jessen; 03.08.2018
comment
Спасибо @ MathiasR.Jessen - принято в качестве ответа, так как он соответствует всем требованиям! - person mikemaccana; 03.08.2018