Durante anos, usei o cmd/DOS/Windows
shell e passei argumentos de linha de comando para arquivos em lote. Por exemplo, eu tenho um arquivo, zuzu.bat
e nele, o acesso I %1
, %2
etc. Agora, eu quero fazer o mesmo quando eu chamar um PowerShell
roteiro when I am in a Cmd.exe shell
. Eu tenho um script xuxu.ps1
(e adicionei PS1 à minha variável PATHEXT e os arquivos PS1 associados ao PowerShell). Mas não importa o que eu faça, parece que não consigo obter nada da $args
variável. Sempre tem comprimento 0.
Se eu estiver em um PowerShell
shell, em vez de cmd.exe
, ele funciona (é claro). Mas ainda não estou confortável o suficiente para viver no ambiente do PowerShell em tempo integral. Eu não quero digitar powershell.exe -command xuxu.ps1 p1 p2 p3 p4
. Eu quero digitar xuxu p1 p2 p3 p4
.
Isso é possível e, em caso afirmativo, como?
O exemplo que não consigo fazer é trivial, foo.ps1:
Write-Host "Num Args:" $args.Length;
foreach ($arg in $args) {
Write-Host "Arg: $arg";
}
Os resultados são sempre assim:
C:\temp> foo
Num Args: 0
C:\temp> foo a b c d
Num Args: 0
c:\temp>
fonte
xuxu p1 p2 p3 p4
").Depois de vasculhar a documentação do PowerShell, descobri algumas informações úteis sobre esse problema. Você não pode usar o
$args
se usouparam(...)
no início do arquivo; em vez disso, você precisará usar$PSBoundParameters
. Eu copiei / colei seu código em um script do PowerShell e funcionou como você esperava no PowerShell versão 2 (não tenho certeza de qual versão você estava usando quando encontrou este problema).Se você estiver usando
$PSBoundParameters
(e isso SÓ funciona se estiver usandoparam(...)
no início do seu script), então não é um array, é uma tabela hash, portanto, você precisará referenciá-lo usando o par chave / valor.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
E quando chamado com ...
PS> ./foo.ps1 a b c d
O resultado é...
Num Args: 4 $p1=a $p2=b $p3=c $p4=d
fonte
pwsh .\ParamTest.ps1 -arg1 val1 -listOfArgs val2 val3 val4
, realmente não gosto disso. Por outro lado, se estou no PowerShell e faço.\ParamTest.ps1 -arg1 val1 -listOfArgs val2 val3 val4
isso, funciona como eu esperava. Ouvi dizer que é assim que ele deve funcionar por "motivos de segurança".Powershell>pwsh .\ParamTest.ps1 val1 val2 val3 val4
rendimentos:Num Args: 4 $p1=val1 $p2=val2 $p3=val3 $p4=val4
param
é uma construção de linguagem, porém deve ser a primeira coisa no arquivo. Você declarou uma variável ou algo mais antes dela? Mais informações aqui: docs.microsoft.com/en-us/powershell/module/…OK, então primeiro isso está quebrando um recurso básico de segurança no PowerShell. Com esse entendimento, aqui está como você pode fazer isso:
Você também pode querer apresentar um
-NoProfile
argumento, dependendo do que o seu perfil faz.fonte
Você pode declarar seus parâmetros no arquivo, como param:
[string]$para1 [string]$param2
Em seguida, chame o arquivo PowerShell assim
.\temp.ps1 para1 para2....para10
, etc.fonte
Talvez você possa agrupar a invocação do PowerShell em um
.bat
arquivo assim:rem ps.bat @echo off powershell.exe -command "%*"
Se, em seguida, você colocou esse arquivo em uma pasta em seu
PATH
, poderá chamar scripts do PowerShell como este:Citar pode ser um pouco confuso:
ps write-host """hello from cmd!""" -foregroundcolor green
fonte
Você pode não obter "xuxu p1 p2 p3 p4" como parece. Mas quando você está no PowerShell e define
PS > set-executionpolicy Unrestricted -scope currentuser
Você pode executar esses scripts como este:
ou
ou
./xuxu.ps1 p1 p2 p3 p4
Espero que isso o deixe um pouco mais confortável com o PowerShell.
fonte
se você deseja invocar scripts ps1 de cmd e passar argumentos sem invocar o script como
powershell.exe script.ps1 -c test script -c test ( wont work )
você pode fazer o seguinte
setx PATHEXT "%PATHEXT%;.PS1;" /m assoc .ps1=Microsoft.PowerShellScript.1 ftype Microsoft.PowerShellScript.1=powershell.exe "%1" %*
Isso pressupõe que powershell.exe esteja em seu caminho
https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/ftype
fonte