基本的には公式ドキュメントの内容をベースに説明が不足している個所を補足してまとめています。
正確な情報が必要な場合は英語版の公式ドキュメントをあたってください。
公式ドキュメント
本エントリを書き始めたときは日本語版はなかったのですが最近できた様です。
ただ、明らかに機械翻訳で日本語が怪しい個所がちらほらあるのでできるだけ英語版を見る方が良いでしょう。
新機能一覧
ここから本題に入ります。
構成は公式ドキュメントとできるだけ近くしましたが微妙に変えています。
また、前回説明している部分に関しては端折っています。
ログ
PowerShell内部のイベント発行システムがETWだけでなく、Linuxではsyslog
を、macOSではunified logging systemを使う様になりました。
あくまで内部のログ出力が変わっただけでありGet-EventLog
などのコマンドレットがLinuxやmacOSで使える様になったわけではないのでご注意ください。
ファイルシステム
WindowsだけでなくLinuxやmacOSをサポートしたことにより、ファイルシステムに関する制約や挙動に以下の変更が加えられています。
- パスセパレーターは
/
、\
の両方使えます。(これはWindows PowerShellでもサポートされていますが...) - LinuxやmacOSにおいてはXDG Base Directoryの仕様に従う様になっています。
- CurrentUser*なプロファイルは
~/.config/powershell/
配下に配置されます。 - PSReadilneのヒストリーは
~/.local/share/powershell/PSReadline/ConsoleHost_history.txt
に配置されます。 - ユーザーモジュールは
~/.local/share/powershell/Modules
に配置されます
- CurrentUser*なプロファイルは
- LinuxやmacOSではWindowsで禁止さえれている文字列(
:
、,
など)を含むファイルやディレクトリ名がサポートされます。 - ファイル操作系のCmdletで
-LiteralPath
が指定された場合はワイルドカード文字(*
など)の展開が抑制されます。 Get-ChildItem
の挙動がよりUnixのls -R
、コマンドプロンプトのdir /S
に近くなりました。
新しいGet-ChildItem
はデフォルトでシンボリックリンクのリンク先を再帰検索しない様になっています。PowerShell Coreでは260文字を超えるパスを使用できるようになっています。(#3960)
大文字と小文字の区別
言語としてのPowerShellは基本的に大文字・小文字を区別しませんが、クロスプラットフォーム化したことによりLinuxやmacOSにおいてはいくかのケースで大文字・小文字が区別されます。
- パス指定
# Windows : 大文字・小文字は区別されない PS C:\> Test-Path C:\ True PS C:\> Test-Path c:\ True # Linux/Mac : 大文字・小文字は区別される PS /> Test-Path /var/ True PS /> Test-Path /Var/ False
- 環境変数
# Windows : 大文字・小文字は区別されない PS C:\> $env:HOMEDRIVE C: PS C:\> $env:HomeDrive C: # Linux/Mac : 大文字・小文字は区別される PS /> $env:HOME /home/vagrant PS /> $env:Home
サイドバイサイドインストールのサポート
PowerShell CoreはポータブルなZipファイルのパッケージを持っており、各バージョンをサイドバイサイドでインストールすることが可能です。
WindowsでMSIインストーラーを使用してインストールした場合は過去バージョンのPowerShell Coreは削除されるインプレースアップデートとなります。
プログラム名の変更
PowerShell Coreのプログラム名がpowershell(.exe)
からpwsh(.exe)
に変更されました。
細かい話はこちらのエントリをご覧ください。
SSHベースのPowerShellリモート処理
PowerShell Core 6.0から通信の下回りにSSHを使用するリモート接続であるPowerShell Remoting over SSH
が導入されました。
細かい話はこちらのエントリをご覧ください。
ちなみに、LinuxやmacOSに対して従来のPSRPによるリモート接続も可能です。
既定のエンコーディングに関して
PowerShell Core 6.0からファイル主力に関わるエンコーディングが見直され、BOMなしUTF-8がデフォルトエンコーディングになりました。
細かい話はこちらのエントリをご覧ください。
&によるバックグラウンドジョブ実行
PowerShell Core 6.0からパイプラインの最後にアンパサンド(&
)を付けることでジョブを起動することができる様になりました。
細かい話はこちらのエントリをご覧ください。
Dockerサポート
PowerShell CoreはDocker上でも動作させることが可能です。
Docker Hubに公式なもの・非公式なもの合わせてイメージが公開されており、以下に一例を挙げておきます。
またGitHub上で各種OS用のDcokerfileも公開されています。
セマンティックバージョニング
PowerShell Core 6.0からセマンティックバージョニング 2.0と互換のあるバージョン番号が付く様になりました。
$PSVersionTable.PSVersion
の型が従来のSystem.Version
から新しいSystem.Management.Automation.SemanticVersion
に変更されています。
# PowerShell 5.1まで PS C:\> ($PSVersionTable.PSVersion).GetType().FullName System.Version # PowerShell 6.0 PS C:\> ($PSVersionTable.PSVersion).GetType().FullName System.Management.Automation.SemanticVersion
ただし、運用としては厳密にセマンティックバージョニングを適用する気は無く、半年ごとのリリースでマイナーバージョンを上げるものとなっています。
(次のリリースはPowerShell Core 6.1になる予定ですがこれには確実に破壊的変更も含まれるでしょう。この場合セマンティックバージョニングを厳密に適用するならPowerShell Core 7.0にしなければなりません。)
あくまでもバージョニングの体系を互換させるのと、アルファ、ベータリリースに対応するためだけに導入した感じです。
言語機能の更新
Unicode文字のエスケープ (#3958)
発端は#2751のIssueで、新しくUnicode文字をエスケープするための構文が追加されました。
`u{CodePoint}
の形式でエスケープすることが可能です。
Write-Host "`u{1F363} `u{1F37A}"
(通常のコンソールでは絵文字を表示できないためHyperを使っています)
エスケープキャラクター `e のサポート
ESC
をエスケープするために`e
がサポートされました。
ConvertTo-Jsonの更新 (#4318)
ConvertTo-Json
コマンドレットに-EnumsAsString
パラメーターが追加され、列挙型を文字列に変換する機能が追加されました。
# PowerShell 5.1 まで PS C:\> [System.Management.Automation.ActionPreference]::Ignore | ConvertTo-Json 4 # PowerShell Core 6.0 から PS C:\> [System.Management.Automation.ActionPreference]::Ignore | ConvertTo-Json -EnumsAsString "Ignore"
範囲演算子がChar型をサポートする様になりました (#5026)
範囲演算子(..
演算子)が拡張され、Int型だけでなくChar型も扱える様になりました。
細かい話はこちらのエントリをご覧ください。
読み取り専用であるべき変数が上書きされてしまう問題が修正されました
おそらく#2400の修正を指していると思われます。
[datetime]$HOME=1
の様な本来であれば上書きされてはいけない変数($HOME
)が上書きされない様に変更されています。
(従来のWindows PowerShellでは上記コードで$HOME
変数の内容が更新されてしまう。)
ドットソース演算子で読み込んだScript Cmdletの自動変数のスコープが修正されました (#4709)
もとのIssueは#4688。
pwsh(.exe) -File
パラメーターおよび、.
演算子からソースを読み込みScript Cmdletを呼び出した際の自動変数(元のIssueでは$PSScriptRoot
)が正しく設定されない不具合が修正されています。
-split演算子に'Singleline, Multiline'オプションを同時に指定した際の挙動が改善されました (#4721)
PowerShell 5.1までは-split演算子のオプションにSingleline, Multiline
を同時に指定するとパラメーターエラーとなりましたが、PowerShell 6.0ではこの制約が取り除かれました。
もともと内部で使わているC#のRegExクラスではSplitOptions.Singleline
とSplitOptions.Multiline
が併用可能であり、この制約を取り除いても挙動に問題はないと判断された様です。
PowerShellエンジンの更新
$PSVersionTable でサポートするプロパティが増えました
$PSVersionTable
に以下のプロパティが増えました。
PSEdition
: PowerShellのエディションGitCommitId
: ソースのコミットIDOS
: 実行OS情報Platform
: プラットフォーム名
$PSVersionTable から BuildVersion プロパティが削除されました
このBuildVersion
プロパティはWindowsのビルドと強く結びついているため廃止され、代わりにGitCommitId
プロパティが導入されています。
$PSVersionTable から ClrVersion プロパティが削除されました
PowerShell Coreの基盤である.NET Coreではこのプロパティの値が意味を成さなくなったため廃止されました。
OSを識別するための自動変数が追加されました
OSを識別するために以下の自動変数が追加されました。
$IsWindows
: Windowsの場合$True。$IsMacOS
: macOSの場合$True。$IsLinux
: Linuxの場合$True。
割とそのままですが、内部的には.NET CoreのSystem.Runtime.InteropServices.RuntimeInformationクラスの機能が使われており、
# $IsWindows [System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform([System.Runtime.InteropServices.OSPlatform]::Windows) # $IsMacOS [System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform([System.Runtime.InteropServices.OSPlatform]::OSX) # $IsLinux [System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform([System.Runtime.InteropServices.OSPlatform]::Linux)
といったコードと等価になります。
PowerShell起動時のバナーにGitCommitIdが追加されました
こちらは割とそのままで、pwsh(.exe)起動時のバナーにGitCommitId
(v6.0.1
の部分)が表示される様になりいちいち$PSVersionTable
の内容を参照しないでもバージョン確認ができる様に改善されています。
$PSHOMEディレクトリにJSONの設定ファイルが追加されました
$PSHOME
ディレクトリにpowershell.config.json
というJSONの設定ファイルが配置されPowerShell起動時の設定を記述することが出来る様になりました。
今のところWindowsのみ配置されており、初期状態では、
{"Microsoft.PowerShell:ExecutionPolicy":"RemoteSigned"}
とExecutionPolicyの既定値が設定されています。
そのほかのパラメーターについては順次ドキュメント化されていく(#5885)様ですが、まだまとまった資料はありません。
とりあえず現状ログ出力にかかわるパラメーターに関する記述だけ見つけました。
- LogIdentity
- LogChannels
- LogLevel
- LogKeywords
といった設定項目がある様です。
Windows EXEの実行中はパイプラインをブロックしません
こちらはどのIssueに対する改善か名言されていないのですが、Windowsに限らずネイティブコマンドをパイプラインする際に処理がブロックされる、レスポンスが悪いといった問題がいくつかあり、それに対する改善がPowerShell Core 6.0でされています。
COMコレクションの列挙が有効になりました (#4553)
元になるIssue(#3775)およびPull Request(#4553)を読む限りでは新機能ではなく互換性の保証の様に見受けられます。
現状の.NET CoreではCOMオブジェクトの列挙がサポートされていないためPowerShellで独自に実装してPowerShell 5.1との互換を取ったものの様です。
Windows PowerShellとの後方互換性について
以前ロードマップを公開した時にも述べましたが、PowerShell CoreにはWindows PowerShellとの互換性を持ちWindows PowerShellを置き換えていきたい展望があります。(現状は多くの互換性が切り捨てられています)
互換性保持の一つとしてWindows PowerShellのモジュールをPowerShell Coreから利用するためにWindowsPSModulePathというモジュールが用意されています。
このモジュールにはAdd-WindowsPSModulePath
コマンドが用意されており、これを実行するとPowerShell CoreのPSModulePath
環境変数にWindows PowerShellのモジュールパスを追加し、PowerShell CoreからWindows PowerShellのモジュールを参照・実行可能になります。
Install-Module WindowsPSModulePath -Force Add-WindowsPSModulePath
ただし、現状ではあくまでもパスを追加しているだけですので、実行されるモジュール側に互換性がなければ実行時エラーとなりますのでご注意ください。
コマンドレットの更新
ここから各種コマンドレットの更新情報について触れていきます。
新しいコマンドレット
新しく以下のコマンドレットが導入されました。
細かい説明は不要でしょう。
Get-Uptime
Remove-Alias
Remove-Service
Webコマンドレット
PowerShell Core 6.0では基盤が.NET Coreになったこともあり、Web Cmdletsの基盤がWebRequestクラスからHttpClientクラスに代わっており、中身は完全に作り替えられています。
これに伴いHTTP/HTTPSアクセスに係る古い仕様を取り除き新しい仕組みに対応できる様に修正されています。
これらの修正についてほとんどテキサスのMVPであるMark Krausさんが直しており、正直公式ドキュメントより彼のブログ等を見た方が良いでしょう。
Get-PowerShellBlog: PowerShell Core Web Cmdlets in Depth (Part 1)
Get-PowerShellBlog: PowerShell Core Web Cmdlets in Depth (Part 2)
Get-PowerShellBlog: PowerShell Core Web Cmdlets in Depth (Part 3)
JSONコマンドレット
JSON関連のコマンドレットはPowerShell Coreで内部的にJson.NETを使用する様に変更されています。
PowerShell Core 6.0ではこの変更に起因する修正や新機能の導入がされています。
また、ドキュメント化されていない部分で細かな挙動にWindows PowerShellとの差異が発生している様です。
ConvertFrom-Json
に戻り値をHashTable
にして返す-AsHashtable
パラメーターが追加されました (#5043)
通常 ConvertFrom-Json
はPSCustomObject
を返しますが、-AsHashtable
パラメーターを指定した場合はHashTable
を返します。
# 通常は PSCustomObjectを返す PS C:\> '{"a" :', '"x"}' | ConvertFrom-Json | Get-Member TypeName: System.Management.Automation.PSCustomObject (後略) # -AsHashtableをつけるとHashtableを返す PS C:\> '{"a" :', '"x"}' | ConvertFrom-Json -AsHashtable | Get-Member TypeName: System.Collections.Hashtable (後略)
ConvertTo-Json
の出力フォーマットが改善されました (#2787)
PowerShell Core 6.0で出力されるJSONはWindows PowerShellよりコンパクトになっています。
基本的には4タブから2タブになったのとクローズブレース(}
など)の付き方が変更されています。
# PowerShell 5.1まで PS C:\> [ordered]@{'one' = 1; 'two' = @{'value' = 2}} | ConvertTo-Json { "one": 1, "two": { "value": 2 } } # PowerShell Core 6.0 PS C:\> [ordered]@{'one' = 1; 'two' = @{'value' = 2}} | ConvertTo-Json { "one": 1, "two": { "value": 2 } }
ConvertTo-Json
でNewtonsoft.Json.Linq.JObject
型のオブジェクトのシリアル化がサポートされました (#5141)
Json.NET対応の一環での機能改善の様です。
複数行にかかわるデータに対するConvertFrom-Json
の挙動が改善されました (#3823)
元のIssueを見てもいまいち理解しきれない部分があったのですが、
Get-Content .\sample.json | ConvertFrom-Json
の様な場合でGet-Content
の結果であるstring[]
の入力を正しく解釈できないことがありそれを改善した様です。
System.Array
に定義されていたCount
エイリアスプロパティが削除され、JSONの配列を扱うケースで不要なCount
プロパティが付かない様に改善されました (#3231)
例えば
(1,,"2") | ConvertTo-Json
といった例の場合、Windows PowerShellでは
# PowerShell 5.1まで PS C:\> (1,,"2") | ConvertTo-Json [ 1, { "value": [ "2" ], "Count": 1 } ]
と配列のCount
プロパティが出力されてしまいますが、PowerShell Core 6.0からは
# PowerShell Core 6.0 PS C:\> (1,,"2") | ConvertTo-Json [ 1, [ "2" ] ]
の様にCount
プロパティは付かない様に改善されています。
CSVコマンドレット
Import-Csv
とConvertFrom-Csv
でPSTypeName
のサポートが追加されました (#5389)
これはExport-Csv
やConvertTo-CSV
で付与されるPSTypName(#TYPE [型名]
の部分)がImport-Csv
やConvertFrom-Csv
で正しく反映されかった点の改善となります。
Import-Csv
の行区切りにCRLF
だけでなくCR
、LF
が使える様になりました (#5363)
クロスプラットフォーム化対応での改善です。
Export-Csv
やConvertTo-Csv
で-NoTypeInformation
を既定値に変更しました (#5164)
こちらは発端となったIssue(#5131)を見ればわかりますが、CSV出力する際にPSTypeNameのヘッダが出力されるのが煩わしいという声が多かったため改善されました。
サービスのコマンドレット
Get-Service
などの戻り値であるServiceController
クラスのプロパティにUserName
、Description
、DelayedAutoStart
、BinaryPathName
、StartupType
が追加されました (#4907)
UserVoiceのこちらの要望に対する対応として機能追加されました。
ただしWindows PowerShellにバックポートされる見込みは低いでしょう...
Set-Service
に資格情報を設定するための-Credential
パラメーターが追加されました (#4844)
New-Service
には-Credential
パラメーターがあるのにSet-Service
にはなかったことに対する改善です。
その他のコマンドレット
結構大きな変更もあるのですが本エントリでは公式ドキュメントの内容を軽く補足する程度にとどめておきます。
Get-ChildItem
にシンボリックリンクを追跡するための-FollowSymlink
パラメーターが追加されました (#4020)
加えてシンボリックリンクにより一度走査したディレクトリを多重に走査しないかチェックする機能がサポートされています。
Add-Type
の-Language
にCSharpVersion7
が追加されました (#3933)
余談ですが、今後の方針としてAdd-Type
で使える言語からJScript
が削除されC#のバージョン指定も簡素化される予定です。
Future of Add-Type · Issue #5725 · PowerShell/PowerShell · GitHub
Cleanup Add-Type by iSazonov · Pull Request #5829 · PowerShell/PowerShell · GitHub
サポートされないAPIを使っていたためMicrosoft.PowerShell.LocalAccounts
モジュールは削除されました (#4302)
「サポートされない」の意味に関して.NET CoreとしてのサポートなのかWindowsのサポートなのかは不明です。
サポートされないAPIを使っていたためMicrosoft.PowerShell.Diagnostics
モジュールの*-Countr
コマンドレットは削除されました (#4303)
「サポートされない」の意味に関して.NET CoreとしてのサポートなのかWindowsのサポートなのかは不明です。
Split-Path
に-Extension
、-LeafBase
パラメーターが追加されました (#2721)
-Extension
は拡張子を、-LeafBase
は拡張子なしのファイル名を取得するためのスイッチパラメーターです。
PS C:\> Split-Path C:\Temp\sample.txt C:\Temp PS C:\> Split-Path C:\Temp\sample.txt -Extension .txt PS C:\> Split-Path C:\Temp\sample.txt -LeafBase sample
Sort-Object
に-Top
と-Bottom
パラメーターが追加されました
概ね以下のコードと等価になります。
# PowerShell 5.1まで 1,3,2,5,4 | Sort-Object | Select-Object -First 2 1,3,2,5,4 | Sort-Object | Select-Object -Last 2 # PowerShell 6.0より 1,3,2,5,4 | Sort-Object -Top 2 1,3,2,5,4 | Sort-Object -Bottom 2
Get-Process
などの戻り値のSystem.Diagnostics.Process
クラスにコードプロパティParent
が追加され、該当プロセスの親プロセスを取得できる様になりました (#2850)
地味ですが便利な改善だと思います。
# PowerShell Core 6.0 から親プロセスの取得が容易に PS C:\> (Get-Process -id $PID) NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName ------ ----- ----- ------ -- -- ----------- 69 43.47 80.04 2.16 2484 1 pwsh PS C:\> (Get-Process -id $PID).Parent NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName ------ ----- ----- ------ -- -- ----------- 191 110.25 119.97 1,865.97 7500 1 explorer
Get-Process
の結果を表示する際のメモリ使用量に関する列がKB単位からMB単位に変更されました
こちらは下図を見てもらうのが手っ取り早いでしょう。
Out-String
に-NoNewLine
パラメーターが追加されました (#5056)
こちらは割とそのままの改善です。
-NoNewline
をつけた時は改行コードがないことが見て取れます。
PS C:\> 'a' | Out-String | Format-Hex 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00000000 61 0D 0A a.. PS C:\> 'a' | Out-String -NoNewline | Format-Hex 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 00000000 61 a
Move-Item
の-Include
、-Exclude
、-Filter
パラメーターの挙動が改善されました (#3878)
レジストリに対するRemove-Item
で*
が使える様になりました (#4866)
レジストリのパスには*
が使用可能なのですが、PowerShellでは*
はワイルドカードとして扱われてしまうためRemove-Item
が正しく動作しないケースがあり、PowerShell Core 6.0でこれが修正されています。
Get-Credential
に-Title
パラメーターが追加されました
PowerShell Coreで認証ダイアログがCUI化したことによる機能追加になります。
Test-Connection
に-TimeOut
パラメーターが追加されました (#2492)
ただし、Test-Connection
はまだ正式にPowerShell Coreに組み込まれていません...(#5328)
Get-AuthenticodeSignature
コマンドレットでTimeStamperCertificate
プロパティが取得できなかったのが改善されました (#4061)
こちらは新機能というよりはベータ版で発生した不具合の改善ぽいです。
Get-Help
から-ShowWindow
パラメータが削除されました (#4903)
.NET CoreではGUIサポートがないための変更です。
ただ、今後の方針としてConsole GUIおよびそのためのライブラリの導入を検討(#3957)しているのでいずれ復活するかも...しれません。
Get-Content
で-Delimiter
を指定した際にデリミタ自身が残ってしまう不具合が解消されました (#3706)
こちらは以下の例を見てもらうのが手っ取り早いでしょう。
# PowerShell 5.1まではデリミタ "-" が結果に残ってしまう。 PS C:\> "00-01-02-03-04-05-06" > .\mac.txt PS C:\> Get-Content .\mac.txt -Delimiter "-" 00- 01- 02- 03- 04- 05- 06 # PowerShell 6.0からこの挙動は改善されます PS C:\> "00-01-02-03-04-05-06" > .\mac.txt PS C:\> Get-Content .\mac.txt -Delimiter "-" 00 01 02 03 04 05 06
ConvertTo-HTML
に-Meta
、-Charset
、-Transitional
パラメーターが追加されました (#4184)
Get-ComputerInfo
の実行結果にWindowsUBR
、WindowsVersion
プロパティが追加されました
なお、現状Get-ComputerInfo
はWindowsでのみ利用可能です。
Get-Verb
に-Group
パラメーターが追加されました
指定したグループだけを抽出可能になっています。
PS C:\> Get-Verb -Group Other Verb AliasPrefix Group Description ---- ----------- ----- ----------- Use u Other Uses or includes a resource to do something
New-FileCatalog
、Test-FileCatalog
で-WhatIf
、-Confirm
パラメーターが動作しなかったのが改善されました (#3074)
内部的にはShouldProcess
のサポートが正しく実装されました。
Start-Process
に-WhatIf
パラメーターが追加されました (#4735)
併せて-Confirm
パラメーターも増えています。
多くの既存コマンドレットのパラメーターにValidateNotNullOrEmpty
属性を追加しています
おそらく#2672の改善を指している様です。
引数なしのcd
がcd ~
として動作する様になりました (#1534)
これはUnixのcd
コマンドの挙動に合わせた変更となります。
テレメトリ
現在PowerShell Coreではテレメトリとして以下の情報を収集しています。
- OSのプラットフォーム(
$PSVersionTable.OSDescription
) - PowerShellの正確なバージョン(
$PSVersionTable.GitCommitId
)
これをオプトアウトするには$PSHome\DELETE_ME_TO_DISABLE_CONSOLEHOST_TELEMETRY
ファイルを削除する必要があります。
ただ、この方式はAppImage版のPowerShell Coreなど$PSHOME
が読み取り専用となっているシステムでは使用できないため、オプトアウトの方法をファイルの削除から環境変数の設定に変更する計画が立てられており、PowerShell Core 6.0.2で採用される見込みです。(#6063)
最後に
とりあえずこんな感じです。
ボリュームがありまとめるのも一苦労でした。