我如何使用需要从命令提示符/批处理文件中引用的参数调用 PowerShell Start-Process 命令?

How I do invoke a PowerShell Start-Process command with arguments that require quoting from a Command Prompt / batch file?

我在 PowerShell 中尝试执行一个命令时遇到此错误:

我正在尝试 exec 这个命令:

powershell.exe Start-Process -FilePath "C:\Windows\System32\attrib +h +s "%CD%"" -Verb runAs

谁能帮我弄清楚为什么会发生这种情况以及如何解决它?

Can someone please help me figure out why this is happening?

Start-Process cmdlet 的 -FilePath 参数需要可执行文件 file 本身的名称或路径,而不是 整个命令行.

要传递给通过 -FilePath 指定的可执行文件的 参数 必须作为 单独 传递 ]array,通过 -ArgumentList (-Args) 参数。

cmd.exe(批处理文件)调用时,将整个命令行传递给 PowerShell 在单个 [=17] 中进行评估在概念上更清晰=]-封闭参数:

powershell.exe -Command "Start-Process -Verb RunAs -FilePath attrib.exe -Args +h, +s, '\"%CD%\"'"

注意需要转义 %CD% 双重 ,为了 PowerShell,首先将其包含在 ' 中,然后在 [=20] 中=] 里面:外层 ' 确保 PowerShell 本身将值识别为单个参数,嵌入的 \" 引号确保最终目标程序 attrib.exe 将值视为也只有一个论点。

这种双重转义的需要是不幸的,不应该是必要的 - this GitHub issue.

中对此进行了讨论

不需要完全限定 attrib.exe 的路径,它可以通过 DOS 和 PoSH 环境变量在本地使用。

powershell attrib 'd:\temp\SomeFile.txt'
# A                    D:\temp\SomeFile.txt

powershell attrib +r 'd:\temp\SomeFile.txt'

powershell attrib 'd:\temp\SomeFile.txt'
# A    R               D:\temp\SomeFile.txt

任何带空格的字符串都必须用引号引起来,参数也必须括起来,否则它们必须单独传递。

Start-Process powershell -ArgumentList "-NoExit","-Command  &{ $ConsoleCommand }" -Wait

在您的用例和我展示的内容中,您所做的只是调用 PoSH 以 运行 一个您可以在 DOS 中执行的 DOS 命令。那么,为什么要为此使用 PoSH,而不是 运行as 东西?

此外,当您按照您尝试的方式执行命令时,正确引用以将该命令正确限定为 运行 可能会造成混淆。这是该行的真正问题。 传递参数必须正确完成,如果处理不当,空格会导致问题,因此你的错误。

此外,为什么要从 cmd.exe 开始这项工作,只是为了结束 PoSH 控制台主机以执行 运行 这个命令?

只需在 PoSH 控制台主机中本机执行此操作,这就是您正在做的事情。省去额外的步骤和并发症。

只需启动 powershellexe,而不是 cmd.exe 和 运行 您的 DOS 命令。

attrib +r 'd:\temp\SomeFile.txt'

几乎没有 cmd.exe 可以做 PoSH 控制台不能做的事情,PoSH(控制台主机和 ISE)可以做很多 cmd.exe 做不到的事情。 那么,为什么不直接开始并留在 PoSH 中呢?

您可以 运行 在 PoSH 控制台主机中使用所有 DOS 命令(在 ISE 中,要让它们工作需要付出更多的努力),或者只使用 PoSH 等价物。

Use a PowerShell Cmdlet to Work with File Attributes --- 'blogs.technet.microsoft.com/heyscriptingguy/2011/01/26/use-a-powershell-cmdlet-to-work-with-file-attributes'

那个牙有点长,我知道。但是,您也可以执行以下操作,获取属性,并使用类似但不同的 cmdlet 修改它们。

(Get-ChildItem -Path 'D:\Temp\SomeFile.txt').Attributes
# ReadOnly, Archive

# or this
(gci 'D:\Temp\SomeFile.txt').Attributes

# or this
(dir 'D:\Temp\SomeFile.txt').Attributes

# or this
(ls 'D:\Temp\SomeFile.txt').Attributes

以上每个都做完全相同的事情。 设置属性就是这样...

Set-ItemProperty -Path 'D:\Temp\SomeFile.txt'-Name IsReadOnly -Value $false

# or
sp 'D:\Temp\SomeFile.txt' IsReadOnly $false

(ls 'D:\Temp\SomeFile.txt').Attributes
# Archive

当然可以使用.bat调用PoSH脚本文件。但是,如果您只是坐在终端机旁,请根据需要选择一个或另一个。