Windows PowerShell設定檔的威力

Don Jones

目錄

殼層、主機及設定檔
使用您的設定檔?
建立自訂主控台
其他設定檔使用秘訣
設定檔注意!

如果您定期閱讀此專欄,現在應該已經知道 Windows PowerShell 支援設定檔系統。這些設定檔本質上是殼層指令碼 (副檔名是 .ps1),當殼層執行時它們也會自動執行。舉例來說,設定檔提供絕佳的方法來定義自訂別名。您可以讓設定檔在每次殼層執行時都自動定義您的別名,方便您每次使用殼層時使用這些別名。

殼層定義下列四種不同的設定檔:

  • 套用至所有殼層和電腦中所有使用者的設定檔。
  • 套用至所有使用者,但只套用至 Microsoft PowerShell 殼層的設定檔。
  • 套用至目前使用者和所有殼層的設定檔。
  • 套用至目前使用者,但只套用至 Microsoft PowerShell 殼層的設定檔。

「所有殼層」的概念可能有點令人困惑。這個用語是源自早期開發 Windows PowerShell 時的一些概念,但最終產品並未採用這些概念。今日,「所有主機」這樣的用語應該比較貼切。

殼層、主機及設定檔

Windows PowerShell 本身是一套 Microsoft .NET Framework 組件。我喜歡將這部分的殼層稱為 Windows PowerShell 引擎,因為其中包含了一般被認定為 Windows PowerShell 的功能。不過系統並沒有提供內建的方法讓使用者與此引擎互動。若要實際使用殼層,必須透過主控應用程式 (或主機) 載入引擎。

您習慣執行的 powershell.exe 應用程式便是這類的主機。Windows PowerShell 2.0 Community Technology Preview (CTP) 隨附的 gpowershell.exe 應用程式則是另一種主機。主機與殼層之間的關係並不像我在前文所說的那麼單純,但至少涵蓋了您觀察到的行為。

重點是,如果您透過文字型命令列介面與殼層互動,那麼您很可能是使用 powershell.exe 主機。即使您是使用其他應用程式 (Exchange 管理命令介面) 安裝的捷徑來啟動殼層也不例外。Exchange 管理命令介面並非不同的殼層或主控應用程式。其實它只是使用捷徑來啟動的標準 powershell.exe 主機,該捷徑會指定一組預先載入的嵌入式管理單元和指令碼。殼層內的 Exchange 管理功能正是由那些嵌入式管理單元啟用。因此您仍然是使用相同的殼層。

powershell.exe 主機的設定檔位置 (在 Windows Vista 中) 如下:

  • %windir%\system32\WindowsPowerShell\v1.0\profile.ps1 用於電腦的所有使用者和所有殼層。
  • %windir%\system32\WindowsPowerShell\v1.0\Microsoft.PowerShell_profile.ps1 用於電腦的所有使用者,但只用於 Microsoft.PowerShell 殼層。
  • %UserProfile%\Documents\WindowsPowerShell\profile.ps1 只用於目前使用者和所有殼層。
  • %UserProfile%\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 只用於目前使用者且只用於 Microsoft.PowerShell 殼層。

這些設定檔並非預設就建立的。只有您建立後,它們才存在。

每個主控應用程式都負責載入和執行正確的設定檔。如果某個主控應用程式「決定」什麼設定檔都不要載入,它就不用載入任何設定檔。設定檔執行作業不是由 Windows PowerShell 引擎自動執行。

要了解這些行徑,最簡單的方法是直接開啟殼層,輸入 $profile,再按 Enter 鍵。這樣會顯示殼層嘗試使用我稱之為「主要」設定檔的完整路徑 (它是針對使用者的殼層特定設定檔)。接著您可以建立或修改指令碼,而它會在每次殼層啟動時執行。

使用您的設定檔

我之前說過,設定檔的常見用途之一就是定義自訂別名。或者您也可以加入自訂 PSDrive (PSDrive 基本上是完全存在於 Windows PowerShell 內的對應磁碟機)。另一種比較少見的用法是根據環境中使用的軟體產品建立某種超級殼層,讓您進行各種所需的管理工作。為了充分解說超級殼層概念,我首先必須提供一些背景資訊。

在 Microsoft 中建立 Windows PowerShell 的產品小組負責其他許多核心管理技術,包括 Microsoft Management Console (MMC)。MMC 剛好可以當作 Windows PowerShell 運作方式的類比。執行 mmc.exe 時,一開始是使用一個沒什麼作用的空白主控台。然後加入 MMC 嵌入式管理單元來建立功能性主控台。

按照您的意思設定主控台之後,將主控台儲存成副檔名為 .msc 的檔案。這個儲存好的主控台可讓您隨時快速重新載入您的自訂主控台。

許多系統管理員都只依賴他們管理的產品所安裝的主控台,而非建立自訂 MMC 主控台。比方說,Exchange Server 會建立只包含 Exchange Server 嵌入式管理單元的主控台。Active Directory 使用者及電腦是另一個包含單一嵌入式管理單元的預建主控台。

Windows PowerShell 的運作模式也大同小異。與 Exchange Server 2007 管理工具一起安裝的 Exchange Management Shell 圖示,實際上是 powershell.exe 的捷徑,其中包含載入主控台檔案的指令。殼層主控台檔案具有 .psc1 副檔名,包含要預先載入的嵌入式管理單元清單 (很像是內含一份 MMC 為您預先載入的嵌入式管理單元清單的 .msc 檔案)。然而,您不會受到這種預先建立的殼層控制台的侷限。您可以建立自訂主控台 (就像對 MMC 一樣),然後使用它來完成所有管理工作。而設定檔在此過程中扮演著關鍵的角色。

建立自訂主控台

若要建立自訂主控台,一開始應該找出要使用的每個嵌入式管理單元的完整名稱。確認所有必要的管理工具都已經安裝在電腦上。接著在 Windows PowerShell 中,執行 Get-PSSnapin –registered。此舉會列出所有已註冊但尚未載入的可用嵌入式管理單元。然後建立或編輯適當的 Windows PowerShell 設定檔。加入 Add-PSSnapin 命令,以便載入您希望隨時提供的各個嵌入式管理單元。其中可能包括 Exchange Server、System Center 產品的嵌入式管理單元,以及 PowerShell Community Extensions 等協力廠商嵌入式管理單元。接著儲存設定檔 (如果 Windows PowerShell 執行原則要求的話,記得以數位方式簽署設定檔),然後關閉殼層。重新開啟殼層後,它會自動載入設定檔列出的所有嵌入式管理單元。

另一項技巧是將所有嵌入式管理單元載入殼層中 (使用 Add-PSSnapin 與殼層名稱),然後執行 Export-Console 來建立包含目前使用的所有嵌入式管理單元的 .psc1 主控台檔案。接著您可以使用此 .psc1 主控台檔案來建立新的 Windows PowerShell 捷徑,此捷徑會指定 PSConsoleFile 參數和您的自訂 .psc1 檔案。捷徑將使用您的主控台,自動載入所有指定的嵌入式管理單元。

其他設定檔使用秘訣

我使用我的 Windows PowerShell 設定檔在殼層啟動時執行其他一些有用的工作。以下就是殼層在我的系統上啟動時會執行的一些動作:

  1. 針對網域管理員帳戶執行 Get-Credential,並以名為 $cred 的變數排序結果。這樣可在整個殼層中使用 $cred。我接著可以將它代入各種指令程式 (例如 Get-WmiObject 指令程式) 的 –credential 參數。既然 $cred 可儲存密碼,我可以直接使用這些指令程式,這樣就不會收到密碼提示的提示。
  2. 我執行 Cd C:\,好讓殼層在電腦的 C: 磁碟機根目錄啟動。
  3. 我執行 Out-File 的 New-Alias 來建立別名「of」。如此一來,我就可以使用「of」來取代「Out-File」。我常使用它,所以定義較短的別名非常方便。

我試圖在殼層的 HKLM: 磁碟機中建立測試機碼,它代表登錄的 HKEY_LOCAL_MACHINE 部分。如果發生錯誤,我就知道殼層是在沒有提高權限的情況下啟動。我所執行的工作通常都需要提高權限,因此我可以藉由這種方式,在進行重要工作之前很快得知我是否具有提高權限。

我定義一個名為 Ping-Address 的自訂函式,可接受電腦名稱或 IP 位址,並根據電腦是否可 ping 來傳回 True 或 False 值。我在工作中常用到這個函式,因此在設定檔中定義此函式,以便在殼層中通用。

本月指令程式:Get-WmiObject

細心的讀者可能已經發現我要討論的指令程式過去曾經出現過,不過我想要向您介紹它所提供的一項小花招。我常見到系統管理員使用下面的技巧,試著從多台電腦以文字檔列出名稱的方式擷取 Windows Management Instrumentation (WMI) 資訊:

Get-Content c:\computers.txt | ForEach-Object 
  { Get-WmiObject Win32_Service –comp $_ }

雖然這項技巧可行,但您其實不需要這麼做,因為 Get-WmiObject 可以接受在 –computerName 參數使用電腦名稱陣列。您只要這麼做就能達到相同的效果:

Get-WmiObject Win32_Service –comp (Get-Content
  c:\computers.txt)

將 Get-Content 命令放入括弧內可強迫殼層執行命令,並將結果 — 電腦名稱陣列 — 放入 –computerName 參數中。

設定檔注意!

請記住,powershell.exe 並非唯一可載入 Microsoft.PowerShell 設定檔或所有殼層設定檔的應用程式。提供 Windows PowerShell 支援的許多整合式開發環境 (IDE) — 包括 SAPIEN Technologies 的 PrimalScript、Quest Software 的 PowerGUI 及 ShellTools 的 PowerShell Plus — 也會載入這些相同的設定檔,以提供與 powershell.exe 主機同等的使用經驗。

載入很多嵌入式管理單元的大型設定檔可能讓應用程式的啟動速度變慢,因為 Windows PowerShell 引擎必須執行許多指令,才能準備好讓主控應用程式使用。事實上,如果您要執行的設定檔指令碼非常大,就連 powershell.exe 都需要花點時間才會啟動。

定義相同名稱的指令程式的嵌入式管理單元也可能導致衝突。比方說,如果有兩個嵌入式管理單元都定義名為 Get-User 的指令程式,那麼 Windows PowerShell 兩個都不會執行,除非您使用指令程式的完整格式名稱來指定所要執行的指令程式。完整格式名稱可能不太好看,因為嵌入式管理單元名稱可能蠻長的。遇到這種問題時,我通常是乾脆放棄同時載入這兩個嵌入式管理單元的念頭。相反地,我只會載入在設定檔中最常使用的那個,然後在需要時使用其他「全新」殼層來載入和使用另一個嵌入式管理單元。

Windows PowerShell 設定檔可以為殼層提供大量額外的便利性。但是要記住,如果設定檔被惡意程式碼不當編輯,也可能造成巨大的損失。您可以利用數位簽署設定檔的方式,並設定 Windows PowerShell 使用其 AllSigned 執行原則,或是修改所有設定檔上的 NTFS 檔案權限,讓一般使用者帳戶無法修改 NTFS 檔案權限,藉此保護設定檔的安全性。

Don Jones 是《Windows PowerShell:TFM》和《VBScript, WMI, and ADSI Unleashed》等書的作者。您可以透過 PowerShellCommunity.org網站與他聯繫。