Как передать аргументы командной строки в файл ps1 PowerShell
В течение многих лет я использовал оболочку cmd/DOS/Windows
и передал аргументы командной строки пакетным файлам. Например, у меня есть файл zuzu.bat
, и в нем я получаю доступ к %1
, %2
и т.д. Теперь я хочу сделать то же самое, когда я вызываю PowerShell
script when I am in a Cmd.exe shell
. У меня есть script, xuxu.ps1
(и я добавил PS1 в свою переменную PATHEXT и связанные с ней файлы PS1 с помощью PowerShell). Но независимо от того, что я делаю, мне кажется, что я ничего не могу получить от переменной $args
. Он всегда имеет длину 0.
Если я в оболочке PowerShell
вместо cmd.exe
, он работает (конечно). Но мне еще не достаточно комфортно жить в среде PowerShell полный рабочий день. Я не хочу набирать powershell.exe -command xuxu.ps1 p1 p2 p3 p4
. Я хочу ввести xuxu p1 p2 p3 p4
.
Возможно ли это, и если да, то как?
Образец, с которым я не могу работать, тривиален, foo.ps1:
Write-Host "Num Args:" $args.Length;
foreach ($arg in $args) {
Write-Host "Arg: $arg";
}
Результаты всегда будут такими:
C:\temp> foo
Num Args: 0
C:\temp> foo a b c d
Num Args: 0
c:\temp>
Ответы
Ответ 1
Эта статья помогает. В частности, этот раздел:
-File
Запускает указанный script в локальной области ( "dot-sourced" ), так что функции и переменные, создаваемые script, доступны в текущем сеансе. Введите путь к файлу script и любые параметры. Файл должен быть последним параметром в команде, потому что все символы, введенные после имени параметра File, интерпретируются как путь к файлу script, за которым следуют параметры script.
то есть.
powershell.exe -File "C:\myfile.ps1" arg1 arg2 arg3
означает запуск файла myfile.ps1 и arg1 arg2 и arg3 - параметры для PowerShell script.
Ответ 2
ОК, поэтому сначала это нарушает базовую функцию безопасности в PowerShell. С этим пониманием, вот как вы можете это сделать:
- Откройте окно Windows Explorer
- Инструменты меню → Параметры папки → вкладка Типы файлов
- Найдите тип файла PS1 и нажмите кнопку "Дополнительно"
- Нажмите кнопку "Создать"
- Для Action put: Открыть
- Для приложения put: "C:\WINNT\system32\WindowsPowerShell\v1.0\powershell.exe" "файл" "% 1" % *
Возможно, вы захотите также добавить аргумент -NoProfile
в зависимости от того, что делает ваш профиль.
Ответ 3
После обработки документации PowerShell я обнаружил полезную информацию об этой проблеме. Вы не можете использовать $args
, если вы использовали param(...)
в начале вашего файла; вместо этого вам нужно будет использовать $PSBoundParameters
. Я копировал/вставлял ваш код в PowerShell script, и он работал так, как вы ожидали в PowerShell версии 2 (я не уверен, какая версия была включена, когда вы столкнулись с этой проблемой).
Если вы используете $PSBoundParameters
(и это ТОЛЬКО работает, если вы используете param(...)
в начале вашего script), то это не массив, это хеш-таблица, поэтому вам нужно будет ссылайтесь на нее с помощью пары ключ/значение.
param($p1, $p2, $p3, $p4)
$Script:args=""
write-host "Num Args: " $PSBoundParameters.Keys.Count
foreach ($key in $PSBoundParameters.keys) {
$Script:args+= "`$$key=" + $PSBoundParameters["$key"] + " "
}
write-host $Script:args
И когда вызывается с...
PS> ./foo.ps1 a b c d
Результат...
Num Args: 4
$p1=a $p2=b $p3=c $p4=d
Ответ 4
Вы можете объявить свои параметры в файле, например, param:
[string]$para1
[string]$param2
А затем вызвать файл PowerShell следующим образом .\temp.ps1 para1 para2....para10
и т.д.
Ответ 5
Возможно, вы можете перенести вызов PowerShell в файл .bat
следующим образом:
rem ps.bat
@echo off
powershell.exe -command "%*"
Если вы разместили этот файл под папкой в PATH
, вы могли бы вызвать сценарии PowerShell, как это:
ps foo 1 2 3
Цитата может немного запутаться:
ps write-host """hello from cmd!""" -foregroundcolor green
Ответ 6
Вы не можете получить "xuxu p1 p2 p3 p4", как кажется. Но когда вы находитесь в PowerShell, и вы установили
PS > set-executionpolicy Unrestricted -scope currentuser
Вы можете запустить эти скрипты следующим образом:
./xuxu p1 p2 p3 p4
или
.\xuxu p1 p2 p3 p4
или
./xuxu.ps1 p1 p2 p3 p4
Я надеюсь, что это сделает вас более удобным с PowerShell.
Ответ 7
если вы хотите вызывать сценарии ps1 из cmd и передавать аргументы, не вызывая сценарий, как
powershell.exe script.ps1 -c test
script -c test ( wont work )
Вы можете сделать следующее
setx PATHEXT "%PATHEXT%;.PS1" /m
assoc .ps1=Microsoft.PowerShellScript.1
ftype Microsoft.PowerShellScript.1=powershell.exe "%1" %*
Это предполагает, что powershell.exe находится на вашем пути
https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/ftype
Ответ 8
не указывайте $arg в условном блоке