引言
我從老舊的 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 的新語法“
主站蜘蛛池模板:
突泉县|
西宁市|
阿拉尔市|
香港
|
康乐县|
和政县|
沙田区|
和田县|
潼关县|
梧州市|
花莲县|
福清市|
南乐县|
广东省|
阿拉善左旗|
彩票|
永顺县|
邵阳市|
霍邱县|
湘乡市|
岢岚县|
于都县|
波密县|
会昌县|
台安县|
龙南县|
化隆|
荔浦县|
竹山县|
茂名市|
抚州市|
象山县|
北川|
永州市|
沾益县|
萝北县|
同德县|
大姚县|
吴桥县|
阿拉善右旗|
南陵县|