Windows PowerShell是啥?看完本文你就懂它了

這篇文章主要介紹了Windows PowerShell是啥?Windows PowerShell是什麼?Windows PowerShell有哪些特性?Windows PowerShell有什麼用?看完本文你就懂它了,須要的朋友能夠參考下
 

引子正則表達式

一直很羨慕Linux的命令提示符(固然他們叫Shell)。正則表達式,管道,各類神奇的命令,組合起來就能高效完成不少複雜的任務。效率實在是高。流了n年的哈喇子之後,終於有幸用上了Win7,邂逅了cmd的升級版:Windows PowerShell。今後暗爽無比,原來Windows下也有這樣的利器呀~
看看下面的Windows腳本,不到15行有效代碼。在Win7下只要右擊腳本文件,選擇Run with PowerShell,就會自動找到最佔內存的10個進程,而後將它們佔用的內存畫成一個三維餅圖,以下圖所示。shell

 

複製代碼代碼以下:

# create new excel instance
 $objExcel = New-Object -comobject Excel.Application
 $objExcel.Visible = $True
 $objWorkbook = $objExcel.Workbooks.Add()
 $objWorksheet = $objWorkbook.Worksheets.Item(1)

 

 # write information to the excel file
$i = 0
$first10 = (ps | sort ws -Descending | select -first 10)
$first10 | foreach -Process {$i++; $objWorksheet.Cells.Item($i,1) = $_.name; $objWorksheet.Cells.Item($i,2) = $_.ws}
$otherMem = (ps | measure ws -s).Sum - ($first10 | measure ws -s).Sum
$objWorksheet.Cells.Item(11,1) = "Others"; $objWorksheet.Cells.Item(11,2) = $otherMemwindows

# draw the pie chart
$objCharts = $objWorksheet.ChartObjects()
$objChart = $objCharts.Add(0, 0, 500, 300)
$objChart.Chart.SetSourceData($objWorksheet.range("A1:B11"), 2)
$objChart.Chart.ChartType = 70
$objChart.Chart.ApplyDataLabels(5)數組

 

(1. 這個腳本調用了Excel的COM庫。 2. 固然從命令耦合的角度來看,輸出成文本格式更有利,但這個例子主要想說明PowerShell的強大以及微軟產品優異的複用性。 3. 要手動啓動PowerShell,能夠在開始菜單的搜索框中直接鍵入PowerShell回車便可)
簡單領略PowerShell的強大以後,下文就從幾個方面介紹一下PowerShell相對於以往版本的命令提示符甚至Linux Shell的優點。網絡

Cmdlet + Regex + Pipeline + ...數據結構

以往cmd相對於Shell有不少不足,好比命令偏少,部分命令功能偏弱,對正則表達式不支持等等。但如今PowerShell一下遇上來很多。2.0 RTM版內建支持414個命令(術語稱爲cmdlet),支持正則表達式,強大的管道應用(其實管道自己的功能和之前差很少,關鍵是冒出來一堆能用管道的命令,好比more, sort, foreach等等),和系統的聯繫也比之前緊密了不少。異步

舉幾個例子來講明:函數

dir registry::HKEY_CURRENT_USER能夠直接顯示註冊表相應位置的內容,能夠看到dir的功能改進了很多。工具

ps | sort ws -Descending | select -first 10能夠顯示佔用內存最大的10個進程,能夠看到管道的靈活應用。spa

dir -Name | ? {$_ -match "(?<num>.).*(\k<num>)"}能夠顯示出當前目錄下文件名有重複字符的文件。好比abcda.efg,而abcd.efg則不會顯示出來。能夠看到PowerShell對正則表達式的支持至關強大。(確切的說嚴格的正則表達式 已經沒法實現這樣的效果,須要上下文無關文法 纔可以支持。)
之前爲了演示Linux Shell的強大,Stephenjy發了一個本身的截圖,在碰見PowerShell前以爲好神奇,所幸如今也能夠實現了。:-)

(爲了節約顯示空間,PowerShell的部分顯示結果被刪除,但這個Prompt效果能夠用如下腳本驗證: function prompt {"($env:username)-($env:computername)-(`$?: $?)-(jobs: $((get-job | measure).Count))-($(get-location))`n(! $(((history)[-1]).ID + 1))->"})

大殺器 - 面向對象

Linux的設計思想決定全部的輸入和輸出都儘量是文本格式,這樣能夠方便各進程間的合做。一樣這也要求各個程序提供必定強度的文本解析能力。但Windows的思想與此不一樣,PowerShell中不少輸入輸出都不是普通的文本(plain text),而是一個個對象(objects)。所以與其說PowerShell是一種交互環境,不如說它是一種強大語言的Runtime,而這種語言甚至是面向對象的。

好比當鍵入get-process查看當前進程列表時,系統返回的是這樣的列表:

複製代碼代碼以下:

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    318       8    12948       3872    84            1728 AppleMobileD
    115       5    13816      13328    38            6920 audiodg
   1315      21    11732      10988   108            2544 CcmExec
... ...

 

雖然看似通常的格式化文本,但其實這是一個數組,而每一個數組元素又是Process類型的對象。同.NET一脈相承,PowerShell中的全部的類都繼承自Object,且支持GetType()函數。所以咱們能夠執行(get-process).GetType()來看看它的類型:

複製代碼代碼以下:

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

而數組中每一個元素的類型能夠用(get-process)[0].GetType()查看:
複製代碼代碼以下:

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    Process                                  System.ComponentM...

其中面向思想的思想很是明顯,類成員,方法,繼承都出現了。我的感受這樣的好處並非期望能用PowerShell寫什麼大型軟件,而是體如今另外兩個方面:首先,這樣讓內置的cmdlet及其數據結構組織清晰,符合直覺,寫代碼時速度快不容易出錯。第二,對面向對象的內建支持也爲後面無縫接合.NET和COM接口提供了基礎。

 

站在巨人的肩膀上 - 無縫調用.NET/COM

.NET Framework中包含了一個異常強大的庫,而微軟爲了保證二進制層面上跨語言的兼容性,不少庫都是用COM封裝的。PowerShell的一大特點就是能夠直接調用這些庫。好比前面的示例用$objExcel = New-Object -comobject Excel.Application建立了一個Excel對象。而wikipedia上的一個腳本更示範了這種無縫調用的強大。下面這個3句話的腳本的做用是顯示一個RSS源最近的8篇文章的標題。注意其中網絡鏈接,內容下載,XML解析等工做所有由.NET庫完成,正由於站在巨人的肩膀上,PowerShell在實際使用中每每左右逢源,簡潔高效。

複製代碼代碼以下:

$rssUrl = "http://blogs.msdn.com/powershell/rss.aspx"
$blog = [xml](new-object System.Net.WebClient).DownloadString($rssUrl)
$blog.rss.channel.item | select title -first 8 

 

編輯,運行,調試 - IDE

Windows程序開發,尤爲是基於微軟技術的開發很爽的一點就是有強大的IDE和專業的文檔做支持。不管是Windows下的Visual Studio仍是Linux下的Mono Develop,甚至連PowerShell這樣的語言都有集編輯與調試爲一體的IDE:Windows PowerShell ISE。有了自動完成,即時腳本交互,調試甚至遠程調試,PowerShell腳本寫起來「甚爽甚強巨」。固然文檔也是通常的強大,MSDN中關於PowerShell的部分依舊專業浩瀚。

蛋疼的假裝 - Profile

有了PowerShell之後,不多就去cmd了。不過做爲一個蛋疼的裝B男,把PowerShell假裝成cmd也是挺有樂趣的一件事。不難發現PowerShell和cmd僅僅在圖標,標題,背景色,提示符,以及剛啓動時的顯示文字五個方面不一樣。圖標和背景色在快捷方式屬性中能夠很方便的修改。而標題和提示符的修改就要用到Profile了。所謂Profile就是在每次啓動PowerShell時都首先自動運行的一段腳本。這個腳本的路徑在$profile變量中有設定。只要設定$host.UI.RawUI.WindowTitle爲C:\windows\system32\cmd.exe就能將標題假裝爲cmd。而自定義提示符爲當前路徑在PowerShell中天然萬分簡單。至於啓動時的顯示文字,只要經過/nologo參數隱藏原有的版本信息,再打印一行cmd中的文字就行了。最終效果如圖:(關於Profile,能夠參見這個連接

另:進程級工做調度 – 並行支持?

==========================================================
隨着多核處理器的迅速發展,從.NET Framework 4.0開始,並行計算被一再強調。從System.Threading中新增長的並行工具類到F#這種很是適合並行化的函數式語言,微軟適時對線程級並行提供了強大的支持。可是對於進程級的工做調度,Windows彷佛還至關原始。舉個最簡單的例子來講,若是咱們同時向一個移動硬盤啓動5個拷貝會話的話,Windows會同時開始全部的拷貝操做。這樣磁頭會在不一樣的目標位置間反覆進行無心義的移動(尋道),因而在硬盤燈的狂閃中,大量時間就被浪費了。一樣當咱們同時啓動數個計算量大的進程時,Windows也會試圖讓這些進程「齊頭並進」。然而爲了不某個進程被餓死,系統又不得不頻繁切換進程,因而大量的時間又被浪費在了保存現場,進程切換,恢復現場上。這樣來看,進程級的並行作的反而不夠好。

所幸PowerShell中加入了任務調度管理功能。經過簡單的實驗,咱們能夠發現PowerShell對jobs的調度和Windows默認的大不相同,它通常維持和CPU核心數相同的進程高速運轉,而其它進程僅僅佔用小部分CPU時間。直到前面的進程結束工做後,後面纔有新的進程遞補進入高速運轉的狀態。==========================================================後來更仔細地作了實驗之後發現,原來Windows內置的進程調度方案就是小部分高速運轉(在個人雙核處理器上是兩個進程佔用50%CPU),大部分低速跟進(其餘全部進程分享剩下的50%CPU)。這樣PowerShell的工做調度並無改善系統原有的現狀。同時因爲PowerShell的調度系統須要佔用不小的內存,初始化也須要時間。在實測中甚至比默認調度慢了50%。這個實驗結果比較囧。不曉得爲何PowerShell中爲何要加入Job這個東西,難道僅僅爲了異步調用嗎?

相關文章
相關標籤/搜索