将参数从 Powershell 传递到批处理脚本

Jho*_*nny 6 windows powershell batch-file

我需要将带有特殊字符的密码从 powershell 脚本automation.ps1传递到批处理脚本batch_script.bat,然后通过管道将其传输到main.py. 从batch_script.batto管道main.py工作正常,即身份验证成功。但是,当我运行上述整个过程时,身份验证失败,但echoing the password 显示正确的密码字符串。

我的猜测是特殊字符存在问题。传递这些字符串的安全方法是什么?

背景

我想通过 Python 脚本从某些外部源自动执行每日下载main.py。此过程需要密码。所以我写了一个batch_script.bat在提示输入密码时将密码传递给 Python 脚本的方法。但是,我不想将密码作为纯文本存储在批处理脚本中,所以我加密了密码并编写了另一个层automation.ps1来解密密码并将其作为纯文本传递给batch_script.bat.

自动化.ps1

# get password
$securePassword = Get-Content "<file_path>" | ConvertTo-SecureString
$credentials = New-Object System.Management.Automation.PsCredential("<user_name>",$securePassword)
$unsecurePassword = ($credentials).GetNetworkCredential().Password

# call script
$script = "<path>\batch_script.bat"
$args = @("`"<user name>`"","`"$unsecurePassword`"")
start-process $script $args
Run Code Online (Sandbox Code Playgroud)

批处理脚本.bat

(我知道在这个例子中我丢弃了传递的用户名,只是想保留我传递多个参数的事实,以防与它有任何相关性)

@echo off
SET username=%~1
SET password=%~2
echo(%password%|python main.py
Run Code Online (Sandbox Code Playgroud)

sub*_*der 5

通过以下内容,所有特殊字符都应该得到很好的处理。如果需要转义任何字符,请选中此项

$pass 可以是任何字符串,但检查powershell的特殊字符

$pass="%^&<>|'\``,;=(\)![]\/";
# Wait till it ends with -Wait when using -NoNewWindow.
# It may be comprehensible to use `" instead of "" to denote we are enclosing string in quotes.
(thanks @mklement0 for elaboration).
start-process -Wait -NoNewWindow .\script.cmd "`"$pass`""
Run Code Online (Sandbox Code Playgroud)
script.cmd
    setlocal

    rem Remove Double quotes
    set "arg=%~1"

    rem Test result with base64 encoding
    echo|set/p="%arg%"|openssl base64
    rem echo is used with set/p to prevent trailing new line.
    echo|set/p="%arg%"|python main.py

    rem Test with following, argument is in double quotes
    rem script "%^&<>|'\`,;=(\)![]\/"
    rem Expected result
    rem %^&<>|'\`,;=(\)![]\/



Run Code Online (Sandbox Code Playgroud)


Nic*_*oru 1

您可以使用/-argumentlist开关 将参数传递给 powershell 中的批处理文件。对于你来说,你可以使用:startsaps

saps "$script" -argumentlist $args
Run Code Online (Sandbox Code Playgroud)

但我建议先分手,$args因为它可能行不通,因为要传递参数,您通常希望一次传递一个参数,例如:

saps "$script" -argumentlist "1","2","3"
Run Code Online (Sandbox Code Playgroud)

大多数情况下,通过$args是有效的,但也有一些情况是无效的。大多数时候你都很好

  • 仔细看看:鉴于第二个 _positional_ 参数的“-ArgumentList”参数是_implied_,您的解决方案实际上与OP自己的尝试相同,“start-process $script $args”(不考虑周围的双引号)您的解决方案中的“$script”是多余的)。除此之外,通过变量(`$args`)传递参数数组与通过_literal_数组(`"1","2","3"`)传递参数之间没有区别。 (2认同)
  • 虽然将参数作为数组元素传递_应该_是最稳健的方法,但遗憾的是,由于长期存在的错误,事实并非如此:请参阅[此 GitHub 问题](https://github.com/PowerShell/PowerShell/issues/5576 )。最终,将参数作为_单字符串_传递,并根据需要嵌入双引号会更简单;例如,不要使用 `Start-Process $script 'one', 'two (2)'`,而是使用 `Start-Process $script "one \`"two (2)\`""` (2认同)