PowerShell Core 6.2 新機能・破壊的変更まとめ

PowerShell Core

しばたです。

先日リリースされたPowerShell Core 6.2の新機能および破壊的変更に関するドキュメントが更新されたのでいつも通り簡単に解説していきます。
(過去バージョンのPowerShell Coreについてはクラスメソッド入社前に個人ブログでまとめています。(6.1新機能6.0新機能6.0破壊的変更))

今回はPowerShell Teamも忙しかったのかドキュメントの構成がかなり雑で「機能修正と言いってるけどそれ新機能でしょ?」といった感じの修正がそこそこあります...
残念ながら元のドキュメントがあまり整理されていないのですが本記事もこの構成に従う形で進めていきます。

PowerShell Core 6.2 新機能

PowerShell Core 6.2では以下の新機能が導入されています。

Experimental Features

PowerShell Core 6.2から新規に導入された試験的な機能(Experimental Feature)については以前にDevelopers.IOで記事にしていますのでこちらをご覧ください。

破壊的変更

PowerShell Core 6.2では以下の破壊的変更が加えられています。

以降の内容で各タイトルにある #9069 といった番号はPowerShellのGitHubでのIssue/Pull Reqestの番号となります。

Fix -NoEnumerate behavior in Write-Output to be consistent with Windows PowerShell. (#9069)

こちらはちょっと問題の経緯がややこしいのですが、PowerShell Coreのどこかの修正(#2038とされている)で、Write-Output -NoEnumerateを指定した際の挙動が期待した動作にならない問題がありました。(#5955)

# 期待される挙動 (Windows PowerShellの挙動でもある)
C:\> (Write-Output -NoEnumerate 1, 2).GetType().Name
Object[]
C:\> (Write-Output -NoEnumerate ([System.Collections.ArrayList] (1, 2))).GetType().Name
ArrayList

# PowerSHell Core 6.0 - 6.1の挙動
C:\> (Write-Output -NoEnumerate 1, 2).GetType().Name
PSObject[]
C:\> (Write-Output -NoEnumerate ([System.Collections.ArrayList] (1, 2))).GetType().Name
PSObject[]

この挙動を改善するためにWrite-Output-InputObjectパラメーターの型をPSObject[]からPSObjectに変更しています。

Add -Stable to Sort-Object and related tests (#7862)

Sort-Objectに安定ソートを行うための-Stableパラメーターが追加されました。

Improve Start-Sleep cmdlet to accept fractional seconds (#8537)

Start-Sleep-Secondsパラメーターの型がintからdoubleに変わり小数値を受け入れることができる様になりました。

Change hashtable to use OrdinalIgnoreCase to be case-insensitive in all Cultures

Linux環境でLANG環境変数にC.UTF-8(InvariantCultureなコード)を指定された場合にハッシュテーブルのプロパティ参照で大文字・小文字が区別されてしまう問題(#7761)があり、これに対応するためにカルチャに依存しない方式(OrdinalIgnoreCase)で大文字・小文字の区別をしない様にする修正を施しています。

Fix LiteralPath in Import-Csv to bind to Get-ChildItem output (#8277)

Get-ChildItem | Import-Csv

といったコマンドを実行可能にするためにImport-Csv-LiteralPathパラメーターの挙動を変更しています。

No longer skips a column without name if double quote delimiter is used in Import-Csv (#7899)

デリミタにダブルクオート(")が指定されており、ヘッダ行に空文字となる列がある場合にその列が一切インポートされない不具合(#7110)に対する修正が入っています。

Debug parameter now sets $DebugPreference to Continue instead of Inquire (#8195)

-Debugパラメーターの挙動に対するこちらの提案(#7122)の内容を受けて、-Debugパラメーターが指定された際の$DebugPreferenceの既定値をInquireからContinueに変更しています。
細かい話は上記提案およびPull Requestをご覧ください。

Honor -OutputFormat if specified in non-interactive, redirected, encoded command used with pwsh (#8115)

pwsh(.exe)の引数で-NonInteractive-OutputFormatを併用した際に指定した-OutputFormatにならない不具合が解消されています。
(こちら手元の環境で状況再現をしようとしたのですがうまくいきませんでした...)

Load assembly from module base path before trying to load from the GAC (#8073)

バイナリモジュールで参照するアセンブリがBasePathおよびGACにある場合にGACにあるアセンブリを先読みしてしまう問題を解消し、BasePathにあるアセンブリを先にロードする様に修正されています。

Remove tilde from Linux preview packages (#8244)

Linuxパッケージ名のバージョン区切りに含まれる~の使用を廃止する修正が入っています。
バージョンのフォーマットが major.minor.patch[~previewName[Number]] から major.minor.patch[-previewName[Number]] に変更されています。

Move processing of -WorkingDirectory before processing of profiles (#8079)

pwsh(.exe)-WorkingDirectoryパラメーターの指定が反映されるタイミングをプロファイルの実行後から実行前に変更しています。

Do not add PATHEXT environment variable on Unix (#7697)

非Windows環境ではPATHEXT環境変数を追加しない様になりました。

既知の問題

Remoting on Windows IOT ARM platforms has an issue loading modules. See (#8053)

こちらはタイトルにある通り#8053をご覧ください。
PowerShell Core on Windows IOT ARM32 on Raspberry Piな環境にEnter-PSSessionで接続できない不具合だそうです。

プログラム修正など

以下各種バグフィックスなどの修正について解説していきます。
最初に触れた通り「どう見ても新機能でしょコレ?」といった修正もあります。

Enable case-insensitive tab completion for files and folders on case-sensitive filesystem (#8128)

Linuxなど大文字・小文字を区別するファイルシステム上でのタブ補完によるファイル・ディレクトリ名の列挙が大文字・小文字を区別しない様になりました。
こちらはIssueとしてはかなり昔からあったのですが、.NET Core 2.1での機能追加によりやっと対応できた模様です。

Make PSVersionInfo.PSVersion and PSVersionInfo.PSEdition public (#8054)

バイナリモジュール開発者向けにPSVersionInfoクラスとPSEditionプロパティのアクセシビリティがinternalからpublicに変更されました。

Add Type Inference for $_ / $PSItem in catch{ } blocks (#8020)

これは地味に嬉しい改善で、catch{ }ブロック内で使う$_自動変数で型推論ができる様になりました。
内部的にはErrorRecord<TException>型として扱う様にしてタブ補完等できる様にしています。

Fix static method invocation type inference (#8018)

クラスの静的メソッドの結果に対する型推論が改善されています。
私も細かいところを把握できていないため、詳細は元のプルリクエスト(#8018)をご覧ください。

ざっと試した感じ、

[powershell]::Create().<Tab入力>

の様な補完が利く様になっていました。

Create inferred types for Select-Object, Group-Object, PSObject and Hashtable (#7231)

Select-ObjectGroup-ObjectでPSCustomObjectやHashtableのプロパティを推論できる様にするためにPSInferredPropertyという内部プロパティを追加しています。
この対応により、例えば、

@{ Name = "Staffan"; Size = 3 } | Select-Object -Property <Tab入力>

といった入力をした際にHashtableのプロパティ(NameSize)が補完できる様になっています。

Support calling method with ByRef-like type parameters (#7721)

ByRef-likeな型(SpanReadOnlySpanなど)を引数に持つメソッドの実行に対応しています。

# .NET CoreではIsPathRootedはSystem.ReadOnlySpan[char]が引数になるものがある
# * static bool IsPathRooted(System.ReadOnlySpan[char] path)
#
# 上記対応によりこの様な呼び出しが正しく動作する
$charArray = "F:\".ToCharArray()
[System.IO.Path]::IsPathRooted($charArray)

Handle the case where the Windows PowerShell module path is already in the environment's PSModulePath (#7727)

こちらはWindows環境においてPSModulePath環境変数に設定されるパスの順序をPowerShell Coreを優先させる変更となります。

元々の問題(#7679)として、PowerShell CoreからWindows PowerShell環境にリモート接続した際にWindows PowerShell側のモジュールが先に読み込まれてエラーになる事象が発生したためこれに対処するための対応となります。

Enable SecureString cmdlets for non-Windows by storing the plain text (#9199)

こちらは以前Developers.IOで触れた記事の内容となります。

Improve error message on non-Windows when importing clixml with securestring (#7997)

こちらは元のプルリクエスト(#7997)に記載されている通り、Import-ClixmlでSecureStringが含まれるCLIXMLを読み込んだ際のエラーメッセージをよりわかりやすくする改善となります。

Adding parameter ReplyTo to Send-MailMessage (#8727)

Send-MailMessageコマンドレットに-ReplyToパラメーターが追加されました。

Add Obsolete message to Send-MailMessage (#9178)

素のSMTPによるメール送信はセキュリティ的によろしくないということでSend-MailMessageは非推奨となりました。
こちらは元々.NET CoreでSmtpClientの使用が非推奨になったことを受けての対応となります。(Send-MailMessageは内部でSmtpClientを使っています)

*DE0005: SmtpClient shouldn't be used

そして、まだプルリク内で議論中ですが以下のRFCで詳細を確認できます。

PowerShell Core 6.2ではSend-MailMessageを利用すると以下の警告メッセージが表示される様になっています。

WARNING: The command 'Send-MailMessage' is obsolete. This cmdlet does not guarantee secure connections to SMTP servers. While there is no immediate replacement available in PowerShell, we recommend you do not use Send-MailMessage at this time. See https://aka.ms/SendMailMessage for more information.

Fix Restart-Computer to work on localhost when WinRM is not present (#9160)

WinPEといったWinRMサービスが存在しない環境でRestart-Computerがエラーになるのが修正されています。

Make Start-Job throw terminating error when PowerShell is being hosted (#9128)

独自プログラム内でホストされているPowerShellからStart-Jobを呼び出すとエラーになるのが修正されています。

Add C# style type accelerators and suffixes for ushort, uint, ulong, and short literals (#7813)

ushortuintulongshort型に対して以下の型アクセラレーターとサフィックスが追加されました。

型アクセラレーター サフィックス
ushort [ushort] us
uint [uint] u
ulong [ulong] u
short [short] s

ドキュメントは以下で更新されています。

Correctly Report impact level when SupportsShouldProcess is not set to 'true' (#8209)

これまで各コマンドレットに設定されているConfirmImpactがすべてMediumとなっておりあまり役に立たない現状を改善するため、SupportsShouldProcess = $falseとなっているコマンドレットのConfirmImpactNoneにするのと、明らかに影響度の低いコマンドレットである

  • New-PSDrive
  • New-Alias
  • New-TemporaryFile
  • Update-TypeData
  • Update-FormatData
  • New-Variable
  • ForEach-Object
  • New-ModuleManifest
  • Receive-PSSession

についてはConfirmImpact = Lowにする変更を加えています。

Fix Request Charset Issues in Web Cmdlets (#8742)

Invoke-RestMethodなどのWeb CmdletsにおいてContent Typeにキャラクタセット指定が含まれている場合に指定のキャラクタセットを反映させる様に修正が入っています。

Fix Expect 100-continue issue with Web Cmdlets (#8679)

Web CmdletsにおいてExceptヘッダが無効にされていたのが改善されています。

Fix file blocking issue with web cmdlets (#7676)

Web Cmdletsにおいてファイルをマルチパートアップロードしようとするとファイルのオープンエラーとなってしまう件に対応しています。
(単純にファイルを共有オープンすることで対処しています)

Fix code page parsing issue in Invoke-RestMethod (#8694)

この件の元となるIssue(#8510)は「Invoke-RestMethodがエンコーディングがCP936の中国語サイトで動作しない」で、それに対処したとされているのですが、プルリクエストの内容を見る限りエラー時の詳細メッセージを表示する様にしただけで特に対処していない様に見受けられます...

Refactor ConvertTo-Json to expose JsonObject.ConvertToJson as a public API (#8682)

JSON Cmdlets内部で使われているJsonObjectのうちConvertFromJsonメソッドはPublicに公開されているもののConvertToJsonは非公開となっているのは不便だということでConvertToJsonメソッドも公開される様になりました。

Add configurable maximum depth in ConvertFrom-Json with -Depth (#8199)

ConvertFrom-Jsonコマンドレットで対応可能なJSONのネストの深さは1024固定だったのですが、この深さを-Depthパラメーターで設定できる様になりました。
既定値は1024です。

Add EscapeHandling parameter in ConvertTo-Json cmdlet (#7775)

ConvertTo-Json<>&'"のエスケープが行われる様に改善されました。
これはWindows PowerShellでの挙動およびRFC 8259に合わせる変更となります。

Add -CustomPipeName to pwsh and Enter-PSHostProcess (#8889)

名前付きパイプを使って別のPowerShellプロセスに接続するために、pwsh(.exe)の引数とEnter-PSHostProcessCustomPipeNameパラメーターが追加されました。

  • 接続される側
# pwshの引数でcustompipenameを設定
pwsh -custompipename mypipe
  • 接続する側
# Enter-PSHostProcessのCustomPipeNameパラメーターでパイプ名を指定
Enter-PSHostProcess -CustomPipeName mypipe

Enable creating relative symbolic links on Windows with New-Item (#8783)

New-Itemでシンボリックリンクを作る際に相対パスでの指定ができる様に修正がされています。

Allow Windows users in developer mode to create symlinks without elevation (#8534)

Windows環境においてWindows 10 Creators Update(Build 14972)以降であれば管理者権限無しでシンボリックリンクを作成できるのですが、これにPowerShell側が対応できていなかったのが改善されました。

Enable Write-Information to accept $null (#8774)

Write-Informationの引数に$nullが指定されてもエラーとならない様になりました。

Fix Get-Help for advanced functions with MAML help content (#8353)

MAMLで定義された高度な関数のヘルプが表示されない問題がこの対応により解消しています。
具体的にはMicrosoft.PowerShell.Archiveモジュールのヘルプ表示が改善されたそうです。

Fix Get-Help PSTypeName issue with -Parameter when only one parameter is declared (#8754)

Get-Helpで表示されるパラメーターの型の表示を改善した、そうなのですが、手元の環境で試した限りでは改善した様に見えませんでした...

Token calculation fix for Get-Help executed on ScriptBlock for comment help. (#8238)

スクリプトブロック、またはスクリプトブロック内で動的に作成された関数に対してヘルプ情報を取得できる改善がされています。

Change Get-Help cmdlet -Parameter parameter so it accepts string arrays (#8454)

Get-Help-Parameterパラメーターが複数の文字列を受け取れる様に改善されました。

Get-Help -Name Get-Command -Parameter Verb, Noun

Resolve PAGER if its path contains spaces (#8571)

PAGER環境変数にスペースが含まれる場合にヘルプのページングが正しく動作しない件が修正されています。

Add prompt to the use of less in the function 'help' to instruct user how to quit (#7998)

非Windows環境ではGet-Helpのページングにlessがデフォルトで使われるのですが、これまでは引数無しでlessが呼ばれていたものがless -Ps(後略)と引数が付けられ終了方法を促すメッセージを表示する様に改善されています。

Add support enum and char types in Format-Hex cmdlet (#8191)

Format-Hexcharenumがサポートされる様になりました。

Remove ShouldProcess from Format-Hex (#8178)

Format-HexShouldProcess = falseに変更されました。

Add new Offset and Count parameters to Format-Hex and refactor the cmdlet (#7877)

Format-Hex-Offset-Countパラメーターが追加されました。

Make scriptblock based calculated properties work again in ConvertTo-Html (#8427)

ConvertTo-Html-PropertyパラメーターがSelect-Objectのそれの様にHashtableを引き受けることができる様に拡張されました。

Allow 'name' as an alias key for 'label' in ConvertTo-Html, allow the 'width' entry to be an integer (#8426)

前項の修正に加えて、namelabelのエイリアスとする対応と、列幅をWidthで指定できる様に機能拡張されています。

Add cmdlet Join-String for creating text from pipeline input (#7660)

文字列を結合するためのJoin-Stringコマンドレットが追加されました。
詳細はドキュメントをご覧ください。

C:\> 1..3 | Join-String -OutputPrefix "A " -OutputSuffix " B" -Separator "," -SingleQuote
A '1','2','3' B

Change Clear-Host back to using $RAWUI and clear to work over remoting (#8609)

Clear-Hostコマンドレットが非Windows環境に対してリモート接続した際に正しく動作しない不具合が解消されています。

help function shouldn't use pager for AliasHelpInfo (#8552)

help関数でエイリアス情報を表示する際に表示が崩れてしまう不具合が解消されています。

Add -UseMinimalHeader to Start-Transcript to minimize transcript header (#8402)

Start-Transcriptで作成されるテキストファイルのヘッダ情報を最小限にする-UseMinimalHeaderパラメーターが追加されました。

  • 通常のTranscriptヘッダ
**********************
PowerShell transcript start
Start time: 20190423144037
Username: User01
RunAs User: User01
Configuration Name: 
Machine: PC001 (Microsoft Windows NT 10.0.17763.0)
Host Application: C:\Program Files\PowerShell\6\pwsh.dll
Process ID: 17660
PSVersion: 6.1.3
PSEdition: Core
GitCommitId: 6.1.3
OS: Microsoft Windows 10.0.17763 
Platform: Win32NT
PSCompatibleVersions: 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.10032.0, 6.1.3
PSRemotingProtocolVersion: 2.3
SerializationVersion: 1.1.0.1
WSManStackVersion: 3.0
**********************
  • -UseMinimalHeaderパラメーター使用時
**********************
PowerShell transcript start
Start time: 20190423144029
**********************

Expose all cmdlets from PSDiagnostics if logman.exe is available (#8366)

PSDiagnosticsモジュールのコマンドレットが正しく公開されていない不具合が解消されています。

Remove Persist parameter from New-PSDrive on non-Windows platform (#8291)

プラットフォームとして対応できないため、非Windows環境ではNew-PSDrive-Persistパラメーターが削除されました。

Add support for cd + (#7206)

以前のバージョンでcd -に対応したのに加えて、PowerShell Core 6.2ではcd +にも対応しました。

Enable Set-Location -LiteralPath to work with folders named - and + (#8089)

前項でcd +cd -に対応した件で、+-という名称のフォルダが存在する場合に正しく動作しない不具合が解消されています。

Test-Path returns $false when given an empty or $null path value (#8080)

Test-Path ' 'といったスペースや空文字に対するTest-Path$trueを返してしまう挙動が改善されています。

Allow dynamic parameter to be returned even if path does not match any provider (#7957)

Get-Content C:\NonExistentWildcard*.txt -Rawの様に-Raw-Delimiterパラメーターを併用してワイルドカード指定でGet-Contentを呼び出し、該当ファイルが無い場合のエラーメッセージが不適切なのが解消されています。

Support Get-PSHostProcessInfo and Enter-PSHostProcess on Unix platforms (#8232)

Get-PSHostProcessInfoEnter-PSHostProcessがLinuxおよびmacOSで使用できる様になっています。
LinuxおよびmacOSでも名前付きパイプを使い別PowerShellプロセスにアタッチする形となります。

Reduce allocations in Get-Content cmdlet (#8103)

Get-Contentの内部処理を見直しメモリ使用量を抑える修正が入っています。
具体的にどの程度改善されたか数値化はされていませんが、ざっくりSpanを使う対応が入っているのと、コンテンツ内の文字検索にボイヤー-ムーア文字列検索アルゴリズムを採用する様になっておりそれなりの効果はあるのではないかと思われます。

Enable Add-Content to share read access with other tools while writing content (#8091)

Add-Contentでファイルを開く際のモードをFileShare.WriteからFileShare.ReadWriteに変更し、他のプロセス(tailなど)がファイルを読み込んでいる最中にAdd-Contentを呼び出してもエラーとならない様に改善されています。

Get/Add-Content throws improved error when targeting a container (#7823)

ディレクトリに対してGet-ContentAdd-Contentを呼び出した際のエラーメッセージがよりわかりやすいものに改善されています。

Add -Name, -NoUserOverrides and -ListAvailable parameters to Get-Culture cmdlet (#7702)

Get-Culture-Name-NoUserOverrides-ListAvailableパラメーターを追加されました。

Add unified attribute for completion for Encoding parameter. (#7732)

-Encodingパラメーターを使うコマンドレットの-Encodingパラメーターの記述を内部的に統一しています。
あくまで内部処理の変更で利用者には影響はありません。

Allow numeric Ids and name of registered code pages in Encoding parameters (#7636)

-Encodingパラメーターを使うコマンドレットの-Encodingパラメーターにコードページの値を指定できる様に機能が拡張されました。

# コードページの数値指定
Set-Content -Path .\test1.txt -Value "я" -Encoding 1251

# コードページ名での指定
Set-Content -Path .\test2.txt -Value "я" -Encoding "windows-1251"

Fix Rename-Item -Path with wildcard char (#7398)

ワイルドカード文字を含む名称に対するリネーム処理でエラーがでる場合があるのが改善されています。

When using Start-Transcript and file exists, empty file rather than deleting (#8131)

Start-Transcriptで既存のファイルを上書きする際にこれまでは既存のファイルを削除して新しいファイルを書き直す挙動だったが空文字列で上書きする様に内部処理が変更されています。
これは削除する際にアクセスエラーになる場合があるのに対処するための対応だそうです。

Make Add-Type open source files with FileAccess.Read and FileShare.Read explicitly (#7915)

Add-Typeでソースファイルを読み込む際に共有モードでファイルをオープンする様に改善されています。

Fix Enter-PSSession -ContainerId for the latest Windows (#7883)

Enter-PSSession -ContainerId $idでコンテナにPowerShell Directに接続しようとするとエラーになる件が解消されています。

この件に関しては以前私の個人ブログで少し触れていますので以下の記事を参照してください。

Ensure NestedModules property gets populated by Test-ModuleManifest (#7859)

Test-ModuleManifestでNestedMoudleの情報が正しく取れない不具合が解消されています。

Add %F case to Get-Date -UFormat (#7630)

Get-Date-UFormatパラメーターの書式で%F(%Y-%m-%dと同等)が使える様になりました。

C:\> Get-Date -UFormat '%F'
2019-04-24

Fix Set-Service -Status Stopped to stop services with dependencies (#5525)

依存関係のあるサービスに対してSet-Service -Status Stoppedを呼び出してサービスを止めようとするとエラーになる不具合が解消されています。

最後に

以上です。
更新の多さもありますが、内容が整理されていないこともありとても疲れました...

英語は全然得意ではないのですがこれはちょっと元のドキュメントに対して改善のフィードバックを上げないとダメかなぁと考えています。