PowerShell
查看本機的說明文件前, 請先更新說明文件:
接著就可以用 get-help
觀看本機版的說明文件:
以上看到的是簡易版本的說明, 如果要觀看完整的說明文件, 必須加上 -Full
參數:
你也可以查看線上版本的說明文件:
說明文件中的語法表示方式:
你可以看到顯示的語法有兩組, 這表示有兩組參數集, 彼此不能隨意混用。舉例來說, 如果使用了上方參數集獨有的 -LiteralPath
參數, 就不能同時使用下方參數集才有的 -Path
參數。
每個參數都是 -參數名稱 參數值
的形式
沒有被中括號括住的參數就是強制參數, 一定要有, 例如:
這個 Path
參數就是強制參數, 不過參數名稱有用中括號括起來, 表示指定此參數時, 可以不用加上 -Path
指定參數名稱。
有用中括號括起來的參數就是可選用的參數, 例如:
就表示 Filter
參數並不一定要有, 需要時才指定。
選用參數的參數名稱若有再使用中括號括起來, 稱為位置參數, 表示指定該參數時, 並不一定要指定參數名稱, 但若是指令可接受多個位置參數時, 必須依照其在語法說明中的順序出現, 例如:
也就是說, 下指令時, 若有多個不具名參數, 就會依照順序一一對應到語法中的個別位置參數。若該指令有強制參數, 那麼第 1 個不具名參數就會對應到強制參數。
參數值具有型別, 若型別後面還跟著一對中括號, 表示該參數值可以接受單一資料或是資料清單 (陣列), 例如:
若是資料清單, 清單中的個別項目以逗號相隔, 單一資料內含空白時, 必須以 "" 括起來, 例如:
有些參數只有名稱沒有值, 稱為開關 (switch) 參數, 代表 True
或是 False
的值, 例如:
如果查看完整的說明文件, 可以看到這個參數的進一步說明:
就可以知道這個參數不指定的話預設值為 False
, 指定時代表 True
。
以下可取得特定指令的範例:
command 代表各種可以執行的事物, 包括以下幾種:
動詞-名詞
的格式, 像是 Get-Help
。PowerShell 並不區分大小寫。
參數名稱最少字母原則, 只要能區分參數名稱, 可以不用打完整的名稱, 例如以下兩者功能相同:
由於沒有其他參數的名稱是 Disp
開頭, 因此打 -Disp
就可以代表 -DisplayHint
參數。
如果指令太長, 可以用反引號 (backtick, `
符號) 接續下一行, 例如:
用小括號可以在指令內代入其他指令的執行結果:
利用英文雙引號可以在字串中用 $
符號代入變數值, 或者用 $()
代入指令執行結果:
如果要在字串中表示 $
符號, 可以加上 `
字元讓 $
跳脫置換功能變成一般文字, 或是改用英文單引號來表示字串, 就不會有置換功能了。
PowerSehll 提供有 -match
及 -replace
運算器, 可以依據規則表達式比對或是取代字串, 例如:
如果比對成功, 它會自動產生一個雜湊陣列 $Matches
, 包含比對相符的內容:
索引鍵 '0' 為相符的子字串內容, 索引鍵 '1' 開始是從最外層依序到最裡層的群組相符的子字串內容。
-nomatch
則是和 -match
相反的運算器。
你也可以處理字串替換, 例如:
注意在 PowerShell 中英文雙引號的字串會進行變數置換, 所以在使用規則表達式取代字串時, 最好用英文單引號, 避免以 $
字元標示的群組編號被當成變數。
PowerShell 使用 Provider 抽象化系統內儲存的資料, 例如檔案系統、登錄檔、甚至環境變數等等。
以下指令可以得知目前系統上有哪些 Provider:
以下指令則可以知道系統上有哪些 (含抽象的) 磁碟機:
你可以像是操作檔案系統的方式操作這些資料, 例如檢視環境變數:
也可以這樣操作登錄檔:
取得集合中物件的屬性清單:
使用 year
取得年份:
所有的指令都是針對物件在操作:
我們可以針對兩個檔案物件排序:
取得物件的屬性:
篩選物件的屬性, 只留下指定的屬性 (移除未指定屬性):
用指定的屬性替代原始的物件:
若該屬性是陣列, 就會展開陣列的內容, 例如:
這一堆 .dll 就是 Modules 屬性展開後的每一個 Module。
請參考這裡
$PROFILE 變數會記錄目前使用的 PowerSehll 設定檔路徑:
$PSVersionTable 可以取得 PowerShell 版本資訊:
腳本區塊是一種功能類似匿名函式的物件, 定義的方式就是用大括號將要執行的內容包起來, 例如:
要叫用定義好的腳本區塊, 必須使用 &
運算器:
你也可以幫腳本區塊定義引數, 例如:
叫用時可以利用位置傳遞傳數:
也可以指名方式傳遞參數:
如果要從字串中記錄的敘述建立並執行腳本區塊, 可以搭配 Invoke-Expression
, 例如若我們讀取一個腳本檔案, 並將內容記錄在變數中:
如果想使用 $s
的內容建構成腳本執行, 你可能會想這樣做:
但這樣建構出來的腳本區塊在叫用時, 是執行 $s
, 所以只會顯示字串的內容:
正確的作法是先透過字串置換, 然後再使用 Invoke-Expression
來執行叫用腳本區塊:
你也可以省略中間置換字串的變數, 直接寫成一列:
在底下的更新 PowerShell Core 到最新版中, 就有實際運用的範例, 會從網路下載的腳本檔建立腳本區塊執行。
單純用管線取得程式輸出的話, 會等到程式結束才傳回所有的輸出內容, 如果希望一行一行取得輸出結果處理, 不用等到程式結束, 可以使用 ForEach-Object
:
其中 -process
是預設參數, 所以可以省略不寫:
另外, %
與 foreach
是 ForEach-Object
的別名, 可以縮短指令行:
如果 foreach 出現在一列的開頭, 會變成 foreach
敘述, 雖然和上面談的 ForEach-Object
內建指令相似, 但它無法一行一行取得程式輸出, 只能接收完整的集合資料後才一行行處理。例如:
可以看到時間都在同一秒, 但若是改用 ForEach-Object
:
就會看到 ping
每一秒動作一次產生輸出後, 就會立刻經由 ForEach-Object
的腳本區塊處理, 所以中間的幾行訊息時間間隔都是 1 秒鐘。
兩者的差異可以參考這一篇文章。
以下蒐集一些小範例供參考使用。
若要像是 Linux 下以 sudo 指令提升成管理員權限執行指令, 可以使用 Start-Process
搭配 -verb runas
參數執行指令, 例如:
就會以管理員權限執行 netsh 指令, 過程中還是會詢問是否允許:
只要按是即可。
也可以使用 runas 指令, 例如:
PowerShell 本身沒有計時的 cmdlet, 不過可以利用 .net 的 StopWatch 物件來計時, 首先產生物件:
接著即可使用 Start()、Stop()、Reset() 方法操控計時器, 並使用 Elapsed 屬性取得目前累計的計時時間。例如:
Select-String
要篩選輸出內容, 可以使用 Select-String
搜尋文字或是規則表達式, 例如有一個這樣的文字檔:
以下的指令就可以篩選出有 "this" 的那一行:
要注意的是, Select-String
是針對文字物件搜尋, 如果是要篩選 cmdlet 輸出的物件, 必須先用 Out-string
轉成文字物件再篩選:
要特別留意 Out-String
的 -stream
參數, 如果沒有加上此參數, 就會轉換成一個包含多行文字的字串物件, 這樣搜尋到字串時, 顯示的是多行的文字。加上 -stream
選項會轉換成多個單行文字的字串物件, 就只會顯示搜尋到文字的那一行。
find.exe
在 PowerShell 中如果要使用 find 搜尋檔案中的字串, 會因為 PowerShell 把雙引號括起來的內容當成字串物件, 使得實際傳送給 find 的參數內容沒有雙引號而出錯
使用 find 會出錯:
必須用單引號把雙引號包起來, 改用 '"要搜尋的文字"' 才能將含有雙引號的文字當成參數傳給 find:
findstr.exe
如果覺得太麻煩, 也可以改用 findstr 指令, 不需要引號:
以下是找尋 time.h
檔案中名稱含有 "time" 的自訂資料型別:
有關 gcc 選項說明如下:
-E
會在前置處理完就停止。-
當檔名表示不是從檔案讀取原始碼, 而是從標準輸入讀取, 這裡因為有資料通道的轉向, 原始碼就是前面的 echo
送出的空字串。-x
是指定要編譯哪一種程式語言, 此處 -xc
表示是 C 語言。由於是從標準輸入讀取原始碼, 所以 gcc 無法依據副檔名判斷程式語言種類, 這裡一定要指定程式語言才能正常運作。-include
可以指定要匯入的表頭檔, 這裡就是將 time.h
匯入。以上的 gcc 指令實際結果就是讓前置處理器把 time.h
讀入與空的原始碼合併後輸出, 也就可以看到 time.h
檔案的內容。
後面透過資料通道串接的 Select-String
可以搜尋文字。
這個方式找不到像是 #define
定義的項目, 因為在前置處理器處理後, 這些項目都已經被取代掉了。
要在 PowerShell 內更新 PowerShell, 可以使用以下指令:
以下指令可以得知模組的安裝位置:
以下指令可以列出已載入的模組:
搜尋網路上可安裝的模組:
若要包含未正式發佈的版本:
已安裝的模組會在執行到其中的指令時自動載入, 例如若先卸載已載入的模組, 然後執行 oh-my-posh 模組的 Set-Theme 指令, 就會自動載入 oh-my-posh 模組: