【问题标题】:powershell.exe start-process -About "\" when using the Verb optionpowershell.exe start-process -关于使用动词选项时的“\”
【发布时间】:2020-11-15 13:29:55
【问题描述】:

感谢您的帮助。
我在 Windows 10 命令提示符下使用 Powershell 并尝试以管理权限执行命令。
当我尝试以下三个 a、b 和 c 时,我无法像我想的那样以“RunAs”开头。
有谁知道如何解决这个问题?

(a) 可以成功执行。参数也正确传递。
powershell.exe start-process -FilePath 'TestEnv.cmd' -ArgumentList '\"a\" \"B C\" \"d\"' -Verb Open

(b) UAC 确认后不启动。
powershell.exe start-process -FilePath 'TestEnv.cmd' -ArgumentList '\"a\" \"B C\" \"d\"' -Verb RunAs

(c) 可以调用,但是“B C”参数没有体现在“双引号”参数中,单独识别“B C”。
powershell.exe start-process -FilePath 'TestEnv.cmd' -ArgumentList '"a" "B C" "d"' -Verb RunAs

翻译为www.DeepL.com/Translator(免费版)

【问题讨论】:

    标签: powershell cmd elevated-privileges start-process


    【解决方案1】:

    tl;dr

    REM From cmd.exe (Command Prompt) / a batch file:
    powershell.exe -c Start-Process cmd.exe -Verb RunAs ('/k {0} \"a\" \"B C\" \"d\"' -f ((Convert-Path 'TestEnv.cmd') -replace ' ', '^^ '))
    
    • /k 替换为/c 以使批处理文件退出时自动关闭新窗口。

    • 批处理文件的工作目录C:\Windows\System32

    如果你还想确保批处理文件在调用者的当前目录中执行

    REM From cmd.exe (Command Prompt) / a batch file:
    powershell.exe -c Start-Process cmd.exe -Verb RunAs ('/k cd \"{0}\" ^&^& {1} \"a\" \"B C\" \"d\"' -f $PWD.ProviderPath, ((Convert-Path 'TestEnv.cmd') -replace ' ', '^^ '))
    

    继续阅读以获得解释。


    主要问题是:

    • 当您将批处理文件路径直接 - 作为可执行文件 - 传递给Start-Process -Verb RunAs 时,传递包含双引号的参数列表似乎存在问题 (@987654333 @) - 我不知道原因,但问题出现在下面 PowerShell 的层中,可能在底层System.Diagnostics.ProcessStartInfo .NET API 中,甚至可能在底层@987654322 中@WinAPI 函数。

    • (如果你需要 no 参数或者它们都不需要",你可以直接将批处理文件路径作为可执行文件传递;默认情况下,因为底层可执行文件是cmd.exe,它位于C:\Windows\System32C:\Windows\System32 成为工作目录,您可以使用-WorkingDirectory 覆盖它,但请注意,您必须使用(可能是相对的)引用批处理文件路径,如果它位于其他地方。)

    解决方法

    • 不要使用批处理文件路径直接作为要启动的可执行文件,而是使用cmd.exe作为可执行文件,并将批处理文件路径及其所有参数作为参数传递给@987654342 @ 选项(或 /k,如果您想保持新窗口打开)。

    • 不幸的是,-Verb Runascmd.exe 总是使用 C:\Windows\System32 作为新进程的工作目录 - 传递带有 -WorkingDirectory 参数的启动目录然后被忽略。

      • 这同样适用于powershell.exe,但奇怪的是,适用于pwsh.exe(PowerShell [Core] v6+)和基于.NET的可执行文件,它们( a) 默认保留调用者的工作目录,并且 (b) 遵守 -WorkingDirectory 参数。
    • 因此,如果您的 TestEnv.cmd 批处理文件位于 当前 目录中 - 而不是 PATH 环境变量 ($env:PATH) 中列出的目录 - 您必须通过批处理文件的完整路径cmd.exe,您可以使用Convert-Path 确定。

      • 注意:如果你的批处理文件PATH,可以这么说,这一步是没有必要的。

      • 不幸的是,如果批处理文件的完整路径包含空格,则需要另一个解决方法:因为"..."-莫名其妙地包含批处理文件路径失败,各个空格必须改为^-转义。

    PowerShell 内部 这意味着您的命令必须如下所示(请注意,我使用 /k 保持新窗口打开,用于诊断目的;使用/c 在批处理文件退出时自动关闭窗口):

    # From inside PowerShell:
    Start-Process cmd.exe -Verb RunAs (
      '/k {0} "a" "B C" "d"' -f ((Convert-Path 'TestEnv.cmd') -replace ' ', '^ ')
    )
    

    警告:由于正在调用cmd.exe,因此C:\Windows\System32 是工作目录。
    如果您还想确保批处理文件在调用者的当前目录中执行,则必须在前面添加cd 命令:

    # From inside PowerShell:
    Start-Process cmd.exe -Verb RunAs (
      '/k cd "{0}" && {1} "a" "B C" "d"' -f $PWD.ProviderPath, ((Convert-Path 'TestEnv.cmd') -replace ' ', '^ ')
    )
    

    cmd.exe(命令提示符)/批处理文件、通过Windows PowerShell's CLIpowershell.exe(请注意,在PowerShell [Core ] v6+ 现在是pwsh),增加了额外的复杂性:

    • " 字符。必须将其转义为 \",以便 PowerShell 将它们识别为要执行的命令的一部分,而不是 CLI 参数周围的句法引用。

    • ^ 必须转义为 ^^,并且在下面的第二个命令中,& 必须转义为 ^&,以防止 cmd.exe 解释这些字符(预先)。

    REM From cmd.exe (Command Prompt) / a batch file:
    powershell.exe -c Start-Process cmd.exe -Verb RunAs ('/k {0} \"a\" \"B C\" \"d\"' -f ((Convert-Path 'TestEnv.cmd') -replace ' ', '^^ '))
    

    如果你还想确保批处理文件在调用者的当前目录中执行

    REM From cmd.exe (Command Prompt) / a batch file:
    powershell.exe -c Start-Process cmd.exe -Verb RunAs ('/k cd \"{0}\" ^&^& {1} \"a\" \"B C\" \"d\"' -f $PWD.ProviderPath, ((Convert-Path 'TestEnv.cmd') -replace ' ', '^^ '))
    

    【讨论】:

    • 好一个。我试了一下,但我仍然不明白为什么 RunAs 的行为会发生变化(在这里谈论引号),就好像突然不可能在没有明显原因的情况下在参数列表中包含空格。解决方法做得很好。
    • 谢谢,@PMental。是的,这种行为听起来肯定有问题。
    • 对我来说听起来也很糟糕。我提出了一个问题github.com/PowerShell/PowerShell/issues/14099
    • 谢谢。我知道这是一个错误。我知道如何传递另一种方法,例如 CMD。我只是不知道它,想知道是否可以通过使用 Powershell 的选项和转义序列来解决它。谢谢。
    • 谢谢大家,mklement0。答案被批准了。除了Powershell,WSH的ShellExecute函数似乎也有同样的问题。我一直在使用 ShellExecute 函数的管理权限运行 Powershell,以解决 JSCRIPT 中的这个问题。然后我在 Powershell 中运行所需的命令和参数来解决这个问题。您向我展示的替换方法 mklement0 非常有用。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-28
    • 1970-01-01
    • 2020-07-21
    • 1970-01-01
    相关资源
    最近更新 更多