问题
I am getting this error when trying exec one command in PowerShell
:
I am trying to exec
this command:
powershell.exe Start-Process -FilePath "C:\Windows\System32\attrib +h +s "%CD%"" -Verb runAs
Can someone please help me figuring out why this is happening and how to solve it?
回答1:
Can someone please help me figure out why this is happening?
The -FilePath
parameter of the Start-Process
cmdlet expects the name or path of an executable file by itself, not an entire command line.
The arguments to pass to the executable specified via -FilePath
must be passed separately, as an array, via the -ArgumentList
(-Args
) parameter.
When calling from cmd.exe
(a batch file), it's conceptually cleaner to pass the entire command line to be evaluated by PowerShell in a single, "
-enclosed argument:
powershell.exe -Command "Start-Process -Verb RunAs -FilePath attrib.exe -Args +h, +s, '\"%CD%\"'"
Note the need to escape the %CD%
value doubly, by enclosing it in '
for the sake of PowerShell first, then in \"
inside that: The outer '
ensures that PowerShell itself recognizes the value as a single argument, and the embedded \"
quoting ensures that the ultimate target program, attrib.exe
, sees the value as a single argument too.
This need for double escaping is unfortunate and shouldn't be necessary - it is discussed in this GitHub issue.
回答2:
The is no need to fully qualify the path to attrib.exe, it's natively available via the DOS and PoSH environment variables.
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
Any strings with spaces must be enclosed in quotes, as well as arguments or they must be passed separately.
Start-Process powershell -ArgumentList "-NoExit","-Command &{ $ConsoleCommand }" -Wait
All you are doing, in your use case and what I show, is calling PoSH to run a DOS command that you can just do in DOS. So, why use PoSH at all for this, other than the runas thing?
Also, as you do command they way you are trying, proper quoting to properly qualify that command to run can be confusing. Which is the real issue with that line. Passing arguments have to be done properly, spaces if not properly handled will cause issues, hence your error.
Also, why start at cmd.exe for this effort, just to end up shelling out to the PoSH console host to run this command?
Just do this natively in PoSH console host, which by nature is what you are doing. Save yourself the extra steps and complications.
Just launch powershellexe, instead of cmd.exe and run your DOS commands.
attrib +r 'd:\temp\SomeFile.txt'
There is little cmd.exe can do that PoSH console cannot and there are tons of things PoSH (console host and ISE) can do that cmd.exe cannot. So, why not just start and stay in PoSH natively?
You can run all you DOS commands in PoSH console host (in the ISE, there is a little bit more effort to get them to work) natively, or just use the PoSH equivalent.
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'
That one is a bit long in the tooth, I know. However, you can just do following as well, to get the attributes, and modifying them using similar but a different 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
Each of the above do exactly the same thing. Setting attributes is just this...
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
Sure you can use .bat to call a PoSH script file. But if you are just sitting at a terminal, pick one or the other based on what is needed.
来源:https://stackoverflow.com/questions/50900785/how-i-do-invoke-a-powershell-start-process-command-with-arguments-that-require-q