windows - 通过 CMD 和 PowerShell 终端提示符链执行复杂指令

标签 windows powershell cmd

我最近一直在努力使一组指令能够作为单行代码发挥作用。我想要实现的是以提升的权限运行特殊的 CMD 指令,但从非特权的 CMD 开始。我发现我想要做的事情可以通过利用 PowerShell 作为中间人来实现,并且我成功地创建了一些行之有效的俏皮话,但我无法理解更复杂的场景。这是我计划使用的程序流程:

CMD(非特权)-> PowerShell(非特权,触发管理员权限)-> CMD 或 PowerShell(现在具有管理员权限)-> 执行所需的指令(需要管理员权限)

我必须从非特权 CMD 开始。我计划从那里启动 PS session ,因为我发现了一个很好的“技巧”(即,在命令末尾使用 -Verb RunAs),它可以让我切换到管理 CMD/PS session 只需在 Windows UAC GUI 中按"is"即可。

这是我必须在管理 CMD/PS session 中运行的最终命令:

tbcon -run:"a2lmerger --optionsfile _gen\swb\module\asap2\opt\a2lmerger_internal.opt"

此外,该命令还必须从特定文件夹执行。 我可以确认,这个命令本身可以正常工作。

我已经一步步进行,我可以保证下一个命令在从 PS 启动时有效:

cmd \"/k cd C:\MY\PATH\WITHOUT\SPACES && tbcon -run:"a2lmerger --optionsfile _gen\swb\module\asap2\opt\a2lmerger_internal.opt"\"

因此,我尝试实现完整的解决方案,从非特权 CMD 启动它:

powershell.exe -Command Start-Process cmd \"/k cd C:\MY\PATH\WITHOUT\SPACES && tbcon -run:"a2lmerger --optionsfile _gen\swb\module\asap2\opt\a2lmerger_internal.opt" && exit\" -Verb RunAs

但这失败了,因为 tbcon 没有正确接收参数,并且确实报告了我:

[tbcon] ERROR - Invalid argument: '--optionsfile'.

我怀疑这是因为 CMD 弄乱了 a2lmerger--opstionsfile 之间的空格(最终是 --optionsfile 之间的空格)和 _gen[...]),但我花了很多时间试图解决这个问题,但运气不佳。

此外,如果能够将 C:\MY\PATH\WITHOUT\SPACES 替换为也包含空格的路径,那就太好了,但这将是一个额外的好处。

感谢大家的帮助!

最佳答案

任何 "字符。您需要将其保留为传递给 Windows PowerShell 的命令的一部分 CLI-Command参数必须转义为 \" (否则,初始命令行解析将删除它们)。

  • 虽然您已经为嵌套 cmd 执行此操作命令行总体,嵌入式" -run: 周围的字符选项值缺乏这种转义。

  • 将它们转义为 \"然而,这还不够,因为它们需要被解释为 "PowerShell 字符串文字中,其中 "必须转义为 `" 。因此,您必须以正确的顺序组合这些转义机制,即:`\"

    • 这同样适用于括起 cd "..." 中的参数

因此:

powershell.exe -Command Start-Process cmd \"/k cd `\"C:\MY\PATH\WITH SOME\SPACES`\" && tbcon -run:`\"a2lmerger --optionsfile _gen\swb\module\asap2\opt\a2lmerger_internal.opt`\" && exit\" -Verb RunAs

注意边缘情况:

<强> cmd.exe本身没有转义的概念"字符。;也就是说,甚至是"\"被视为开始或结束双引号字符串,嵌套 \"...\"因此创建 cmd.exe 的子字符串考虑未加引号,导致诸如 & 之类的字符被解释为 cmd.exe 元字符,放在前面,可以破坏命令
此陷阱适用于从 cmd.exe 运行的任何命令。 ,不仅仅是在调用PowerShell时;这是 cmd.exe -仅示例:

:: From cmd.exe.
:: BREAKS, because the 2nd & is considered UNQUOTED causing
:: interpretation as the statement-sequencing operator.
:: Prints "A & \"B, then looks for a command named C\" D"
echo "A & \"B & C\" D"

解决方法:

  • 手动、视情况解决方法:选择性 ^ -转义这样的字符,但是需要具体了解哪些子字符串cmd.exe考虑未加引号,这是麻烦且不平凡的。

    :: From cmd.exe.
    :: OK, due to ^-escaping of the 2nd &
    :: Prints "A & \"B & C\" D"
    echo "A & \"B ^& C\" D"
    
  • 有条理的解决方法:

    • 如果 objective-c LI 支持,请使用 ""代替\" 作为 Fugitive " 里面"..."字符串,这从根本上避免了问题( cmd.exe ,它也不将 "" 识别为特殊的,然后实际上看到 "..." 字符串的串联,因此一切在其中引用)。
      使用 Microsoft 编译器创建的 CLI 通常确实接受 "" (可与 \" 互换),其中包括 pwsh.exe PowerShell(核心)7+ CLI,但不幸的是 - 不是 powershell.exe Windows PowerShell CLI(请参阅下一点)。
      调用pwsh.exe时,附上 -Command "..." 中的参数总体而言,并使用 ""用于嵌入式" :

      :: From cmd.exe.
      :: OK, due to "..." enclosure and
      :: escaping of embedded " as "" (if you tried to use \", this would break)
      :: Prints "A & B"
      pwsh.exe -Command " Write-Output ""A & B"" "
      
    • 对于powershell.exe Windows PowerShell CLI,不幸的是,解决方法比较麻烦; 使用"^"" (原文如此)在 -Command"..." 中包含的参数总体:

      :: From cmd.exe.
      :: OK, due to overall "..." enclosure and
      :: escaping of embedded " as "^"" (sic)
      :: Prints "A & B"
      powershell.exe -Command " Write-Output "^""A & B"^"" "
      
      • 不幸的是,这种技术for /f 内部不起作用循环,需要更复杂的解决方法,在 this answer 的底部部分讨论.

关于windows - 通过 CMD 和 PowerShell 终端提示符链执行复杂指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76289281/

相关文章:

windows - 尽管设置ImagePullPolicy = Never,但仍无法使用kubectl和minikube启动pod

powershell - powershell-连接N个文本文件,并在每行前添加文件名

windows - 批处理脚本变量不保持设置

适用于 Windows XP 和 2003 的 Windows 批处理选择命令

c++ - 如何完全清除Windows C++中的所有用户环境变量

c++ - 在 Windows 上,什么时候需要附加到目录路径才能使 _stat 成功?

java - SFTP使用java从Windows服务器检索文件到Linux服务器

function - 连接路径和文件

powershell - 在不使用 PowerShell 的情况下在 Nuget 包中嵌套文件

windows - Typepref 命令在运行远程命令时没有给出有效的计数器