PowerShell中运行CMD命令的技巧总结(解决名称冲突和特殊字符等问

2019-09-30 18:40:09于丽

有时旧命令的参数使用的字符在 PowerShell 里有特殊意义。
比如您想让某个目录被所有用户完全控制。在 CMD.EXE 里您可以这样做:

C:>ICACLS.EXE C:TEST /GRANT USERS:(F)
processed file: C:TEST
Successfully processed 1 files; Failed processing 0 files
在 CMD.EXE 做这些没问题,但如果你在 PowerShell 运行就会报错:

PS C:> ICACLS.EXE C:TEST /GRANT USERS:(F)
The term 'F' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling
of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:34
+ ICACLS.EXE C:TEST /GRANT USERS:(F)
+ ~
+ CategoryInfo : ObjectNotFound: (F:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundExceptionn
试图给名字以 $ 结尾的电脑对象授权时也会引起一个类似的错误。

PS C:> ICACLS.EXE C:TEST /GRANT COMPUTERNAME$:(F)
At line:1 char:39
+ ICACLS.EXE C:TEST /GRANT COMPUTERNAME$:(F)
+ ~~
Invalid variable reference. '$' was not followed by a valid variable name character. Consider using ${} to delimit the
name.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : InvalidVariableReference

这个问题是因为括号和美元符在 PowerShell 中都有特殊意义。例如大括号之类常用字符也会引发相似的冲突。也有几种不同的方案来解决这个问题。

方案 2A:使用 CMD /C

和第一个问题一样,你可以引号括起您的命令交给 CMD.EXE 来处理。先不考虑效率,PowerShell 不会去解析引号里的字符串,这样就能正常工作。

PS C:> CMD.EXE /C "ICACLS.EXE C:TEST /GRANT USERS:(F)"
processed file: C:TEST
Successfully processed 1 files; Failed processing 0 files

方案 2B:使用 PowerShell 的转义字符

对于这个方案,您必须先知道使用的字符哪些对 PowerShell 有特殊意义。然后在它们每一个前面加上个反引号(`),它就是 PowerShell 的转义字符。这个方案的主要问题是你必须知道哪些字符需要转义,这让读写您的脚本更困难。
我们的例子里,你需要处理 ( 和 ) 这两个字符:

PS C:> ICACLS.EXE C:TEST /GRANT USERS:`(F`)
processed file: C:TEST
Successfully processed 1 files; Failed processing 0 files


方案 2C:使用 PowerShell v3 的新语法“–%”

在 PowerShell v3 中有另一种选择来解决这个问题。您只需在命令行的任意位置添加 –% 序列(两个短划线和一个百分号)PowerShell 就不会再去解析剩下的部分。
我们的例子里,您可以这样用:

PS C:> ICACLS.EXE --% C:TEST /GRANT USERS:(F)
processed file: C:TEST
Successfully processed 1 files; Failed processing 0 files
也可以这样用: