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() 2022年10月9日 13: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() 2022年10月9日 14: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