通过批处理文件以管理员身份运行带参数的PowerShell脚本。

4
当我通过批处理文件以非管理员身份运行脚本时,它会传递参数,但是当我以管理员身份运行脚本时,它不会传递参数。
我正在尝试以下链接中的命令,但没有成功: run-script-within-batch-file-with-parameters 通过批处理文件以管理员身份执行脚本的命令:
PowerShell -NoProfile -ExecutionPolicy Bypass -Command "& {Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File "D:\z_Batchs e Scripts\Batchs\Normaliza_LUFS\ArqsNorms_LUFS_pass.ps1' '%_vLUF%'  -Verb RunAs}" 
%_vLUF% 是需要传递的参数。
错误信息:
No line:1 character:4
+ & {Start-Process PowerShell -ArgumentList '-NoProfile -ExecutionPolic ...
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Start-Process], ParameterBindingException
    + FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.StartProcessCommand

在PowerShell脚本中接收参数的命令:

Param(
     [decimal]$env:_vLUF
)

可能出现问题的是批处理文件中的命令还是PowerShell脚本中的命令?

测试:
当以非管理员身份通过批处理文件执行脚本时,而参数在PowerShell脚本中被定义为:

PowerShell中的参数:

Param(
     [decimal]$env:_vLUF
)

批处理文件中的命令可在非管理员身份下运行脚本:

powershell.exe -executionpolicy remotesigned -File "D:\z_Batchs e Scripts\Batchs\Normaliza_LUFS\ArqsNorms_LUFS_pass.ps1" %_vLUF%

注意:
target参数名不需要使用命名参数。
结果: enter image description here 结论:
当脚本通过批处理文件运行时,即使脚本中使用的参数被定义为环境参数,例如:[decimal]$env:_vLUF,并且参数值为负数,例如:-11.0,它也能正常工作,而无需作为管理员运行。
为什么Powershell在没有作为管理员运行脚本时正确解释参数中的减号,而在作为管理员运行时却不能正确解释减号,这是一个问题,我留给专家们去解决!
不过,我的问题已经得到了@mklement0先生的很好回答。

你的引用有问题。在你的路径之前,你有一个双引号终止了第一个调用。 - Abraham Zinala
@Abraham Zinala,什么是正确的方法? - Clamarc
转义引号(同时提供其结束引号),或转义路径中的空格。 - Abraham Zinala
1
@Abraham Zinala,我只是在路径末尾加了双引号,就可以了吗?"D:\z_Batchs e Scripts\Batchs\Normaliza_LUFS\ArqsNorms_LUFS_pass.ps1"' - Clamarc
1个回答

4

您的.ps1脚本参数声明存在缺陷:

Param(
     [decimal]$env:_vLUF  # !! WRONG - don't use $env:
)

更多信息请参见底部部分。

应该是:

Param(
     [decimal] $_vLUF  # OK - regular PowerShell variable
)

PowerShell中的参数被声明为普通变量,而不是环境变量($env:)。

(虽然可以将环境变量作为参数(参数)传递,但另一种方法是直接在脚本主体中按名称引用它们。)


你的PowerShell CLI调用也存在引号问题。

请尝试使用以下命令:

powershell -NoProfile -ExecutionPolicy Bypass -Command "Start-Process -Verb RunAs powershell -ArgumentList '-NoProfile -ExecutionPolicy Bypass -File \"D:\z_Batchs e Scripts\Batchs\Normaliza_LUFS\ArqsNorms_LUFS_pass.ps1\" -_vLUF %_vLUF%'"

具体而言:
  • 在使用Windows PowerShell CLI(powershell.exe)时,嵌入的 "字符必须转义为\"(如此标注),但是,由于%_vLUF%代表一个[decimal],您无需引用它。

    • 然而,您似乎遇到了影响PowerShell版本至少到7.2.4的错误(当前版本),即如果参数以-开头,例如负数-11.0,则-File CLI参数始终将其解释为参数名称,即使使用引号也无济于事。请参见GitHub issue #17519

    • 上面使用的解决方法是使用命名参数,即在值之前加上目标参数名称:-_vLUF %_vLUF%

  • 顺便提一下:没有理由使用& { ... }来调用通过-Command-c)参数传递给PowerShell CLI的代码 - 直接使用...即可,就像上面所示。早期版本的CLI文档错误地建议需要& { ... },但现已进行了更正。


至于尝试使用[decimal]$env:_vLUF作为参数声明的失败尝试
Param(
     [decimal]$env:_vLUF  # !! EFFECTIVELY IGNORED
)

有效的忽略

然而,如果环境变量_vLUF被定义了,它可以在脚本的主体中访问,与是否传递参数无关。

  • 在从批处理文件直接调用你的.ps1脚本时,_vLUF作为环境变量确实存在,因为在cmd.exe(批处理文件的解释器)中,变量也总是环境变量 - 与PowerShell不同。

    • 也就是说,如果%_vLUF%在批处理文件中有值,则你从其中启动的powershell子进程会自动将其视为$env:_vLUF
  • 相反,如果你从这样的PowerShell子进程通过Start-Process启动一个提升权限的进程,那么新的提升的进程就看不到调用者的环境变量 - 这是出于安全考虑。

注意:

  • 即使PowerShell语法上支持[decimal]$env:_vLUF作为参数声明,这也应该被视为一个错误

  • 发生的事情是,如果有参数传递到[decimal]$env:_vLUF,那么实际上确实创建了一个名为env:_vLUF的常规变量,并将其绑定,但在尝试获取该变量的值时,在你的脚本主体中,它被环境变量预占了。

    • 因此,调用可能会失败,即使参数被类型约束,你传递的值无法转换为该类型(在此案例中是[decimal])。

    • 如果调用不会失败,则类型约束被忽略$env:_vLUF始终是[string]类型,因为所有环境变量都是如此。


@Clamarc,我看到了在非管理员调用中需要在负数前面加上目标参数名称的问题,并已在https://github.com/PowerShell/PowerShell/issues/17519上报告了此问题。这个错误报告是针对PowerShell_Core的,所以要在Windows PowerShell中测试它,请将“pwsh”替换为“powershell.exe”。 - mklement0
@Clamarc,关于PowerShell窗口闪烁的问题:很可能是批处理文件引起了闪烁,这种情况通常发生在从现有控制台窗口外部调用控制台应用程序时,例如通过在文件资源管理器中双击批处理文件。至于运行控制台应用程序隐藏的技巧,请参见此答案 - mklement0
请查看我问题中的 test。如果脚本在非管理员身份下执行,并且我们在脚本参数中定义变量,就好像它是一个环境变量,例如 [decimal]$env:_vLUF,脚本可以正常识别负号并正常接收变量。如果脚本在非管理员身份下运行,并且我们在脚本参数中正常定义变量,例如 [decimal] $_vLUF,则脚本会出错并无法识别负值,也就是说,[decimal]$env:_vLUF 可以工作,但 [decimal] $_vLUF 不能工作。 - Clamarc
@Clamarc,啊,我错过了$env:_vLUF的角度 - 请看我的更新(新的底部部分)。简而言之:您的param()声明在直接(非提升)调用中有效,但实际上被忽略,并且只是偶然起作用。在提升的调用中,它会可预见地失败。 - mklement0
好的,让我们等待GitHub工作组分析这个错误。关于这个错误的另一个细节:我在Superuser网站上提出了一个问题,没有人能够回答,在进行了几次测试后,我发现问题与以非管理员身份执行批处理文件时Powershell的行为有关。在我的测试中,Out-file命令会给出不同的结果。我自己回答了我的问题,所以如果你能在Superuser上看到我的答案,链接是:https://superuser.com/questions/1725299/powershell-commands-not-working-correctly-via-batch-file - Clamarc
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接