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

 更新时间:2014年05月07日 11:42:54   作者:  
这篇文章主要介绍了PowerShell中运行CMD命令的技巧总结(解决名称冲突和特殊字符等问题),需要的朋友可以参考下

引言

我从老旧的 CMD.EXE 命令行换到优秀的 POWSERSHELL.EXE 已经有一段时间啦。您可能知道新的 Windows PowerShell 可以运行任何旧命令。不过有些旧命令的名称或语法可能会产生问题。但这都不是事儿。

麻烦 1:名称冲突

PowerShell 的 cmdlet 别名和旧命令的名称有冲突是个常见的问题。比如说您喜欢的服务控制命令 SC.EXE。SC.EXE 非常灵活!我能理解您为什么喜欢它(不要为用 NET.EXE 管理服务找借口)。如果您想查看 SMB Server 服务的状态,可以在 CMD.EXE 里这样用:

复制代码 代码如下:

C:\>SC QUERY LANMANSERVER

SERVICE_NAME: LANMANSERVER
TYPE : 20 WIN32_SHARE_PROCESS
STATE : 4 RUNNING
(STOPPABLE, PAUSABLE, IGNORES_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0


如果您在 PowerShell 中尝试同样的事,会得到:
复制代码 代码如下:

PS C:\> SC QUERY LANMANSERVER
Set-Content : Access to the path 'C:\QUERY' is denied.
At line:1 char:1
+ SC QUERY LANMANSERVER
+ ~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (C:\QUERY:String) [Set-Content], UnauthorizedAccessException
+ FullyQualifiedErrorId : GetContentWriterUnauthorizedAccessError,Microsoft.PowerShell.Commands.SetContentCommand

因为 SC 是 Set-Content 的别名。它优先于 SC.EXE 文件。

方案 1A:使用 .EXE 扩展名

为了克服这个问题,您可以简单地将 .EXE 扩展名包含进旧命令。这消除了歧义并使相同的命令在 CMD.EXE 和 PowerShell 里都能用。还可以清楚告诉使用您脚本的人这里用的是旧 .EXE 命令而非 PowerShell 别名。

复制代码 代码如下:
PS C:\> SC.EXE QUERY LANMANSERVER

SERVICE_NAME: LANMANSERVER
TYPE : 20 WIN32_SHARE_PROCESS
STATE : 4 RUNNING
(STOPPABLE, PAUSABLE, IGNORES_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0

方案 1B:使用 CMD /C

另一个办法是把您的命令用引号括起让 CMD.EXE 来运行。但这样做没啥效率,仅仅为了执行您的命令就得运行一个 CMD.EXE 实例。

复制代码 代码如下:
PS C:\> CMD /C "SC QUERY LANMANSERVER"

SERVICE_NAME: LANMANSERVER
TYPE : 20 WIN32_SHARE_PROCESS
STATE : 4 RUNNING
(STOPPABLE, PAUSABLE, IGNORES_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0

方案 1C:用等效的 PowerShell

很多情况下,可以用 PowerShell cmdlet 来代替您的旧命令。
例如这里您就可以直接使用 Get-Service:

复制代码 代码如下:

PS C:\> Get-Service LANMANSERVER | FL

Name : LANMANSERVER
DisplayName : Server
Status : Running
DependentServices : {Browser}
ServicesDependedOn : {SamSS, Srv}
CanPauseAndContinue : True
CanShutdown : False
CanStop : True
ServiceType : Win32ShareProcess


麻烦 2:PowerShell 的特殊字符

有时旧命令的参数使用的字符在 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

也可以这样用:
复制代码 代码如下:

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

方案 2D:使用等效的 PowerShell

使用等效的 PowerShell 也是种选择。ICACLS.EXE 可以用 Set-ACL 代替。可以从这篇博客中找到更多的 Set-ACL 例子。

混搭

这里展示如何让您安全地享受 PowerShell 结合您的旧命令带来的灵活性。您可能会学到几个技巧并以全新的方式开始新老结合。

例如您能用灵活的 Get-Service 通配符代替 SC.EXE 里晦涩选项:

复制代码 代码如下:
Get-Service LAN* | % { $_.Name; SC.EXE SDSHOW $_.Name }

或者您可以使用 PowerShell 的 Get-Item(别名 Dir)过滤文件子集传递给 ICACLS.EXE 来处理:
复制代码 代码如下:
DIR C:\TEST -Recurse | ? {$_.Length -ge 1MB} | % { ICACLS.EXE $_.FullName /Grant Administrator:`(F`) }

您甚至可以循环遍历几个数并结合好用的 FSUTIL.EXE 来创建一批大小不同的文件用于测试项目:
复制代码 代码如下:
1..100 | % { FSUTIL.EXE FILE CREATENEW C:\TEST\FILE$_.TXT ($_*10KB)


尾声

事到如今,您可能已经确信 Windows PowerShell 是管理员的好朋友啦。然而您可能因为有些旧命令带着古怪的名字或参数而不能使用 POWERSHELL.EXE。我非常鼓励您使用这些技巧来彻底停用 CMD.EXE 并永久迁移到 PowerShell 来作为您主要的 shell。

文章出处:http://www.pstips.net/using-windows-powershell-to-run-old-command-line-tools-and-their-weirdest-parameters.html

相关文章

  • Powershell中调用邮件客户端发送邮件的例子

    Powershell中调用邮件客户端发送邮件的例子

    这篇文章主要介绍了Powershell中调用邮件客户端发送邮件的例子,需要的朋友可以参考下
    2014-05-05
  • PowerShell使用match操作符来筛选数组

    PowerShell使用match操作符来筛选数组

    本文介绍PowerShell中使用match操作符,配合正则表达式从数组中筛选出想要的内容,需要的朋友可以参考下
    2016-11-11
  • powershell玩转sqlite数据库详细介绍

    powershell玩转sqlite数据库详细介绍

    这篇文章主要为大家分享一下powershell玩转sqlite数据库的一些资料,内容非常详细,需要的朋友可以参考下
    2017-10-10
  • 原创powershell脚本小工具ctracert.ps1跟踪路由(win8以上系统)

    原创powershell脚本小工具ctracert.ps1跟踪路由(win8以上系统)

    这篇文章主要介绍了原创powershell脚本小工具ctracert.ps1跟踪路由(win8以上系统),需要的朋友可以参考下
    2017-10-10
  • Windows Powershell 进行数学运算

    Windows Powershell 进行数学运算

    在Windows PowerShell中, 使用数学运算符来进行数学运算,数学运算符允许你在命令参数中计算数值. 你可以使用一个或者多个运算符进行加减乘除法, 也可以返回除法的余数(模). 包含这些计算的参数, 将计算结果作为参数值. 命令就像处理其他类型参数一样, 来处理参数值.
    2014-08-08
  • powershell常用命令分类

    powershell常用命令分类

    本文创建了powershell常用命令 ,主要分为get类、set类、write类三大类,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2014-10-10
  • PowerShell脚本性能优化技巧总结

    PowerShell脚本性能优化技巧总结

    这篇文章主要介绍了PowerShell脚本性能优化技巧总结,一些PowerShell脚本可能很容易消耗很多内存,或者运行太多时间,甚至兼而有之,本文会分享几个PowerShell小技巧来提高这一类脚本的性能,需要的朋友可以参考下
    2014-05-05
  • PowerShell脚本开发之尝试登录ftp

    PowerShell脚本开发之尝试登录ftp

    本文和后续的文章将会试图通过PowerShell实现对上述潜在攻击点的弱密码尝试,本文首先针对ftp的密码尝试。记录下全过程,有需要的朋友可以参考下。
    2014-10-10
  • Powershell的break、continue和return简单总结

    Powershell的break、continue和return简单总结

    这篇文章主要介绍了Powershell的break、continue和return简单总结,和其它语言中的作用相同,所以本文的总结比较短小,需要的朋友可以参考下
    2014-07-07
  • Powershell中阻止”确认提示”的方法

    Powershell中阻止”确认提示”的方法

    这篇文章主要介绍了Powershell中阻止”确认提示”的方法,本文直接给出操作代码示例,需要的朋友可以参考下
    2015-03-03

最新评论