PowerShellで文字列から[ScriptBlock]::Create()関数でScriptBlockを作ったときのメモ。

今まで invoke-command のscriptblockはベタ打ちでしか使ったことがなかったが、
「PSRemotingでDockerのコンテナの中に入れないのであれば、invoke-commandとさほど変わらないのでは?」
と思い、scriptblockの文字列を変数化してinvoke-commandを試してみて躓いてしまった。
そのとき以下の記事が参考になった。
yomon.hatenablog.com

べたで打ってるときと同じ調子で、コマンドの文字列を変数に格納し、{$cmdstr}としてみたが駄目だった。
[System.Management.Automation.ScriptBlock]型に変換もできない。(前後してしまうが・・・)

PS >$t = [System.Management.Automation.ScriptBlock]$c
"{date}" の値を "System.String" 型から "System.Management.Automation.ScriptBlock" 型に変換できません。
発生場所 行:1 文字:1
+ $t = [System.Management.Automation.ScriptBlock]$c
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) []、RuntimeException
    + FullyQualifiedErrorId : ConvertToFinalInvalidCastException

どうも、[Scriptblock]::Create()関数でちゃんと作らなければならないようだ。

PS >$c = 'date'
PS >$s = [Scriptblock]::Create($c)
PS >$s.gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     ScriptBlock                              System.Object


PS >$s.invoke()

202210913:59:29


PS >$c = '{date}'
PS >$s = [Scriptblock]::Create($c)
PS >$s.gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     ScriptBlock                              System.Object


PS >$s.invoke()
date
PS >$s.invoke().invoke()

202210914:00:41


PS >stop-transcript

コマンド文字列に'{ }'を入れてしまうと、'$s.invoke().invoke()'と2回ほどinvoke()しないと意図する結果が得られなかった。なので文字列としては'{ }'は付けない方が良いのだろう。

=============

2022-10-10 p.s.

ベタ打ちのときは文字化けしないが、[scriptblock]::create()で生成したscriptblockをinvokeするとなぜか文字化けする。

PS >$cmd = 'docker container ls -a -f name=test-.+'
PS >$x = [scriptblock]::create($cmd)
PS >$x.invoke()
CONTAINER ID   IMAGE                 COMMAND                  CREATED       STATUS                  PORTS     NAMES
9bbd5b2256b6   nginx:1.17.6-alpine   "nginx -g 'daemon of窶ヲ"   12 days ago   Exited (0) 2 days ago             test-3
34410af55b73   nginx:1.17.6-alpine   "nginx -g 'daemon of窶ヲ"   12 days ago   Exited (0) 2 days ago             test-2
d892fccc011b   nginx:1.17.6-alpine   "nginx -g 'daemon of窶ヲ"   12 days ago   Exited (0) 2 days ago             test-1

一方、
%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -NoExit -Command "chcp 65001"
で起動したpowershellではencodingはus-asciiのままだったが、文字化けはしていなかった。
PowerShell起動時、文字コードをUTF-8に変える方法 - Qiita

なぜだろう?何が違うのだろう?

PS >$cmd = 'docker container  ls -a -f name=test-.+'
PS >$x = [scriptblock]::create($cmd)
PS >$x.invoke()
CONTAINER ID   IMAGE                 COMMAND                  CREATED       STATUS                  PORTS     NAMES
9bbd5b2256b6   nginx:1.17.6-alpine   "nginx -g 'daemon of…"   12 days ago   Exited (0) 2 days ago             test-3
34410af55b73   nginx:1.17.6-alpine   "nginx -g 'daemon of…"   12 days ago   Exited (0) 2 days ago             test-2
d892fccc011b   nginx:1.17.6-alpine   "nginx -g 'daemon of…"   12 days ago   Exited (0) 2 days ago             test-1
PS >$outputencoding


IsSingleByte      : True
BodyName          : us-ascii
EncodingName      : US-ASCII
HeaderName        : us-ascii
WebName           : us-ascii
WindowsCodePage   : 1252
IsBrowserDisplay  : False
IsBrowserSave     : False
IsMailNewsDisplay : True
IsMailNewsSave    : True
EncoderFallback   : System.Text.EncoderReplacementFallback
DecoderFallback   : System.Text.DecoderReplacementFallback
IsReadOnly        : True
CodePage          : 20127

eof