Windows PowerShell 不是要指令碼

Don Jones

內容

不過度使用變數
有意義的變數名稱
簡化比較
不要中斷您的指令碼
循環迴圈
不要將因此無訊息
顯示我的指令碼

我最近 (其仍然代表) 提供對所作的讀者我 ConcentratedTech.com部落格: 傳送我的 Windows PowerShell 指令碼] 及 [我將加以檢閱,並提供任何已來協助改善它們的建議。 概念實際上來自問卷的部落格我 co 位作者,我已經執行,讀取器的建議這會提供很好,真實世界的方式,來改善其指令碼的技術人員。 在過去幾個月我注意到一些趨勢,我發現自己重複進行幾個特定的建議。 因此我已編譯,這裡與您共用的清單。

讓我第一個狀態,但是,任何指令碼,取得完成 (成功和不的課程這類的附帶損害) 工作是很好的指令碼。 一些事情我並說建立似乎 nitpicky,部份當然。 但是,我建議的每個沒有我會試著指出,我的一些不同優點。

如果您實際進行一些我指出"錯誤作法 」 不會而視同違法行為。 我知道很多人的 Windows PowerShell 該指令碼開始使用 VBScript 指令碼,有些這些"不正確的作法 」 是 VBScript 世界中確實很常見。 這是一個很好的機會然後,了解如何 Windows PowerShell 和 VBScript,有點不同,以及如何撰寫指令碼,請使用唯一的優點,Windows PowerShell 所提供。

這稱為,以下是已經在過去幾個月我前六個常見建議。

不過度使用變數

確定,變數非常有用的但我們無法取得執行了。 我已經被看到很多這類指令碼:

$varfile = "c:\names.txt"
$varexists = Test-Path $varfile
if ($varexists –eq $false) {
  Write-Output "The file $varfile does not exist"
  break
}
$varnames = Get-Content $varfile

有一些我想要查看變更,就像這樣的範例中的作法。 首先,foremost,還有一點不必停到變數中的所有資訊。 很可能會重新寫入這較少的變數。 何必嗎? 也,殼層可能不會注意您使用,多少變數,但是我大,大風扇的指令碼為可讀取,以便其他人能夠讀取您在紙張或指令碼編輯器中的指令碼,和能夠找出指令碼正在執行的動作。 您所包含多個變數,多人必須在追蹤他的標頭中的而且就越不可能他將能夠找出指令碼是什麼最多。 如果我不知道在紙張上的指令碼,我比較不可能能夠偵錯指令碼,如果有問題。 因此我應該先重寫這個範例,如下所示:

$varfile = "c:\names.txt"
If ((Test-Path $varfile) –eq $false) {
Write-Output "The file $varfile does not   exist"
  break
}
$varnames = Get-Content $varfile

我真的是做消除 $ varexists 變數並直接使用的測試路徑輸出。 這的種方式不需要看一下 If 建構,請參閱 $ varexists,並返回上一步然後找出哪些 $ varexists 要包含。 它是小於我追蹤的我的頭中。 請注意我左 $ varfile ; 這是因為使用該資訊三次,如果您正在重新資訊使用多次,然後值得放到變數。

有意義的變數名稱

在繼續前一個範例,永遠記得變數名稱應該協助您記住變數內的。 您不需要使用像是"var"名稱前置詞,因為 $ 字元告訴您它是一個變數。 在就其實名稱像"str"的字串或"int"的整數是過時的前置詞 ("這是 1993"我說我在教學時的類別)。 只要使用簡單的變數名稱。 以下是範例重寫:

$filename = "c:\names.txt"
If ((Test-Path $filename) –eq $false) {
Write-Output "The file $filename does not exist"
  break
}
$computernames = Get-Content $filename

簡化比較

我不風扇的比較運算子,Windows PowerShell 中 — 是要 –gt、-lt,-eq,等等。 我缺乏 fondness 可能來自於我長的經驗與 VBScript,位置可以使用熟悉的運算子如 >,<,及 =。 許多您可能會辨識成績學校的數學課程從這些運算子,它們需要較少心理剖析當您讀取它們的因此。 不論何時儘量,然後,我喜歡避免使用的運算子。 和您檢查為某件事的其中任一條件為 True 或 False 是擺脫運算子的機會:

$filename = "c:\names.txt"
If (-not (Test-Path $filename)) {
Write-Output "The file $filename does not exist"
  break
}
$computernames = Get-Content $filename

由於測試路徑 Cmdlet 會傳回 True 或 False,就不需要比較它設為 True 或 False。 在 [如果內所有項目建構括號必須向下 boil True 或 False。 通常,您可以使用比較來達成的但是如果任何在那裡是已經產生 True 或 False,您可以只使用該資訊直接。

我應該請注意 –not 運算子是我實際上喜歡。 它是比對等用法更像一般的英文! = 許多語言所使用的運算子。

而且,我應該註解上我在測試路徑和其輸入的參數 $ 檔名放在括號。 我已經啟動封入括號的命令,因為它可協助我以視覺化方式瞭解它們當作單一單位。 Windows PowerShell 會使用空格,而非其他某些字元來分隔之類的命令、 參數的名稱和參數值。 在括號中封入整個命令字串,幫助我看所有就一起不強迫我實際上看看空格,並決定命令的開始與停止處。

不要中斷您的指令碼

已執行這個範例中的最後一個建議是它的邏輯內建的方法。 如果檔案不存在,我破壞指令碼。 如果存在檔案,我絕對不會執行中斷陳述式,並因此指令碼會繼續。 盡可能時,我要避免使用符號若要結束指令碼。 我想重寫範例 — 一次),如下所示:

$filename = "c:\names.txt"
If (Test-Path $filename) {
$computernames = Get-Content $filename
  # do whatever we planned to do
} else {
Write-Output "The file $filename does not exist"
}

這樣的一來我已經簡化在 [如果邏輯建構。 我也已經被消滅需要使用中斷陳述式可減少混淆有關指令碼正在執行的動作。 我承認這個建議絕對是一個的 nitpick,但我認為良好的程式碼撰寫方式有助於讓更好的指令碼,這是絕對比 bailing 出一半透過指令碼的不錯的練習的第一個。 這種建構是容易偵錯,而且很容易如果您正在查看指令碼,並嘗試找出它的功用,請遵循在紙張上。

循環迴圈

有幾個我檢閱附加的指令碼需要讀取文字檔案與檔案的每一行迴圈中的資訊。 就例如您可能要連絡一系列的電腦,讓您可以列出它們的名稱文字檔案中的一行每一個名稱。 以下是常見建構,我還看過:

$line = 0
$names = get-content c:\names.txt
while ($line –lt $names.length) {
  # do something with $names[$line]
  $line++
}

這將檔案載入至變數的 $ 名稱,然後以手動方式列舉集合,就好像陣列。 $ 列變數會追蹤的我正在使用的線路。 它運作正常,但我在執行更多的工作,我需要而且我對程式碼有點困難稍後讀取其他人。 在 Windows PowerShell ForEach 建構也是更適用列舉集合。 (技術上,取得內容傳回集合,非陣列)。 而是嘗試:

Foreach ($name in (Get-Content c:\names.txt))
{
  # do something with $name
}

有幾個優點。 我先前的建議以一致我時發生將右內的建構呼叫取得內容,因為我認為它會以進行些什麼的位元更清楚。 ForEach 將列舉的時間長度的在整個集合。 透過,每次它將取得 [集合中的 [下一個項目,並將該項目放在 $ 名稱變數中。 因此變數的名稱,表示它的內容 (電腦名稱。 並且,讓指令碼更容易閱讀,請依照下列。

Windows PowerShell Q & A

Q 有一個方法,Windows PowerShell 中定義一個永久的自訂別名嗎?

A 您會建立新的別名,如果您已經可能注意到它會立即關閉殼層時。 就例如這會建立新的別名 d,即取得很命令的捷徑:

新別名 d 取得很

但時關閉殼層是遺失的別名。 訣竅是建立 Windows PowerShell 設定檔。 您的文件] 資料夾中建立 [一個稱為 WindowsPowerShell 的新資料夾]。 在該的資料夾建立名為 profile.ps1 的文字檔。 在文字檔案,將置於您想要每次殼層啟動自動執行的任何指令,包括新的別名定義。 設定檔可確保在指令執行每次您啟動殼層,建立永久"的別名,Windows PowerShell 中隨時。

不需要擔心有關哪些列我正在使用或保留 $ 列變數,以追蹤的 — ForEach 建構會幫我。 消除三行程式碼會使程式碼更簡潔,而且需要要追蹤的較少的項目在您嘗試找出指令碼做了什麼時。

不要將因此無訊息

我真的想要 nip 中 bud 一個練習是殼層錯誤的整個指令碼中的作法。 假設您正在查看指令碼,其中包含此列權限,在最上方:

$ErrorActionPreference = "SilentlyContinue"

立即停止。

這並不會讓消失的錯誤,但它不會隱藏它們。 是,但當然有時也會時,您便會預期,並且要忽略了某些錯誤,例如,當您使用 Windows 管理檢測 (WMI 中) 來連線到遠端電腦可能無法使用的。 但不是還有一個全域忽略錯誤的原因。 錯誤訊息是很有用,和點出問題您可以有時修正。

如果想忽略錯誤的特定指令程式您可以這麼 –EA"SilentlyContinue"參數加入該指令程式。 如果您想要忽略錯誤的資料列中的數個命令,其中 –EA 參數加入每個或加入 $ ErrorActionPreference 行立即之前這些命令和這些命令之後,新增:

$ErrorActionPreference = "Continue"

這會設定錯誤處理返回到一般狀態。

個人,我不喜歡關閉錯誤,除非我要自己處理這些錯誤。 例如:

Trap {
  # output error to a log file or something
}
Get-WmiObject Win32_Service –computerName $remote –EA Stop

這個簡短的範例顯示如何 –EA 「 停止 」 參數將會產生,則為 True 的例外狀況,而非只是錯誤訊息,讓您有機會來截取它們,並自行處理它們。 您可能會記錄到檔案、 顯示友善的錯誤訊息或其他項目也有效。

顯示我的指令碼

我說過其中有些已經位元 nitpicky,但它們都提供不同的優點,值得考量。 我邀請您共用您自己的 Windows PowerShell 指令碼。 我檢閱每個月幾並在張貼我建議 ConcentratedTech.com. 請隨意查詢部份我過去的建議,並可能甚至送出您自己的指令碼供檢閱。 我很期待聽到您!

Don Jones 集中技術的一個 co-founder 中取得。 您可以讀取 Windows PowerShell 和其他 IT] 主題中的秘訣,以及連絡別,在他部落格上 ConcentratedTech.com.