[譯] PowerShell Core 6.0 的新增特性

cyw0ng發表於2018-09-15

PowerShell Core 6.0 的新增特性

原文 What's New in PowerShell Core 6.0

PowerShell Core 6.0 是開源的,支援跨平臺(Windows / macOS 和 Linux)的新版本,其構建目標即為支援異構環境及混合雲。

譯者注:異構環境 - 由於 PowerShell 最早被設計為執行在 Windows NT / .Net 平臺,這裡的異構指 *NIX 平臺

從 .Net Framework 遷移到 .Net Core

PowerShell Core 使用 .Net Core 2.0 作為其執行時平臺,.Net Core 2.0 使 PowerShell 可以被執行於多個平臺(Windows / macOS 和 Linux)之上。PowerShell Core 同時向外暴露由 .Net Core 2.0 提供的 API 集合,用於 cmdlet 及指令碼中。

Windows PowerShell 使用 .Net Framework 託管 PowerShell 引擎,因此其向外暴露由 .Net Framework 提供的 API 集合。

.NET Core 與 .NET Framework 間 API 的區別被定義為 .Net 標準 中的一部分

For more information on how this affects module/script compatibility between PowerShell Core and Windows PowerShell, see Backwards compatibility with Windows PowerShell.

更多關於此對 PowerShell Core / Windows PowerShell 模組或指令碼的相容性影響可參考 Windows PowerShell 向前相容性

對 macOS 與 Linux 的支援性

PowerShell 現提供對如下 Linux / macOS 發行版的官方支援,支援範圍包含:

  • Windows 7, 8.1, and 10
  • Windows Server 2008 R2, 2012 R2, 2016
  • Windows Server Semi-Annual Channel
  • Ubuntu 14.04, 16.04, and 17.04
  • Debian 8.7+, and 9
  • CentOS 7
  • Red Hat Enterprise Linux 7
  • OpenSUSE 42.2
  • Fedora 25, 26
  • macOS 10.12+

我們的社群同時也提供對如下平臺的 PowerShell 發行包,但它們並非被官方支援:

  • Arch Linux
  • Kali Linux
  • AppImage(可用於多個 Linux 平臺)

同時我們提供一些實驗性的(非正式支援的)發行版用於下列平臺:

  • Windows on ARM32/ARM64
  • Raspbian (Stretch)

A number of changes were made to in PowerShell Core 6.0 to make it work better on non-Windows systems. Some of these are breaking changes, which also affect Windows. Others are only present or applicable in non-Windows installations of PowerShell Core.

PowerShell Core 6.0 包含了大量針對非 Windows 平臺的修正,其中的部分是斷裂性影響,甚至將同時影響 Windows 平臺,其餘的只出現或被啟用在非 Windows 平臺的 PowerShell Core 上。

  • 提供對 UNIX 平臺的原生命令萬用字元支援。
  • more 功能採用 Linux 的預設分頁器策略,即 less。這代表使用者可以在原生二進位制/命令間使用萬用字元(例如,ls *.txt)。
  • 當處理原生命令引數時,行尾的反斜槓符號將被預設忽略。
  • 由於指令碼簽名功能現在還不能在非 Windows 平臺上使用,在非 Windows 平臺上 PowerShell 的 -ExecutionPolicy 開關被預設忽略。
  • 修復 ConsoleHost 以使能 UNIX 平臺的 NoEcho 功能。
  • 修復 Get-help 以支援 UNIX 平臺上非大小寫敏感的模式匹配。
  • powershell 於安裝包中新增幫助頁(man-page)。

日誌

於 macOS 中,PowerShell 使用原生的 os_log API 以記錄日誌於 Apple 統一日誌系統中。於 Linux 中,PowerShell 使用 Syslog 這個通用的日誌解決方案。

檔案系統

一系列更新已被運用於 macOS 與 Linux 平臺以支援傳統意義上於 Windows 平臺上不支援的檔名內字元:

  • 對 cmdlet 輸入的路徑現已斜槓無感化(slash-agnostic)。即 /\ 均可被用做路徑分割符

  • XDG 基本路徑規範現已被採納並被預設開啟

    譯者注:XDG 基本路徑規範 - 即 XDG Base Directory Specification,用於規範作業系統與上層應用對路徑名的處理規範

    • Linux / macOS 平臺配置檔案存在於 ~/.config/powershell/profile.ps1
    • 歷史檔案存在於 ~/.local/share/powershell/PSReadline/ConsoleHost_history.txt
    • 使用者模組路徑存在於 ~/.local/share/powershell/Modules
  • 於 UNIX 平臺支援包含冒號的檔案 / 資料夾名

  • 支援包含逗號的指令碼名或路徑(感謝 @TimCurwick!)

  • 路徑跳轉相關的 cmdlet 中支援 -LiteralPath 引數,該引數被宣告時,通配擴充套件將被禁用

  • 升級 Get-ChildItem 使得其工作模式更類似於 UNIX 平臺的 ls -R 及 Windows 平臺的 DIR /S 命令。Get-ChildItem 現返回遞迴搜尋中遇到的符號連結且不搜尋該符號連結對應的路徑。

大小寫敏感性

Linux 及 macOS 傾向於大小寫敏感而 Windows 平臺傾向於大小寫不敏感,總的來說,PowerShell 使大小寫不敏感的。

舉例來說,macOS 與 Linux 平臺上的環境變數是大小寫敏感的,因此 PSModulePath 這樣的環境變數已經被預先置為了固定的大小寫組合形式。Import-Module 在通過檔案路徑決定模組名稱時,是大小寫不敏感的

支援共存(side-by-side)安裝

PowerShell Core 的安裝 / 配置及執行都與 Windows PowerShell 相隔離。PowerShell Core 存在行動式 ZIP 包,通過該包,使用者可以於磁碟上部署任意套 PowerShell Core 並將他們作為其他應用的依賴。共存(side-by-side)安裝方案使得對新 PowerShell 版本的測試及存量指令碼的遷移更加容易。同時,該方案也可用於對執行於某特定版本的指令碼做相容性配置。

注:預設的,Windows 平臺基於 MSI 的安裝包將對系統現註冊 PowerShell 例項進行替換升級。

powershell(.exe) 重新命名為 pwsh(.exe)

PowerShell Core 的執行二進位制檔案由 powershell(.exe) 更名為 pwsh(.exe)。這一改變使使用者可以確定性的執行共存(side-by-side)安裝模式下的 PowerShell Core。而且 pwsh 更短也更好記。

其他從 powershell(.exe) 重新命名為 pwsh(.exe) 後的改變:

  • 更改第一個位置引數由 -Command-File。這一改變修復了 PowerShell 指令碼中的 #! 的使用於非 Windows 平臺定向至非 PowerShell shell 的可能性。這也意味著使用者可以直接執行指令碼,而不用指明 -File 引數,如 pwsh foo.ps1 / pwsh fooScript。同時這也意味著,使用者希望執行某命令時必須宣告 -Command / -c 入口,如 pwsh.exe -Command Get-Command
  • PowerShell Core 接受 -i/ -Interactive 為開關標識的互動式 shell 模式。這使得 PowerShell 可以在 Unix 平臺上被作為預設 shell。
  • pwsh.exe 中移除了 -importsystemmodules / -psconsoleFile 引數
  • 更改了 pwsh -version 以及 pwsh.exe 的內建幫助,以與其他原生工具保持一致。(感謝 @iSazonov!)
  • -File / -Command 錯誤引數報錯資訊及退出碼與 Unix 標準保持一致
  • 於 Windows 平臺增加 -WindowStyle 引數。相似的,非 Windows 平臺基於包的 PowerShell 安裝將升級已經安裝的例項。

於 Windows PowerShell 的向前相容性

PowerShell 的設計目標之一即為儘量保持與 Windows PowerShell 的向前相容性。PowerShell Core 使用 .Net Standard 2.0 版本與其他現存 .Net 版本保持彙編相容性。許多 PowerShell 模組依賴這些 .Net 彙編(有時是 DLL),因此 .Net 標準使得這些模組也可以在 PowerShell Core 上工作。PowerShell Core 也包含自發現功能用以探測知名路徑,比如全域性彙編快取(Global Assembly Cache)路徑等,以尋找 .NET Framework DLL 依賴。

更多 .NET Standard 相關內容可以通過 .NET Blog 或此 YouTube 視訊,或通過該託管於 GitHub 上的 FAQ 瞭解。

PowerShell Core 為確保其內建模組(如 Microsoft.PowerShell.ManagementMicrosoft.PowerShell.Utility 等)與 Windows PowerShell 保持一致已付出巨大努力。在很多情況下,在社群的協助下,我們已經為這些 cmdlet 新增了新能力以及 Bug 修復。在某些情況下,由於部分 .Net 層次上的依賴缺失,受影響的功能是不可用的或已經被移除。

大部分作為 Windows 元件分發的模組(例如 DnsClient / Hyper-V / NetTCPIP / Storage 等)及其他微軟產品,例如 Azure 與 Office 等尚未明確的被移植到 .Net Core 中。PowerShell 團隊正在與這些產品的相關團隊一同驗證並移植這些現存模組至 PowerShell Core With .NET Standard and CDXML,大部分現存的 Windows PowerShell 模組看上去確實可以在 PowerShell Core 中正確使用,但這仍然需要官方驗證,因此他們現今也未被完全支援。

通過安裝 WindowsPSModulePath 模組,使用者也可以通過將 Windows PowerShell PSModulePath 填充至 PowerShell Core PSModulePath 的方式,使用這些模組。

首先,從 PowerShell Gallery 安裝 WindowsPSModulePath 模組:

# Add `-Scope CurrentUser` if you're installing as non-admin
Install-Module WindowsPSModulePath -Force
複製程式碼

其後,執行 Add-WindowsPSModulePath cmdlet 將 Windows PowerShell 的 PSModulePath 加入到 PowerShell Core 中:

# Add this line to your profile if you always want Windows PowerShell PSModulePath
Add-WindowsPSModulePath
複製程式碼

Docker 支援

PowerShell Core 為所有其支援的主流平臺(包含多個 Linux 發行版,Windows Server Core 與 Nano Server 等)新增了 Docker 容器映象。

獲取完整列表,請嘗試訪問 microsoft/powershell on Docker Hub,更詳細資訊,請檢視 GitHub 上的 Docker 相關資訊。

基於 SSH 的 PowerShell 遠端訪問

PowerShell Remoting Protocol(PSRP)除執行於傳統的 WinRM 外,現可以工作於 Secure Shell Protocol(SSH)之上。

這代表使用者可以通過 Enter-PSSession / New-PSSession 建立基於 SSH 的會話。所有使用者需要做的,僅僅是將 PowerShell 註冊為基於 OpenSSH 的 SSH Server 的一個子系統,之後便可通過 PSSession 語義層使用傳統的 SSH 認證(如密碼或私鑰等)。

更多關於配置並使用 SSH 基礎的遠端連線的資訊,請參考 PowerShell Remoting over SSH

預設編碼格式除 New-ModuleManifest 外設定為沒有位元組序標識的 UTF-8 編碼

在過往版本中,Windows PowerShell cmdlet 例如 Get-Content / Set-Content 使用不同的編碼規範,比如 ASCII 及 UTF-16。預設編碼上的不同將在混合使用未統一編碼格式的 cmdlet 時產生問題。

非 Windows 平臺傳統上使用沒有位元組序標識(BOM)的 UTF-8 編碼格式作為文字的預設編碼格式。更多的 Windows 程式和工具正在從 UTF-16 向沒有位元組序標識的 UTF-8 編碼格式遷移。PowerShell Core 改變了預設的編碼格式以適應更廣泛的平臺。

這代表所有可使用 -Encoding 引數的內建 cmdlet 將預設取值為 UTF8NoBOM。以下的 cmdlet 將被該改動所影響:

  • Add-Content
  • Export-Clixml
  • Export-Csv
  • Export-PSSession
  • Format-Hex
  • Get-Content
  • Import-Csv
  • Out-File
  • Select-String
  • Send-MailMessage
  • Set-Content

這些 cmdlet 也同時獲得了升級,因此 -Encoding 引數全域性上將採納 System.Text.Encoding

$OutputEncoding 的預設值也被轉變為 UTF-8。

最為最佳實踐,使用者應當於指令碼中明確的通過 -Encoding 引數設定編碼型別,以在各個平臺上取得可預期的確定性結果。

New-ModuleManifest cmdlet 不具備 -Encoding 引數。通過 New-ModuleManifest 建立的模組配置檔案(.psd1)的編碼型別由環境決定:如果 PowerShell Core 執行於 Linux 環境中時,那麼採用沒有位元組序標識(BOM)的 UTF-8 編碼;否則採用有位元組序標識(BOM)的 UTF-16 編碼。

支援將流水線通過 & 符號放置於後臺

放置 & 符號於一條流水線的尾部將使得該流水線被作為一個 PowerShell Job 執行。當一個流水線被放置於後臺時,將返回一個 Job 物件。當一條流水線作為 Job 執行時,所有的標準 *-Job cmdlet 可以被用於管理 Job。變數(忽略程式相關變數)將自動被拷貝到 Job 中,因此 Copy-Item $foo $bar & 可以工作。同時,Job 被執行於當前目錄而不是使用者的家目錄。更多關於 PowerShell Job 的資訊請參考 about jobs

語義版本

  • SemanticVersion 相容 SemVer 2.0。(感謝 @iSazonov!)
  • 改變 New-ModuleManifest 預設的 ModuleVersion0.0.1 以對齊 SemVer 版本。(感謝 @LDSpits!)
  • System.Management.Automation.SemanticVersion 增加 semver 型別加速器
  • 支援比較 SemanticVersion 例項與 Version 例項,當後者僅包含 Major / Minor 兩個值時

語言升級

  • 實現 Unicode 轉義字元解析,因此使用者可以使用 Unicode 字元用於引數、字串或變數名中。(感謝 @rkeithhill!)
  • 為 ESC 增加新的轉義字元
  • 支援將列舉轉為字串。(感謝 @KirkMunro!)
  • 修復轉換隻包含單個元素的陣列至通用集合中出現的問題。
  • .. 運算子增加字元範圍過載,因此 'a'..'z' 返回從 az 的字元。(感謝 @IISResetMe!)
  • 修復變數賦值可能複寫只讀變數的問題
  • 當動態執行指令碼中的 cmdlet 時,將本地自動變數作用於轉換至 'DottedScopes'
  • 分離運算子支援選擇單行、多行選項。(感謝 @iSazonov!)

引擎更新

  • $PSVersionTable 加入四個新屬性:
    • PSEdition:於 PowerShell 平臺返回 Core,Windows PowerShell 平臺返回 Desktop
    • GitCommitId:返回該 PowerShell 版本構建所採取的 git commit id
    • OS:標識作業系統型別,即 [System.Runtime.InteropServices.RuntimeInformation]::OSDescription 的字串值
    • Platform:標識平臺型別,即 [System.Environment]::OSVersion.Platform 的字串值,於 Windows 平臺為 Win32NT,於 macOS / Linux 為 Unix
  • $PSVersionTable 中移除 BuildVersion 屬性,該屬性強依賴於 Windows 版本,現在可以使用 GitCommitId 以獲得精確的 PowerShell Core 構建版本。(感謝 @iSazonov!)
  • $PSVersionTable 中移除 ClrVersion 屬性,該屬性與 .Net Core 無關,且其保留於 .Net Core 中僅僅作為歷史遺留原因且在 PowerShell Core 中不可用
  • 增加三個自動變數以檢查 PowerShell 是否執行於某確定的作業系統之上:$IsWindows / $IsMacOs / $IsLinux
  • 增加 GitCommitId 至 PowerShell Core 提示條。現在不再需要通過 $PSVersionTable 獲取,而在啟動時可以直接得到版本資訊。(感謝 @iSazonov!)
  • $PSHome 路徑下新增名為 powershell.config.json 的 JSON 格式的配置檔案以儲存首次執行時的某些配置,如 ExecutionPolicy
  • 當執行 Windows EXE 程式時不阻塞管道
  • 支援列舉 COM 集合

Cmdlet 更新

新 cmdlet

  • Microsoft.PowerShell.Utility 增加 Get-Uptime
  • 增加 Remove-Alias 命令。(感謝 @PowershellNinja!)
  • 增加 Remove-Service 命令用於管理模組。(感謝 @joandrsn!)

Web 相關 cmdlet

  • 為 web 相關 cmdlet 增加證書驗證功能。(感謝 @markekraus!)
  • 為 web 相關 cmdlet 增加內容頭處理功能。(感謝 @markekraus!)
  • 為 web 相關 cmdlet 增加多連結頭部處理支援。(感謝 @markekraus!)
  • 為 web 相關 cmdlet 增加連線頭部分頁功能。
    • 對於 Invoke-WebRequest,當網路回應包含連結頭部,其將建立一個基於字典的 RelationLink 屬性以表示 URL 以及 rel 欄位間的關係,並確保各個連結均為絕對地址以簡化開發。
    • 對於 Invoke-RestMethod,當網路回應包含連結頭部,其將暴露一個 -FollowRelLink 開關去自動跟蹤下一個 rel 連結直至達到最終的地址或跳次數達到可預設的 ·-MaximumFollowRelLink
  • 為 web 相關 cmdlet 增加 -CustomMethod 引數支援,以支援包含非標準動詞的 cmdlet。(感謝 @Lee303!)
  • 為 web 相關 cmdlet 增加 SslProtocol 支援。(感謝 @markekraus!)
  • 為 web 相關 cmdlet 增加多部分包支援。(感謝 @markekraus!)
  • 為 web 相關 cmdlet 增加 -NoProxy 引數支援以使得他們可以忽略系統代理。(感謝 @TheFlyingCorpse!)
  • Web 相關 cmdlet UA 將包含作業系統平臺部分。(感謝 @LDSpits!)
  • 為 web 相關 cmdlet 增加 -SkipHeaderValidation 開關,以支援不驗證頭部值下新增自定義頭部
  • Web 相關 cmdlet 可以在需要的情況下不驗證伺服器 HTTPS 證書
  • 為 web 相關 cmdlet 增加驗證引數。(感謝 @markekraus!)
    • 增加 -Authentication 引數,提供三種選項:Basic / OAuth / Bearer
    • 增加 -Token 引數,用於獲取 OAuth / Bearer 模式下的令牌。
    • 增加 -AllowUnencryptedAuthentication 引數,用於短路任何非 HTTPS 協議下傳輸模式的驗證功能
  • Invoke-RestMethod 增加 -ResponseHeadersVariable 引數以使能頭部資料捕獲。(感謝 @markekraus!)
  • 修復 web 相關 cmdlet 以識別非 Success 返回值的 HTTP Response 為異常。
  • 將 web cmdlet UserAgentWindowsPowerShell 移動至 PowerShell。(感謝 @markekraus!)
  • Invoke-RestMethod 增加明確的 ContentType 檢測功能。
  • 修復 web 相關 cmdlet 的 -SkipHeaderValidation 引數使其可以相容含非標準 UA 的 HTTP 包頭。(感謝 @markekraus!)

JSON 相關 cmdlet

  • ConvertFrom-Json 增加 -AsHashtable 引數,使其返回值為一個 Hashtable 而不是預設型別。(感謝 @bergmeister!)
  • 美化 ConvertTo-Json 輸出。(感謝 @kittholland!)
  • ConvertTo-Json 新增 Jobject 序列化支援。
  • 修復 ConvertFrom-Json 以使其可以反序列化字串陣列形成 JSON 格式的字串。本項更新修復某些情況下新行符可能意外終止 JSON 解釋的問題。
  • 移除 System.Array 中的 AliasProperty "Count" 宣告,以去除某些 ConvertFrom-Json 結果中額外產生的 Count 屬性。(感謝 @PetSerAl!)

CSV 相關 cmdlet

  • Import-CsvConvertFrom-Csv 增加 PSTypeName 支援。(感謝 @markekraus!)
  • Import-Csv 可支援 CR / LF / CRLF 作為行分隔符。(感謝 @iSazonov!)
  • Export-CsvConvertTo-Csv 增加預設值 -NoTypeInformation。(感謝 @markekraus!)

服務相關 cmdlet

  • Get-Service cmdlet 返回的 ServiceController 物件新增屬性:UserName / Description / DelayedAutoStart / BinaryPathName / StartupType。(感謝 @joandrsn!)
  • Set-Service 增加證書設定功能。(感謝 @joandrsn!)

其他 cmdlet

  • Get-ChildItem 增加引數 -FollowSymlink 使其可以提供支援迴圈引用檢測的按需連結遍歷功能。
  • 升級 Add-Type 以支援 CSharpVersion7。(感謝 @iSazonov!)
  • 移除 Microsoft.PowerShell.LocalAccounts 模組,由於其使用了已經不支援了的 API,當找到更好的解決方案時會被恢復。
  • 移除 Microsoft.PowerShell.Diagnostics 中的 *-Counter cmdlet,由於其使用了已經不支援了的 API,當找到更好的解決方案時會被恢復。
  • 支援 Invoke-Item -Path <folder>
  • Split-Path cmdlet 提供 -Extension-LeafBase 開關,使使用者可以切分路徑中的副檔名和剩餘部分。(感謝 @powercode!)
  • Sort-Object 增加 -Top-Bottom 引數,使其支援對首尾的 N 個專案進行排序
  • 通過向 System.Diagnostics.Process 中增加 CodeProperty "Parent" 以暴露程式的父程式。(感謝 @powercode!)
  • Get-Process 中的記憶體列使用 MB 為單位,替換原來的 KB
  • Out-String 增加 -NoNewLine 開關。(感謝 @raghav710!)
  • Move-Item 新增 -Include / -Exclude / -Filter 引數。
  • 允許 * 用作 Remove-Item 的註冊路徑。
  • Get-Credential 增加 -Title 選項,並統一跨平臺體驗。
  • Test-Connection 增加 -TimeOut 選項
  • Get-AuthenticodeSignature cmdlet 現可以獲取檔案簽名時間戳
  • 移除 Get-Help cmdlet 不主持的 -ShowWindow 開關
  • 修復 Get-Content -Delimiter 使其在返回的陣列元素中不包含分界符。(感謝 @mklement0!)
  • ConvertTo-HTML 增加 Meta / Charset / Transitional 選項。(感謝 @ergo3114!)
  • Get-ComputerInfo 返回值新增 WindowsUBRWindowsVersion 屬性。
  • Get-Verb 增加 -Group 引數。
  • New-FileCatalogTest-FileCatalog 增加 ShouldProcess 支援(修復 -WhatIf / -Confirm)。(感謝 @iSazonov!)
  • Start-Process cmdlet 增加 -WhatIf 開關。(感謝 @sarithsutha!)
  • 增加 ValidateNotNullOrEmpty 至現存引數

Tab 補全

  • 基於執行時變數值增強 Tab 補全中的型別推斷功能。(感謝 @powercode!)這使得如下情況下的 Tab 補全可用:

    $p = Get-Process
    $p | Foreach-Object Prio<tab>
    複製程式碼
  • Select-Object-Property 選項新增雜湊表 Tab 補全。(感謝 @powercode!)

  • Select-Object-ExcludeProperty-ExpandProperty 選項引數新增自動補全。(感謝 @iSazonov!)

  • 修復一個 Tab 補全中的 Bug:native.exe --<tab> 調起原生程式自帶補全功能。(感謝 @powercode!)

斷裂性改變

PowerShell Core 引入了大量斷裂性改變,詳細內容請參考 PowerShell Core 6.0 中的斷裂性改變

除錯

  • Invoke-Command -ComputerName 提供遠端步進除錯(remote step-in debugging)支援
  • 開啟繫結式除錯日誌支援

檔案系統更新

  • 支援從 UNC 路徑提供的檔案系統
  • Split-Path 現在可用於 UNC 根下
  • cd 不帶參時,預設行為為 cd ~
  • 修復 PowerShell Core 以使其支援超過 260 字元的檔案路徑長度

Bug 修復與效能提升

我們已經為 PowerShell 平臺配置了大量效能提升,包含對啟動時間 / 多種內建 cmdlet 及與原生二進位制互動性的優化。

同時,我們也修理了大量的 PowerShell Core 中發現的 Bug,完整列表與更改描述,請參考我們放置於 GitHub 上的 CHANGELOG

感知(資料收集)

  • PowerShell Core 6.0 為執行平臺增加了遠端感知功能以上報如下引數值:
    • 作業系統平臺($PSVersionTable.OSDescription
    • 具體 PowerShell 版本($PSVersionTable.GitCommitId

如果使用者希望自願退出該項感知功能(即:資訊收集)只需宣告環境變數 POWERSHELL_TELEMETRY_OPTOUT 為如下的一個值:true / 1 /yes。宣告該環境變數將忽略所有感知功能,即使於 PowerShell 首次啟動時。我們已經計劃公開從該項遙感計劃中得到的資料和提煉的感知於社群中。你可以從該部落格中獲得更多詳細資訊。

相關文章