Несмотря на то, что обходной путь уже найден, я думал, что люди могут быть заинтересованы в объяснении.
Относительно того, почему он ведет себя по-разному в оболочке по сравнению с cmd.exe, см. Powershell 2.0 - Запуск сценариев для вызова командной строки по сравнению с ISE
Как упомянуто в ссылке, есть разница между следующими двумя командами:
powershell ".\test.ps1"
powershell -File ".\test.ps1"
При использовании первого синтаксиса он, похоже, портится с областью действия, в результате чего команда Set-StrictMode изменяет строгий режим для функций, определенных в глобальной области действия.
Это вызывает ошибку (или, возможно, неверное предположение) в определении функции mkdir.
Функция использует метод GetSteppablePipeline, чтобы проксировать конвейер для командлета New-Item. Однако автор не учел тот факт, что раздел PROCESS все еще выполняется, даже если в конвейере ничего нет. Таким образом, при достижении раздела PROCESS автоматическая переменная $ _ не определяется. Если включен строгий режим, произойдет исключение.
Один из способов объяснить это для Microsoft - заменить следующую строку:
$steppablePipeline.Process($_)
со следующим:
if (test-path Variable:Local:_) {
$steppablePipeline.Process($_)
}
Я допускаю, что это может быть не лучшим способом исправить это, но накладные расходы будут незначительными. Другим вариантом было бы как-то проверить, является ли конвейер пустым в разделе BEGIN, а затем установить $ _ в $ null.
В любом случае, если вы запускаете свои скрипты с синтаксисом powershell.exe -File filename, вам не нужно об этом беспокоиться.