はじめに
この記事は、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 の入力パラメータの型検証結果でした。
私の推測より記載している部分が多々ありますので、あくまでも参考程度にしていただければと思います。
また、誤っている情報がありましたら、指摘していただけると助かります。
