tech.guitarrapc.cóm

Technical updates

パイプラインの処理を途中で打ち切る方法のPowerShell版

PowerShell の最大の特徴と言われた時に、おそらく掲げるべきはパイプラインだと思います。

それが、cmd や Linux/Unix シェルにおけるパイプラインと異なる挙動だったり、オブジェクトを伝搬するという性質も含めて良くも悪くも PowerShell を PowerShell 足らしめているのはパイプラインかなと。

さて、パイプラインが特徴の PowerShell ですが、問題がいくつかあります。その一つが、以下の記事にあるパイプラインの中断処理。

d.hatena.ne.jp

https://winscript.jp/powershell/308winscript.jp

今回は少しその辺をみてみましょう。

目次

StopUpstreamCommandsException

先に結論だけ書くと、Internal なクラスであっても System.Management.Automation.StopUpstreamCommandsException が一番楽ちんでしょう。

ということで、PowerShell版で書くなら雑にこんな感じで。あえて New-Object ではなく Add-Type しています。

gist.github.com

中で System.Collections.Queue を使ってるのはそれほどの意味はありません。入力されたオブジェクトをいいように扱うためです。なので、カウンタ変数を用意してでもお好きなようにやればいいと思います。

この方式なら、Cmdlet でも同様なので好きなように扱えるのもいいでしょう。

はじめは、ReferenceSource見て自分で実装するのでいいんじゃないかなと思いましたが、当然ながら面倒さが上回ったのでやめました。

仕様変更あったらどうしよう

そもそもその場合は、Select-Object も仕様変わります。もはやその時点で一緒かなと。

Select -Fist 1 の GetSteppablePipeline() でも PowerShell スクリプトならいいのですが、Cmdlet から PowerShell 関数呼ぶの悲しさしかないですし仕方ないのかなという妥協もあります。

Connect

ちなみにこの Internal Class なやつを Public にしてというリクエストはあります。ワークアラウンドに do{}while()Select-Object -First 1 の例もあります。

Microsoft Connect is Retired - Collaborate | Microsoft Docs

すでにPowerShell のフィードバックは、UserVoice に移っており、同フィードバックも転載されています。

Please feel free to provide feedback or file bugs here.
  • 20 votes
  • 1 comment

Enable users to stop pipeline/making StopUpstreamCommandsException public

Votes from Connect: 24

Original Date Submitted: 10/25/2012 1:54:42 PM

Description:
********Contact Information********
Handle: TobiasWeltner
Site Name: PowerShell
Feedback ID: 768650
***************************************

Frequency: Always Happens
Regression: No, this is new to the most ...

windowsserver.uservoice.com

なので、Stop-Pipeline Cmdlet や StopUpstreamCommandsException のパブリック化がこれに基づきされてほしいですね。Vote しましょう。

End が実行されないのも、フィードバックすればいいと思います。End で何かしらするのはリソース破棄以外にもあり得るので、実際あってほしいでしょう。PowerShell Team の書くスクリプトの中にも Process{} 句で配列にまとめて End{} 句で出力するパターンもあるので。

余談

こういったパイプラインの制限というか、まだまだいけてないシーンはあって、たとえば foreach(){} | .... もそれです。

Please feel free to provide feedback or file bugs here.
  • 6 votes
  • 1 comment

Make the foreach statement work with a pipeline

Votes from Connect: 29

Original Date Submitted: 7/21/2011 4:50:05 AM

Description:
********Contact Information********
Handle: Joel -Jaykul- Bennett
Site Name: PowerShell
Feedback ID: 680120
***************************************

Frequency: Always Happens
Regression: No, this is ne...

windowsserver.uservoice.com

パイプラインの中断エラーを Write-Error で出せるようにとかもあります。

Please feel free to provide feedback or file bugs here.
  • 2 votes
  • 0 comments

Option to output a pipeline terminating error via a Write-Error switch parameter

Votes from Connect: 3

Original Date Submitted: 4/14/2015 6:32:46 PM

Description:
********Contact Information********
Handle: Carl Sörqvist
Site Name: PowerShell
Feedback ID: 1247244
***************************************

Problem Description:
There are three types of errors in Po...

windowsserver.uservoice.com

昔記事にした | Out-Null の遅さなども。

Please feel free to provide feedback or file bugs here.
  • 10 votes
  • 2 comments

performance of out-null drastically worse then using [void] or assigning result to $null

Votes from Connect: 4

Original Date Submitted: 3/28/2015 6:08:31 AM

Description:
********Contact Information********
Handle: JasonHorner
Site Name: PowerShell
Feedback ID: 1208677
***************************************

Frequency: PowerShell
Regression: gci | out-null
[void](gci)
$null...

windowsserver.uservoice.com

tech.guitarrapc.com

あとは、Where-Object などで {} 抜きで自動変数 $_ にアクセスしたいという例など。実際これほしいですよね。

Please feel free to provide feedback or file bugs here.
  • 3 votes
  • 0 comments

$_ should be accessible without curly brackets with Where-Object

Votes from Connect: 5

Original Date Submitted: 10/30/2014 6:04:29 AM

Description:
********Contact Information********
Handle: Peter M10
Site Name: PowerShell
Feedback ID: 1014939
***************************************

Frequency: Always Happens
Regression: Yes, this happens in all previou...

windowsserver.uservoice.com

まとめ

リフレクション最高 (