В течение многих лет я использовал cmd/DOS/Windows
оболочку и передавал аргументы командной строки пакетным файлам. Например, у меня есть файл, zuzu.bat
и в нем я доступ %1
, %2
и т.д. Теперь я хочу сделать то же самое , когда я называю PowerShell
сценарий when I am in a Cmd.exe shell
. У меня есть сценарий 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>
источник
xuxu p1 p2 p3 p4
»).Покопавшись в документации PowerShell, я обнаружил полезную информацию об этой проблеме. Вы не можете использовать,
$args
если вы использовалиparam(...)
в начале вашего файла; вместо этого вам нужно будет использовать$PSBoundParameters
. Я скопировал / вставил ваш код в сценарий PowerShell, и он работал, как и следовало ожидать, в PowerShell версии 2 (я не уверен, в какой версии вы были, когда столкнулись с этой проблемой).Если вы используете
$PSBoundParameters
(и это работает ТОЛЬКО, если вы используетеparam(...)
в начале своего скрипта), то это не массив, это хеш-таблица, поэтому вам нужно будет ссылаться на нее, используя пару ключ / значение.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
источник
pwsh .\ParamTest.ps1 -arg1 val1 -listOfArgs val2 val3 val4
, мне это действительно не нравится. С другой стороны, если я использую PowerShell и работаю.\ParamTest.ps1 -arg1 val1 -listOfArgs val2 val3 val4
, это работает так, как я ожидал. Я слышал, что именно так он и должен работать из «соображений безопасности».Powershell>pwsh .\ParamTest.ps1 val1 val2 val3 val4
дает:Num Args: 4 $p1=val1 $p2=val2 $p3=val3 $p4=val4
param
это языковая конструкция, но она должна быть первой в файле. Вы перед этим объявили переменную или что-то еще? Дополнительная информация здесь: docs.microsoft.com/en-us/powershell/module/…Хорошо, сначала это нарушает базовую функцию безопасности в PowerShell. При таком понимании вот как вы можете это сделать:
Вы также можете указать здесь
-NoProfile
аргумент в зависимости от того, что делает ваш профиль.источник
Вы можете объявить свои параметры в файле, например param:
[string]$para1 [string]$param2
А затем вызовите файл PowerShell вот так
.\temp.ps1 para1 para2....para10
и т. Д.источник
Возможно, вы можете заключить вызов PowerShell в
.bat
файл следующим образом:rem ps.bat @echo off powershell.exe -command "%*"
Если вы затем поместили этот файл в папку в своем
PATH
, вы могли бы вызывать сценарии PowerShell следующим образом:Однако цитирование может быть немного запутанным:
ps write-host """hello from cmd!""" -foregroundcolor green
источник
Вы не можете получить "xuxu p1 p2 p3 p4", как кажется. Но когда вы находитесь в PowerShell и устанавливаете
PS > set-executionpolicy Unrestricted -scope currentuser
Вы можете запускать эти сценарии следующим образом:
или же
или же
./xuxu.ps1 p1 p2 p3 p4
Надеюсь, вам станет удобнее работать с PowerShell.
источник
если вы хотите вызывать сценарии 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
источник