はじめに
この記事は、PoweShell Runbook で、入力パラメータにて値を渡したときその値の型はどうなるのか?
を検証した記事になります。
誤っている箇所があればご指摘いただければと思います。
型検証を行おうと思ったきっかけはこちらの記事で、Power Automate からJSON 値を渡したはずがConvertFrom-Json でなぜか失敗してしまったことがきっかけです。
Microsoft 365 ユーザーアカウントの作成を自動化する
PowerShell Runbook での入力パラメータの構成方法
PowerShell Runbook で入力パラメータを構成するには、以下のように記述します。
Param ( [Parameter (Mandatory= $true/$false)] [Type] $Name1 = <Default value>, [Parameter (Mandatory= $true/$false)] [Type] $Name2 = <Default value> )
詳しくは以下の公式doc をご確認ください。
検証
PowerShell Runbook の作成
今回作成したPowerShell Runbook には以下のような検証用シェルを作成しました。
PowerShell Runbook の詳しい作成方法は今回省きます。
Param ( $str_1,[string]$str_2, $num_1,[int]$num_2, $json_1,$json_2,$json_3 ) $str = "str" $num = 1 $json = '{ "name": "korune" }' echo ("str:" + $str) echo (" - type:" + $str.GetType().FullName) echo "`r`n" echo ("num:" + $num) echo (" - type:" + $num.GetType().FullName) echo "`r`n" echo ("json:" + $json) echo (" - type:" + $json.GetType().FullName) echo "`r`n" echo ("str_1:" + $str_1) echo (" - type:" + $str_1.GetType().FullName) echo ("str_2:" + $str_2) echo (" - type:" + $str_2.GetType().FullName) echo "`r`n" echo ("num_1:" + $num_1) echo (" - type:" + $num_1.GetType().FullName) echo ("num_2:" + $num_2) echo (" - type:" + $num_2.GetType().FullName) echo "`r`n" echo ("json_1:" + $json_1) echo (" - type:" + $json_1.GetType().FullName) echo ("json_2:" + $json_2) echo (" - type:" + $json_2.GetType().FullName) echo ("json_3:" + $json_3) echo (" - type:" + $json_3.GetType().FullName) echo "`r`n" echo ("`r`n---ConvertFrom-Json----`r`n") $convert_json = ConvertFrom-Json $json echo ("json:" + $convert_json) echo (" - type:" + $convert_json.GetType().FullName) echo "`r`n" $convert_json_1 = ConvertFrom-Json $json_1 echo ("json_1:" + $convert_json_1) echo (" - type:" + $convert_json_1.GetType().FullName) echo "`r`n" $convert_json_2 = ConvertFrom-Json $json_2 echo ("json_2:" + $convert_json_2) echo (" - type:" + $convert_json_2.GetType().FullName) echo "`r`n" $convert_json_3 = ConvertFrom-Json $json_3 echo ("json_3:" + $convert_json_3) echo (" - type:" + $convert_json_3.GetType().FullName) echo "`r`n" echo ("`r`n---ConvertFrom-Json(not in param)----`r`n") echo ("json") ConvertFrom-Json $json echo "`r`n" echo ("json_1") ConvertFrom-Json $json_1 echo "`r`n" echo ("json_2") ConvertFrom-Json $json_2 echo "`r`n" echo ("json_3") ConvertFrom-Json $json_3
ただ実際変数に設定されている値と、その型がわかり、またConvertFrom-Json で失敗するのはどういったケースなのか?
がわかればいいので、書き方は適当です。
テスト実行
それぞれ以下の画像のような変数を設定して実行してみました。
その際の出力は以下のようになりました。
str:str - type:System.String num:1 - type:System.Int32 json:{ "name": "korune" } - type:System.String str_1:a - type:System.String str_2:b - type:System.String num_1:1 - type:System.String num_2:2 - type:System.Int32 json_1:{ "name": "korune" } - type:System.String json_2:'{ "name": "korune" }' - type:System.String json_3:[{ "name": "korune" }] - type:System.String ---ConvertFrom-Json---- json:@{name=korune} - type:System.Management.Automation.PSCustomObject json_1:@{name=korune} - type:System.Management.Automation.PSCustomObject json_2:{ "name": "korune" } - type:System.String json_3: - type:System.Object[] ---ConvertFrom-Json(not in param)---- json name ---- korune json_1 name ---- korune json_2 { "name": "korune" } json_3 Length : 1 LongLength : 1 Rank : 1 SyncRoot : {@{name=korune}} IsReadOnly : False IsFixedSize : True IsSynchronized : False Count : 1
番号(_X)が変数の末についていないものは、変数の値をシェル内で定義しています。
変数の末が_1のものは、Param() にて型宣言を行わずに変数を定義しています。
変数の末が_2のものは、Param() にて型宣言を行って変数を定義しています。
* JSON 除く
JSON の型宣言を行っていないのはJSON 型というものが存在しないためです。
ちなみにPowerShell で利用可能な型は以下になります。
Type | Name |
---|---|
[array] | [System.Array] |
[bool] | [System.Boolean] |
[byte] | [System.Byte] |
[char] | [System.Char] |
[datetime] | [System.DateTime] |
[decimal] | [System.Decimal] |
[double] | [System.Double] |
[guid] | [System.Guid] |
[hashtable] | [System.Collections.Hashtable] |
[int16] | [System.Int16] |
[int32][int] | [System.Int32] |
[int64][long] | [System.Int64] |
[nullable] | [System.Nullable] |
[psobject] | [System.Management.Automation.PSObject] |
[regex] | [System.Text.RegularExpressions.Regex] |
[sbyte] | [System.SByte] |
[scriptblock] | [System.Management.Automation.ScriptBlock] |
[single][float] | [System.Single] |
[string] | [System.String] |
[switch] | [System.Management.Automation.SwitchParameter] |
[timespan] | [System.TimeSpan] |
[type] | [System.Type] |
[uint16] | [System.UInt16] |
[uint32] | [System.UInt32] |
[uint64] | [System.UInt64] |
[xml] | [System.Xml.XmlDocument] |
出力結果を纏めると以下のようになります。
設定値と型の関係
変数名 | 備考 | 設定値 | 型 |
---|---|---|---|
str | シェル内定義 | str | System.String |
str_1 | 型宣言なし | a | System.String |
str_2 | 型宣言あり[string] | b | System.String |
num | シェル内定義 | 1 | System.Int32 |
num_1 | 型宣言なし | 1 | System.String |
num_2 | 型宣言あり[int] | 2 | System.Int32 |
json | シェル内定義 | { "name": "korune" } | System.String |
json_1 | 型宣言なし | { "name": "korune" } | System.String |
json_2 | 型宣言なし | '{ "name": "korune" }' | System.String |
json_3 | 型宣言なし | [{ "name": "korune" }] | System.String |
ConvertFrom-Json の結果
変数名 | 設定値 | 出力 | 型 |
---|---|---|---|
json | { "name": "korune" } | name ---- korune |
System.Management.Automation.PSCustomObject |
json_1 | { "name": "korune" } | name ---- korune |
System.Management.Automation.PSCustomObject |
json_2 | '{ "name": "korune" }' | { "name": "korune" } | System.String |
json_3 | [{ "name": "korune" }] | Length : 1 LongLength : 1 Rank : 1 SyncRoot : {@{name=korune}} IsReadOnly : False IsFixedSize : True IsSynchronized : False Count : 1 |
System.Object[] |
ConvertFrom-Json
の結果はドキュメントを確認すると、 System.Management.Automation.PSCustomObject
となっている。
ConvertFrom-Json
json_2
と json_3
の結果は System.Management.Automation.PSCustomObject
ではないが、何故エラーになっていない?
私の知識が足りないので、ここはもう少し調査を行う必要がある。。。
Power Automate からPowerShell Runbook に値を渡してみる
Power Automate からPowerShell Runbook に値を渡すようフローを作成します。
渡す値は先ほどと同じ値を渡したいと思います。
その結果が以下になります。
json_2
にて "有効な JSON を入力してください。" とでているのはPowerShell 内で ConvertFrom-Json
を利用しているのでその解析結果によるものかと思いますが、 str_1
で同様のエラーがでているのは何故??
Object
型から string
型への変換に失敗してこのエラーがでている??
こちらの公式ドキュメントのRunbook の入力パラメーターを構成する - Runbook に JSON オブジェクトを渡すをみてみると、
JSON データを受け入れるには、Runbook は、入力パラメーターとしてオブジェクトを受け取る必要があります
と記載されています。
これは私の推測なので詳細はわかりませんが、この"ジョブの作成"コネクタのエラーハンドリングが適切ではないのでは??と推測しました。
ここは中のソースを確認するなりサポートに確認するなりしないとわからないですね。
必須項目にはしていないので、該当項目を空白にして保存を行ったところ以下エラーが出力されました。
フローの保存がコード 'OpenApiOperationParameterValidationFailed' およびメッセージ '入力パラメーター 'body' の検証がワークフロー操作 'ジョブの作成' で失敗しました: 種類/形式 'Integer' のパス 'body/properties/parameters/num_1' にある値 '1' のパラメーターは、種類/形式 'Object' に変換できません。' で失敗しました。
先ほどRunbook のテストを行うときにパラメータ入力のスクショを貼り付けましたが、その際、型の宣言を行わなかった変数の型は 'Object' と表示されていたかと思います。
このことから型のデフォルト設定値は Object
だということがわかりますが、公式ドキュメントみるとそもそもPowerShell Runbook の入力パラメーターの Type
は必須になっていて、デフォルト値がなにか記載とかないんですよね...
Runbook の入力パラメーターを構成する - PowerShell Runbook の入力パラメーターを構成する
まぁ、ちゃんと型宣言しろよ。ってことかもしれませんが、これPowerShell Runbook 側でエラーとかださなくていいんですかね?もしくはドキュメントの記載を変えるか。
PowerShell の構文としては問題ないので、ドキュメントの記載方法変えたほうがいいような...と思いますが、私がなにか勘違いしているのでしょうかね。
とりあえずこのことからも、型の宣言はきちんと行っておくべきだということがわかりますね。
対象項目を空白にしましたが、問題はまだあります。
フローの保存がコード 'OpenApiOperationParameterValidationFailed' およびメッセージ '入力パラメーター 'body' の検証がワークフロー操作 'ジョブの作成' で失敗しました: API 操作 'CreateJob' では、プロパティ 'body/properties/parameters/json_3' の種類を 'Object' にする必要がありますが、種類が 'Array' です。' で失敗しました。
指摘の通り、 [{ "name": "korune" }]
は配列なのでエラーがでています。
一旦上の3つの項目、
- str_2
- num_2
- json_1
だけを設定して実行してみます。
その結果が以下になります。
str:str - type:System.String num:1 - type:System.Int32 json:{ "name": "korune" } - type:System.String str_1: str_2:b - type:System.String num_1: num_2:1 - type:System.Int32 json_1:@{name=korune} - type:System.Management.Automation.PSCustomObject json_2: json_3: ---ConvertFrom-Json---- json:@{name=korune} - type:System.Management.Automation.PSCustomObject json_1: json_2: json_3: ---ConvertFrom-Json(not in param)---- json name ---- korune json_1 json_2 json_3
ConvertTo-Json
できてないじゃん...
入力値を確認してみます。
入力値としては想定通りの値が渡ってきています。
ログをみてみます。
Invalid JSON primitive: .
つまりJSON じゃないといわれていますね。
出力結果をみてみると、 json_1
は以下のように出力されています。
json_1:@{name=korune} - type:System.Management.Automation.PSCustomObject
このことから、どうやらPower Automate からPowerShell Runbook へJSON を渡したときは ConvertTo-Json
が行われた結果が変数に設定されるようです。
これは、shibatea さんがMicrosoft 365 ユーザーアカウントの作成を自動化するのコメントでも記載してくれている通り、Power Automate の"ジョブの作成"のRunbook のパラメーターの型は dynamic (動的) なので、渡したパラメーターを自動的に型解決してくれているのだと思います。
Azure Automation - Connectors | Microsoft Docs
このことから考えてもちゃんと型宣言しておくべきですね。
おわりに
以上、PowerShell Runbook の入力パラメータの型検証結果でした。
私の推測より記載している部分が多々ありますので、あくまでも参考程度にしていただければと思います。
また、誤っている情報がありましたら、指摘していただけると助かります。