文章目录[隐藏]

适合初学者阅读的Windows PowerShell 指令工具教学文件,介绍基本概念与操作方法。
PowerShell 是由微软所发展的任务自动化与组态管理框架,它的角色类似于UNIX/Linux 系统上的壳层(shell),透过脚本语言以及各种辅助工具,让系统管理者可以将各种工作自动化。
起初PowerShell 仅支援Windows 系统,后来于2016 年以开放原始码(MIT 授权)的方式释出后,发展成为跨平台的管理工具,目前它已经支援各种主流的Linux 发行版以及Mac OS 系统,其安装档案与原始码都可以从
互动式壳层(Shell)
若要开启Windows 的PowerShell,可从开始选单中寻找「Windows PowerShell」,点选后就可以打开PowerShell 的执行环境。

PowerShell 的操作介面跟传统的命令提示字元(cmd.exe

Cmdlets 与别名
在 PowerShell 指令視窗中,除了可以執行傳統的 Windows 指令、執行檔之外,PowerShell 本身也提供了一種特殊的 cmdlet(發音為 command-let)結構式指令,所有的 cmdlet 指令名稱都是以 動詞-名詞
的方式來命名,例如 Get-Process
、Get-Content
與 Stop-Process
等。
以下這個例子是使用 Get-Process
這個 cmdlet 指令,查詢 Greenshot
這個應用程式的行程資訊:
Get-Process -Name Greenshot

Get-Process
查詢行程資訊大部分的 cmdlet 指令名稱都很長,打字麻煩、也容易不小心打錯字,遇到這種情況時,可以先打指令的前幾個字母,接著按下 Tab 鍵,這樣 PowerShell 就會自動想辦法補其後續的字母。
以輸入 Get-Process
這行指令來說,我們就可以在輸入 Get-Pr
這幾個字之後,按下 Tab 來補齊後續的指令名稱,如果以這幾個字母開頭的指令有很多個的話,則會依序顯示每一個可能的組合,我們可以多按幾下 Tab 鍵來尋找自己想要輸入的指令。
雖然 Tab 鍵可以讓我們少打一些字,但是管理者在平常互動式的操作中,使用太長的指令還是不方便,為了讓互動式操作更順手,PowerShell 為所有的 cmdlet 都定義了簡短的別名(aliases),並且允許使用者再輸入參數名稱時,只要輸入足夠辨識的字母即可,另外 PowerShell 的指令是不分大小寫的,所以可以全部都以小寫輸入。
Get-Process
這行指令預設的別名是 gps
,所以我們也可以這樣執行上面的指令:
gps -n Greenshot

cmdlet 指令的參數除了以參數名稱來指定之外,也可以透過參數的位置順序來判斷(這樣就不需要打參數名稱)。以 Get-Process
來說,若不加參數名稱,其第一個參數就是行程名稱(也就是 -Name
),而這個行程名稱參數也允許使用萬用字元,所以我們可以使用這樣的指令找出名稱是 G
開頭、t
結尾的行程:
gps G*t

物件
PowerShell 將許多的資料都當成物件來處理,這樣可以讓許多的工作指令搞撰寫起來更方便。
舉例來說,以下這行指令會產生一個簡單的字串:
"Hello, World."
Hello, World.
事實上這行字串就是一個 .NET 框架的物件,我們可以透過它的 Length
屬性,得知此字串的長度:
"Hello, World.".Length
13
所有會產生輸出的 cmdlet 指令,也可以傳回資料物件,例如 Get-Process
就會傳回 System.Diagnostics.Process
這種物件,我們可以把指令傳回的物件儲存在變數中,方便後續的指令稿使用。
在 PowerShell 中,變數名稱都是以錢字號($
)開頭,若要把 Get-Process
指令的查詢結果儲存下來,可以這樣寫:
$process = Get-Process -Name Greenshot
由於這個儲存下來的 $process
是一個完整的 Process
物件,所以我們可以使用其中的各種屬性或函數來控制該行程。例如取得行程的 CPU 使用率:
$green.CPU
或強制關閉這個應用程式:
$green.Kill()
這裡的範例只是讓大家了解我們可以透過物件進行各種操作,在 PowerShell 若要讓特定的程式終止執行,最直接的做法是使用 Stop-Process
這個 cmdlet 指令。
管理者需求導向
PowerShell 本身在設計時就考慮了許多系統管理者的需求,除了可使用 .NET 框架的物件之外,還有其他很多方便的小功能,像在電腦上常用的 KB、MB、GB 等單位,也可以在 PowerShell 中直接使用,例如計算 2TB 的資料以每秒 3.5 MB 的速度備份,需要幾個小時:
2TB / 3.5MB / 3600
166.440634920635
另一項常用的功能就是日期與時間的處理,以下這一行指令是計算從現在的時間到晚上 21:45
還有多久:
[DateTime] "21:45" - [DateTime]::Now
Days : 0 Hours : 11 Minutes : 22 Seconds : 44 Milliseconds : 956 Ticks : 409649565189 TotalDays : 0.474131441190972 TotalHours : 11.3791545885833 TotalMinutes : 682.749275315 TotalSeconds : 40964.9565189 TotalMilliseconds : 40964956.5189
這裡用中括號包起來的 [DateTime]
代表 System.DateTime
這個類別,[DateTime] "21:45"
的作用是將 "21:45"
這個字串轉換為 System.DateTime
的物件。
後面的 [DateTime]::Now
代表呼叫 System.DateTime
類別內的 Now
靜態函數,傳回現在的時間,與前面的時間相減之後,就得到間隔的時間了。
如果只想取出結果中的 Hours
欄位,可以這樣寫:
$result = [DateTime] "21:45" - [DateTime]::Now $result.Hours
11
若要計算兩個日期之間的天數,可以這樣寫:
$result = [DateTime] "2018/10/23" - [DateTime]::Now $result.TotalDays
160.565214351617
組合多項指令
有時候我們在處理資料時,會經過好幾道程序,前一個指令的輸出會作為下一個指令的輸入,在這種狀況下就可以使用 PowerShell 的管線(pipe)功能,串接多個指令。
PowerShell 的管線符號為 |
,只要上一個指令所產生的物件類型可以被下一個指令接受,就可以用管線符號直接串接起來使用。例如我們可以使用 Get-Process
指令找出 Edge 瀏覽器的行程,然後將結果直接導給 Stop-Process
,關閉 Edge 瀏覽器:
Get-Process -Name MicrosoftEdge | Stop-Process
另一個例子是使用 Get-Item
將 FolderA
目錄下的的所有檔案列出來,導給 Move-Item
指令,將這些檔案搬移至 FolderB
目錄中:
Get-Item FolderA* | Move-Item -Destination FolderB
我們也可以使用 PowerShell 的管線串接多個指令,以下是將 Get-Process
的輸出用 Where-Object
篩選出 Handles
大於或等於 1000
的項目,經過 Sort-Object
排序後,再由 Format-Table
輸出指定的欄位:
Get-Process | Where-Object { $_.Handles -ge 1000 } | Sort-Object Handles | Format-Table Handles,Name,Description -Auto

保护机制
PowerShell 提供系统管理者非常强大又方便的功能,不过有了快速方便的管理工具,在使用上也必须谨慎小心,避免下错指令搞坏系统。
为了让管理者可以方便确认要执行的实际动作,PowerShell 在许多的指令中都提供了 -WhatIf
-Confirm
例如我们如果想要把所有系统上 Edge
Edge
Stop-Process
Stop-Process
-WhatIf
Stop-Process
Get-Process

-WhatIf
在我们确认所有的动作都没问题之后,再将 -WhatIf
另外一种方式是使用 -Confirm
Get-Process

-Confirm
查询指令与物件用法
PowerShell 中可用的cmdlet 指令数量相当多,我们不太可能记得所有的指令名称与用法,实务上的做法通常都是遇到问题时,再去查询有哪些相关的指令可以使用。
若想要以关键字来寻找相关的cmdlet 指令,可以使用 Get-Command
*
process
Get-Command

Get-Command
搜寻指令Get-Command
会列出所有符合搜寻条件的指令,若想要查询某个指令的详细用法,可以使用 Get-Help
Stop-Process
Get-Help

Stop-Process
在PowerShell 中除了cmdlet 指令很多让人记不起来之外,.NET 框架的物件种类也不少,再加上每一种物件的用法都不同,所以在使用物件时,我们也时常会需要查询各种物件可用的属性与方法。
若要查询一个物件有哪些属性与方法,可以将物件透过管线的方式导给Get-Member
"Hello"
"Hello"

我们也可以将其他cmdlet 指令输出的物件直接导给Get-Member
Get-Process
或是将储存在变数中的物件导给 Get-Member
$result
指令稿
PowerShell 跟一般的指令稿语言(script language)一样,可以直接在互动式的视窗中执行,若程式码比较长的话,也可以把指令写在指令稿档案(script file)当中,一次执行档案内所有的指令。
假设我们有以下的几行下载网页的PowerShell 指令稿:
$webClient
若要以指令稿档案的方式执行这段程式码,首先要把它们储存成PowerShell 的指令搞档案(副档名为.ps1
C:OfficeGuidescript.ps1
C:OfficeGuidescript.ps1
若执行时出现了「系统上已停用指令码执行」的错误讯息,请参考
历史指令
若要查询过去执行过的指令,可以使用 Get-History
Get-History
在执行一系列的指令之后,若想要将执行过的动作储存成整份的指令稿,可以使用 Get-History
Foreach-Object
Get-History
接着可以启动记事本编辑一下这些执行过的指令:
notepad C:OfficeGuidescript2.ps1
编辑好之后,就可以直接执行这份指令稿了:
C:OfficeGuidescript2.ps1
注解
在撰写指令稿的时候,为了让程式码更容易阅读,建议可以加上适当的注解,在PowerShell 中单行的注解可用井字号(#
# 列出chrome 的行程
在程式码中,所有 #
Get-Process
如果要放置多行的注解,可以将注解使用 <#
#>
<# #>
这种多行的注解适合用于详细的叙述,或是把整段暂时没用的程式码注解起来。
浏览种类型资料
PowerShell 的provider 架构允许程式开发者以类似档案系统的操作方式,浏览与操作各类型的资料库。
以最普通的档案系统来说,我们可以使用以下指令列出 C:
Set-Location

而在熟悉这套操作模式之后,就可以用相同的方法浏览Windows 的登录机码:
Set-Location

相同的操作方法也可以套用在凭证的浏览上:
Set-Location

参考资料: