首页 > 图灵资讯 > 技术篇>正文

用新PowerShell 运行旧的CMD命令

2023-05-12 10:18:35

  引言

  我从老旧的 CMD.EXE 命令行换成优秀的 POWSERSHELL.EXE 已经有一段时间了。你可能知道新的 Windows PowerShell 任何旧命令都可以操作。然而,一些旧命令的名称或语法可能会出现问题。但这不是问题。一、 麻烦1:名称冲突

  PowerShell 别名和旧命令名之间的冲突是一个常见的问题。例如,您最喜欢的服务控制命令 SC.EXE。假如你想查一下 SMB Server 服务状态,可以在 CMD.EXE 里这样用: C:\>SC QUERY LANMANSERVERSERVICE_NAME: LANMANSERVERTYPE : 20 WIN32_SHARE_PROCESSSTATE : 4 RUNNING(STOPPABLE, PAUSABLE, IGNORES_SHUTDOWN)WIN32_EXIT_CODE : 0 (0x0)SERVICE_EXIT_CODE : 0 (0x0)CHECKPOINT : 0x0WAIT__HINT : 0x0

  如果您在 PowerShell 尝试同样的事情,你会得到: PS C:\> SC QUERY LANMANSERVERSet-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 文件。方案1 使用 .EXE 扩展名

  为了克服这个问题,你可以简单地解决它 .EXE 扩展名包含旧命令。这消除了歧义,使同样的命令处于 CMD.EXE 和 PowerShell 它可以在里面使用。你也可以清楚地告诉使用你脚本的人,这里使用的是旧的 .EXE 命令而非 PowerShell 别名。 PS C:\> SC.EXE QUERY LANMANSERVERSERVICE_NAME: LANMANSERVERTYPE : 20 WIN32_SHARE_PROCESSSTATE : 4 RUNNING(STOPPABLE, PAUSABLE, IGNORES_SHUTDOWN)WIN32_EXIT_CODE : 0 (0x0)SERVICE_EXIT_CODE : 0 (0x0)CHECKPOINT : 0x0WAIT__HINT : 0x0 方案2 使用 CMD /C

  另一种方法是用引号包括起让你的命令 CMD.EXE 操作。但是这样做没有效率,只是为了执行你的命令,你必须运行一个 CMD.EXE 实例。 PS C:\> CMD /C "SC QUERY LANMANSERVER"SERVICE_NAME: LANMANSERVERTYPE : 20 WIN32_SHARE_PROCESSSTATE : 4 RUNNING(STOPPABLE, PAUSABLE, IGNORES_SHUTDOWN)WIN32_EXIT_CODE : 0 (0x0)SERVICE_EXIT_CODE : 0 (0x0)CHECKPOINT : 0x0WAIT__HINT : 0x0

  请注意,如果您的命令包含双引号,则需要使用反引号`来转换,例如: CMD.EXE /C "C:\install\program.exe --silent=yes --cover-conf=yes --cover-app=yes --install-path=C:\Program Files\ --url=`"https://xxx.com:8080/agent/xxxx`"" 方案3 用等效的 Powershel命令

  在许多情况下,可以使用 PowerShell cmdlet 用旧命令代替你。

  例如,您可以直接在这里使用它 Get-Service: PS C:\> Get-Service LANMANSERVER | FLName : LANMANSERVERDisplayName : ServerStatus : RunningDependentServices : {Browser}ServicesDependedOn : {SamSS, Srv}CanPauseAndContinue : TrueCanShutdown : FalseCanStop : TrueServiceType : Win32ShareProcessss 二、麻烦 2:PowerShell 的特殊字符

  有时旧命令参数中使用的字符是 PowerShell 有特殊意义。

  例如,您希望所有用户都能完全控制目录。在 CMD.EXE 你可以这样做: C:\>ICACLS.EXE C:\TEST /GRANT USERS:(F)processed file: C:\TESTSuccessfully processed 1 files; Failed processing 0 files

  但如果你在 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 spellingof 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 thename.+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException+ FullyQualifiedErrorId : InvalidVariableReference

  这是因为括号和美元符在这个问题上 PowerShell 都有特殊意义。例如,大括号等常用字符也会引起类似的冲突。解决这个问题有几种不同的解决方案。方案1 使用 CMD /C

  就像第一个问题一样,你可以引号包括你的命令 CMD.EXE 来处理。不考虑效率,PowerShell 引号中的字符串不会分析,这样才能正常工作。

  PS C:\> CMD.EXE /C "ICACLS.EXE C:\TEST /GRANT USERS:(F)"processed file: C:\TESTSuccessfully processed 1 files; Failed processing 0 files 方案 2 使用 PowerShell 的转义字符

  对于这个方案,你必须首先知道使用哪些字符? PowerShell 具有特殊意义。然后在每个人面前添加转义字符反引号`。这个计划的主要问题是,你必须知道哪些字符需要转义,这使得读写你的脚本更加困难。

  在我们的例子中,你需要处理 ( 和 ) 这两个字符:

  PS C:\> ICACLS.EXE C:\TEST /GRANT USERS:`(F`)processed file: C:\TESTSuccessfully processed 1 files; Failed processing 0 files 方案3 使用 PowerShell v3 的新语法 --%

  在 PowerShell v3 还有另一种解决这个问题的选择。您只需在命令行的任何位置添加它 --% 序列(两条短线和一个百分号)PowerShell 剩下的部分不会分析。本地执行命令的测试是可用的,但使用它 Invoke-远程操作时不能使用Command,此时可使用方案一。

  在我们的例子中,您可以这样使用:

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

  也可以这样用:

  PS C:\> ICACLS.EXE C:\TEST --% /GRANT USERS:(F)processed file: C:\TESTSuccessfully processed 1 files; Failed processing 0 files 方案4 使用等效的 PowerShell

  使用等效的 PowerShell 也是一种选择。ICACLS.EXE 可以用 Set-ACL 替换。从这个博客中可以找到更多 Set-ACL 例子。三、 混搭

  在这里展示如何让您安全享受 PowerShell 结合你旧命令带来的灵活性。你可能会学到一些技能,并以新的方式开始新旧的结合。

上一篇 代码看不懂?ChatGPT 帮你解释,详细到爆!
下一篇 记录一些 PostgreSQL问题分析思路

文章素材均来源于网络,如有侵权,请联系管理员删除。