Windows PowerShell 講座 (3)— PS 磁碟機

發佈日期: 2008 年 1 月 10 日

作者:賴榮樞
    www.goodman-lai.idv.tw

從 DOS 開始,「磁碟機--目錄--檔案」是我們存取檔案系統的架構,而 Windows PowerShell 不但包含了這種我們早已熟悉的架構,更將這種架構延伸成 『Windows PowerShell 磁碟機』(簡稱 PS 磁碟機),可以讓我們存取其他類型的資料。本文將從檢視 PS 磁碟機開始,分別以實際的例子說明相關指令的用法,包括 PS 磁碟機的新增、刪除與切換,以及 PS 磁碟機工作目錄的切換、內容項目的瀏覽與操作。

本頁內容

檢視 PS 磁碟機
Windows PowerShell 提供者
新增、刪除 PS 磁碟機
切換 PS 磁碟機
處理 PS 磁碟機的目前工作位置
瀏覽 PS 磁碟機內容
提供者形式的路徑表示方式
操作 PS 磁碟機項目
總結

PS 磁碟機讓我們可以在 Windows PowerShell 環境存取檔案系統,但還不只這樣,類似的存取概念、架構、甚至指令,我們還可以用來存取登錄資料庫或系統環境變數,本文將從找出系統裡的 PS 磁碟機開始討論這個議題。

檢視 PS 磁碟機

在 Windows PowerShell 環境執行 Get-PSDriver cmdlet ,就會列出系統裡的各個 PS 磁碟機,例如以下是我系統裡的 PS 磁碟機。

Dd125498.65-winPowerShell-3-01(zh-tw,TechNet.10).jpg

上述結果列出系統所有的 PS 磁碟機,最左欄的 Name 是 PS 磁碟機名稱,接著的 Provider 是該部 PS 磁碟機的提供者、 Root 是磁碟機的根目錄,而最後一欄 CurrentLocation 提示了目前 Windows PowerShell 環境的磁碟機及目錄位置(此例為 C 磁碟機的 Users \ Administrator )。

上述的結果是根據 PS 磁碟機名稱的英文字母作為排列順序,根據磁碟機的提供者,其中有以下幾種類型的 PS 磁碟機:

  • FileSystem :可用來存取原本熟悉的檔案系統,例中有三部屬於檔案系統的 PS 磁碟機,分別對應到系統的軟碟機、硬碟的分割區、光碟機。

  • Alias:存放 cmdlet 別名的 PS 磁碟機。

  • Certificate :存放憑證的PS磁碟機。

  • Environment :存放環境變數的 PS 磁碟機。

  • Function :存放 Windows PowerShell 函式的 PS 磁碟機

  • Registry :存放系統登錄資料庫的 PS 磁碟機,共有 HKCU 和 HKLM 兩部。瀏覽 PS 磁碟機內容

  • Variable:存放 Windows PowerShell 變數的 PS 磁碟機

Get-PSDrive 也可以顯示 PS 磁碟機的細節,下列第一行命令可以列出系統裡所有 PS 磁碟機的細節,第二行命令則會列出C磁碟機的細節(您可將C換成其他 PS 磁碟機名稱)。

Get-PSDrive | Format-List *

Get-PSDrive C | Format-List *
            

Get-PSDrive的其他用法

Get-PSDrive 還有其他用法,例如列出特定名稱的 PS 磁碟機(其中的參數名稱 -name 可以省略):

  • Get - PSDrive -name c,d

  • Get - PSDrive hk *

  • Get - PSDrive function

Dd125498.65-winPowerShell-3-02(zh-tw,TechNet.10).jpg

或者列出特定提供者名稱的磁碟機(其中的參數名稱 -psProvider 不可以省略):

  • Get-PSDrive -psProvider FileSystem

  • Get-PSDrive -psProvider Registry

Dd125498.65-winPowerShell-3-03(zh-tw,TechNet.10).jpg

Windows PowerShell 提供者

我們之所以能存取上述各種類型的PS磁碟機,其實是拜 Windows PowerShell 提供者( provider )所賜。提供者簡化了我們從 Windows PowerShell 命令列存取資料的方式,並且以類似檔案系統的格式來呈現透過提供者所存取到的資料。

FileSystem 提供者呈現了磁碟機、目錄、檔案讓我們存取,這可以說是我們最熟悉的提供者,縱使您不知道何謂 Windows PowerShell 提供者,但只要進入 Windows PowerShell 環境,就可以繼續利用以前DOS或CMD的概念和指令存取磁碟機、目錄、檔案。而同樣的操作觀念和指令除了可以用在檔案,也可以用在其他提供者所呈現的資料項目,這才是 Windows PowerShell 提供者之所以能簡化資料存取的關鍵。

若想知道系統裡安裝了哪些提供者,可以利用 Get-psProvider:

Dd125498.65-winPowerShell-3-04(zh-tw,TechNet.10).jpg

上述七種是 Windows PowerShell 內建的提供者,廠商也可根據自身的需求,替自己的資料開發提供者,讓使用者能在 Windows PowerShell 環境以類似檔案存取的概念或指令來管理資料。

新增、刪除 PS 磁碟機

Windows PowerShell 也可以讓我們新增 PS 磁碟機,然後將目錄路徑對應到新增的磁碟機,以簡化路徑太長的困擾;例如我們可以將常用、路徑很長的目錄或登錄機碼對應到 PS 磁碟機。新增 PS 磁碟機時必須提供三個參數:

  • -Name: 指定磁碟機名稱。

  • -psProvider: Windows PowerShell 提供者, FileSystem 代表檔案系統位置、 Registry 代表登錄位置。

  • -Root: 新磁碟機的根目錄,也就是要對應到新磁碟機的路徑。

新增 PS 磁碟機的 cmdlet 是 New-PSDrive(別名是 ndr、mount),例如以下的例子:

# 新增 FileSystem 類型的PS磁碟機
ndr -Name MyMusic -psProvider FileSystem -Root "C:\Documents and Settings\gboy\My Documents\My Music"
# 新增之後即可使用
cd MyMusic:

# 新增 Registry 類型的PS磁碟機
ndr -Name cvkey -PSProvider Registry -Root HKLM\Software\Microsoft\Windows\CurrentVersion
# 新增即可使用
cd cvkey:
 

新增的 PS 磁碟機僅在目前的 Windows PowerShell 階段有效,但我們可以將新增 PS 磁碟機的指令放在 Windows PowerShell 設定檔,讓每次執行 Windows PowerShell 皆有自己新增的 PS 磁碟機可用。

Remove-PSDrive(別名為 rdr)可以刪除 PS 磁碟機,但如果目前的工作目錄就在要刪除的 PS 磁碟機,則會出現使用中而無法刪除的錯誤(因此要先切到其他磁碟機):

# -Name 可省略
rdr -Name MyMusic
	
rdr cvkey

切換 PS 磁碟機

原本的 CMD 是以單一字母作為磁碟機的識別代號,這種作法在 Windows PowerShell 的 PS 磁碟機依然可行,只是原本稱為磁碟機代號,現在稱為磁碟機名稱(例如此例的 A、C、D),而原本的 CMD 是以磁碟機代號跟著冒號來切換磁碟機,現在也非常類似,只要利用 Set-Location cmdlet(或其別名 cd、chdir、sl),並以磁碟機名稱及冒號作為參數即可,例如以下的例子會從 C:\Users\Administrator 依序切換到 Alias、Function、HKLM、Env:\,最後又切回C,並且再切換到 C:\Documents and Settings; 操作時請記得,磁碟機名稱之後要跟著一個英文半形的冒號。

Dd125498.65-winPowerShell-3-05(zh-tw,TechNet.10).jpg

處理 PS 磁碟機的目前工作位置

Windows PowerShell 內建了四個 cmdlet 讓我們可以處理 PS 磁碟機的目前工作位置,我們需要利用這些 cmdlet 來取得或設定 PS 磁碟機的現行目錄,以便進一步的操作,這四個 cmdlet 包括了上述的 Set-Location ,以及 Get-Location、Push-Location、Pop-Location。

Set-Location

Set-Location 除了可以用來切換 PS 磁碟機(如上例),還可以用來設定現行的工作目錄,例如:

Dd125498.65-winPowerShell-3-06(zh-tw,TechNet.10).jpg

如同我們熟悉的 DOS CD 指令的用法,直接將要設定(切換)的目錄名稱放在 Set-Location 之後當作參數即可,如果目錄名稱有空白字元,請記得要以雙引號括住整個目錄名稱,要設定的目錄必須循序依照既有的階層架構,不然的話就必須指定完整的目錄路徑名稱(例如 "C:\Documents and Settings");此外,亦可使用代表上一層目錄的「雙點」(..)以及代表根目錄的倒斜線(\)等符號,作為設定的目錄名稱(單點(.)代表現行目錄)。

Windows PowerShell 環境預設的提示字元包含了現行目錄,因此成功執行 Set-Location 之後的目錄變化,會反映在提示字元。但如果提示字元未能顯示現行目錄,或其他任何想要確認 Set-Location 執行結果的情況,可以在 Set-Location 加上 -PassThru 參數,讓 Set-Location 執行之後傳回目前所在的工作目錄,例如:

Dd125498.65-winPowerShell-3-07(zh-tw,TechNet.10).jpg

Get-Location

Get-Location(別名是 pwd )可以取得目前工作目錄,預設是取得目前工作磁碟機的目錄,但也可以加上參數來取得其他PS磁碟機的工作目錄,例如以下的例子:

Dd125498.65-winPowerShell-3-08(zh-tw,TechNet.10).jpg

上述第一例沒有任何參數,因此會依預設顯示目前工作磁碟機的目錄,而由於目前所在的磁碟機是C,因此顯示 C:\Users\Administrator。其他例子分別以 -psDrive 和 -psProvider 參數,希望能顯示特定 PS 磁碟機或提供者的目前工作目錄。

Push-Location以 及 Pop-Location

操作過 DOS 的人一定都有不斷利用 cd 切換工作目錄的經驗:不是自己手動輸入 cd 和目錄名稱,就是利用上下方向鍵找出曾經輸入過的 cd 指令;DOS 環境只允許 8.3 的檔名格式,因此目錄名稱都不長(但卻很難記), Windows 環境的 CMD 允許長而比較容易記憶的目錄名稱,但要經常輸入冗長的名稱卻很麻煩。

為了簡化這個問題, Windows PowerShell 可以用堆疊記錄我們去過的工作目錄,而利用這個堆疊裡的記錄,即可返回最近瀏覽過的目錄。堆疊最主要的特性是「先進後出」,也就是最先記錄的資料,只能最後取得;反之,也就是「後進先出」。

為此, Windows PowerShell 提供了兩個功能類似 Set-Location 、但是會將工作目錄名稱推入堆疊或自堆疊取出的 cmdlet:Push-Location(別名為 pushd )、Pop-Location(別名為 popd )。

Push-Location除了會依照參數來設定現行的工作目錄,還會將工作目錄名稱推入堆疊,例如:

pushd links
pushd c:\windows
pushd HKLM:
pushd software

執行上述四個 Push-Location 之後,堆疊內容將如下所示:

HKLM:\software
HKLM:\
C:\Windows
C:\Users\Administrator\Links

因此若執行 Pop-Location(popd),就能依照堆疊內容的順序,回到最近曾經去過的目錄。

Push-Location 和 Pop-Location 還可以指定堆疊名稱,將工作目錄切換的過程記錄特定名稱的堆疊,若不指定堆疊名稱,會使用預設堆疊,因此以下的例子會將切換的過程記錄在兩個堆疊:

pushd links -stackName sn1
pushd c:\windows -stackName sn1
pushd HKLM:
pushd software

  

執行上述四個 Push-Location 之後,兩個堆疊的內容會如下所示:

HKLM:\software
HKLM:\
預設堆疊

C:\Windows
C:\Users\Administrator\Links
sn1

指定了堆疊名稱的 Push-Location ,就必須搭配堆疊名稱相同的 Pop-Location:

popd -stackName sn1
popd

上述例子的第一行命令是在 HKLM:\software ,但取回的是堆疊 sn1 ,因此會回到 C:\Users\Administrator\Links ,而第二行命令因為沒有指定堆疊名稱,因此會以預設堆疊回到 HKLM:\ 。

另外指定堆疊名稱可以讓 Push-Location、Pop-Location 記錄更多的工作目錄歷程,但要注意的是,過多的堆疊卻也考驗著我們使用這項功能的記性。

瀏覽 PS 磁碟機內容

瞭解如何切換(設定)PS磁碟機及工作目錄之後,現在讓我們說明如何存取PS磁碟機的內容。雖然 Windows PowerShell 提供者是以磁碟機、目錄、檔案的階層架構來呈現資料的結構和內容, 但只有 FileSystem 提供者所呈現的是真正的檔案,因此 Windows PowerShell 是以「項目」來表示PS磁碟機的內容,也就是說,依據PS磁碟機的類型, PS 磁碟機的項目可能是真正的檔案、目錄、磁碟機 ,或者是登錄資料庫的機碼、系統的環境變數、定義於 Windows PowerShell 階段的函式、變數、別名。

再者,由於我們大多已經因為之前操作過 DOS、CMD 或 Linux/UNIX 等系統,而熟悉並累積了操作檔案系統的經驗,因此 Windows PowerShell 提供者 /PS 磁碟機將檔案系統的架構、概念、指令,延 伸到其他類型的資料,目的就是希望我們能利用既有的經驗來操作其他類型的資料。例如我們可以繼續使用 cd 、 chdir 、 sl 等指令(其實都是 Set-location 的別名)來切換 PS 磁碟機或工作目錄,同樣的 ,切換到 PS 磁碟機或工作目錄之後,我們也可以利用原本熟悉的 dir 或 ls(其實是 Get-ChildItem 的別名),來列出 PS 磁碟機或工作目錄的內容,或者直接以磁碟機或目錄名稱作為 dir 或 ls 的參數,例如:

dir

ls | more

dir | Format-List * | more

ls | Format-Table * | more

# HKCU對應到HKEY_CURRENT_USER登錄Hive
dir HKCU:

ls alias: | more

# 列出Alias磁碟機Definition欄位是get開頭的項目
ls alias: | Where-Object {$_.definition -like "get*"}

dir c:\windows

ls function:

dir env:

Get-ChildItem 也可以使用萬用字元,而且星號(*)和問號(?)的用法與 DOS/CMD 相同,但是 Windows PowerShell 多了以方括號括住的比對字元模組,例如以下的例子會顯示主檔名是 a 或 b 開頭的任何檔案:

dir [ab]*.*

如果想要找出主檔名是 ab 開頭的任何檔案該怎麼作呢?以下是解答

dir ab*.*

但如果想要找出主檔名裡有 a 或 b 的任何檔案呢?可以這麼做:

dir *[ab]*.*
        

最後一題,該如何找出主檔名裡有 ab 的任何檔案?先試著想想,再參考以下的答案:

dir *ab*.*

Get-ChildItem 的參數不少,以下介紹常用的參數:

  • -Recurse: 一併列出子目錄裡的項目,相當於 DOS/CMD dir 指令的 /s 參數;例如:

    dir c:\windows\system32 -Recurse
    
    # 顯示HKCU底下所包含的項目
    dir HKCU: -Recurse
    
    
  • -Name: 僅列出項目名稱;例如:

    dir HKCU: -Name
                
  • -Force: 顯示隱藏項目,若有屬性為隱藏的檔案,需加此參數才能顯示;例如:

    dir c:\windows -Force
                
  • -Exclude:可以用來排除某些特定的項目,例如以下兩個例子。第一個會從主檔名為 w 開頭、內含 32 的所有檔案,剔除掉副檔名為 dll 的檔案,並加以顯示。第二個會從主檔名內含 32 的所有檔案,剔除掉主檔名包含任何 c 或 r(不分大小寫)的檔案,再加以顯示。

    dir c:\windows\system32\w*32*.* -Exclude *.dll
    
    dir c:\windows\system32\*32*.exe -Exclude *[cr]*
    
                
  • -Include:可以用來包含某些特定的項目。例如以下的第一個例子只會列出 c:\windows 裡所有副檔名為 xml 的檔案, -Recurse 參數其實沒有作用;如果要找出 c:\windows 及其子目錄裡的所有副檔名為 xml 的檔案,必須改用第二個例子。

    dir c:\windows\*.xml -Recurse
    
    dir c:\windows -Include *.xml -Recurse
    
                

以下是個複雜許多的例子,可以找出 Program Files 目錄最近修改日期是 2007 年 12 月 31 日以後、檔案大小介於 1 MB 到 10 MB 之間的所有 dll 檔案:

dir $env:ProgramFiles -Recurse -Include *.dll | Where-Object –FilterScript
{($_.LastWriteTime -gt "2005-10-01") -and ($_.Length -ge 1m) -and ($_.Length
-le 10m)}
            

提供者形式的路徑表示方式

本文所介紹的 cmdlet 都具有 -Path 參數,例如顯示 C 磁碟機根目錄內容的命令,完整寫法應該是:

# 包含-Path的完整寫法
dir -Path c:\

# 省略-Path的寫法
dir c:\
  

其中 -Path 參數的名稱(也就是 -Path )是可以省略的,因此我們通常會採用省略寫法。此外,諸如稍後會介紹的 Copy-Item ,我們通常也會採用省略寫法:

# 省略-Path和-Destination的寫法
Copy-Item c:\temp\*.txt d:\temp

# 完整寫法
Copy-Item -Path c:\temp\*.txt -Destination d:\temp

而不論是 -Path 或 -Destination ,其後跟著的是代表路徑的字串,除了上述這種我們習以為常的「磁碟機\目錄\檔案」名稱的表示方式之外,還有一種稱為「提供者形式」的表示方式;例如 C:\ 和 HKCU 的提供者形式表示方式如下:

 # 完整寫法
dir Microsoft.PowerShell.Core\FileSystem::C:\
dir Microsoft.PowerShell.Core\Registry::HKCU

# 省略寫法
dir FileSystem::C:\
dir Registry::HKCU
 

操作 PS 磁碟機項目

Windows PowerShell 是以「項目」來表示PS磁碟機的內容,因此我們可以利用以下的指令來列出與項目有關的 cmdlet:

 Get-Command -Noun Item 

以下是與項目有關的 cmdlet:

  • Clear-Item

  • Copy-Item

  • Get-Item

  • Invoke-Item

  • Move-Item

  • New-Item

  • Remove-Item

  • Rename-Item

  • Set-Item

從名稱應該不難瞭解這些與項目相關 cmdlet 的功能,以下我們利用例子簡述這些 cmdlet 的用法。

  • New-Item(別名為 ni):可用來建立新的檔案、目錄或登錄機碼;如果是別名或變數,要利用 New-Alias 和 New-Variable 新建。例如以下的例子:

    # 在目前的目錄建立名為 Hour 的目錄
    ni Hour -ItemType Directory
    
    # 在指定的 c:\temp目錄建立 Hour 目錄
    md c:\temp\Hour
    
    # 在指定的 c:\temp\Hour目錄建立 time.txt 檔案
    ni c:\temp\Hour\time.txt -ItemType File
    
    # 在指定的 CurrentVersion 子機碼建立  _Tester 機碼
    ni HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\_Tester
    
    # 新增名稱為 User、 值為 goodman_lai 的環境變數
    ni Env: -Name User -Value goodman_lai
    
            
  • Rename-Item(別名為 rnp、ren ):可更改檔案或目錄的名稱;例如:

    ren c:\temp\Hour\time.txt time.ini
    # 將環境變數 user 更名為 admin
    ren Env:user -NewName admin
    
  • Move-Item(別名為 mi、mv、move ):可以移動檔案或目錄;例如:

    mv c:\temp\Hour c:\       
            
  • Copy-Item(別名為 cpi、cp、copy):複製檔案、目錄或機碼;例如:

    # 將指定的 c:\ 目錄裡的 config.sys 複製到目前目錄
    cp c:\config.sys
    
    # 將指定的 c:\temp 目錄及其底下所有內容複製到D磁碟,並且會強行覆蓋目的區既有且名稱相同的檔案或目錄
    cp c:\temp d:\ -Recurse -Force
    
    # 將HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion 及其屬性和子機碼等全部內容複製到 HKCU:\
    , 並且會建立新機碼 CurrentVersionCopy-Item -Path 'HKLM:\SOFTWARE\Microsoft\Windows\
    CurrentVersion' -Destination HKCU: -Recurse
    
  • Remove-Item(別名為 ri、rm、rmdir、del、erase、rd):刪除檔案或目錄,執行後系統會出現提示訊息;例如:

    # 刪除指定的 c:\temp 目錄底下的所有檔案
    rm c:\temp\hour\*.*
    
    # 加上 -Force 參數可強制刪除隱藏檔和唯讀檔
    rm c:\temp\hour\*.* -Force
    
    # 加上 _Recurse 參數可刪除底下所有的目錄及檔
    rm c:\temp\hour\*.* -Recurse
    
    # 刪除機碼
    Remove-Item HKLM:\_Tester
    
    # 跳過提示並刪除 -Tester 及內含項目(加上 -Recures 參數)
    Remove-Item HKLM:\_Tester -Recurse
    
    # 跳過提示但僅刪除 -Tester 內含的項目
    Remove-Item HKLM:\_Tester\* -Recurse
    
    # 刪除環境變數 admin
    rm Env:admin
     
  • Invoke-Item(別名為 ii):可以用來執行檔案或目錄的預設動作,相當於在檔案總管以滑鼠雙按檔案或目錄;例如:

    ii c:\windows
    
    ii c:\temp\Hour\time.ini
    
  • Remove-Item

  • Rename-Item

  • Set-Item

總結

實從 DOS 時代就已經將許多 IO 裝置當作檔案來處理(例如 copy con ), Windows PowerShell 則是將更多的系統資源也當作磁碟機,尤其將登錄資料庫當成磁碟機來處理,就是很好的方式。 藉由 Windows PowerShell 提供者,我們可以在 Windows PowerShell 命令列模式以磁碟檔案的概念來處理諸多的系統資源,而且廠商更可開發自己的提供者,讓管理者能在 Windows PowerShell 環境處理或管理廠商特定軟體的資料,相當方便。

本文約略介紹了 Windows PowerShell 提供者及 PS 磁碟機的概念與相關指令,但因 PS 磁碟機的範圍包含甚廣,諸如函式、變數、登錄資料庫等磁碟機的存取細節,還與這些議題的基本觀念有關, 待後續有機會提及這些議題的專文,再行完整說明。

顯示: