みなさんこんにちは!ヒロポンです!
設定を JSON ファイルで持つ。社内の REST API を叩く。Teams の Webhook に通知を投げる。
業務の自動化を1人でやってると、こういう「JSON と HTTP」の場面が地味に増えてきますよね。
で、これ PowerShell だけで全部いけます。追加モジュールもいらない。
標準の ConvertFrom-Json と Invoke-RestMethod があれば、JSON を読んで API を叩いて、返りをオブジェクトとして扱う、までひと通り書けます。
今回は「PowerShell で JSON を扱う方法」を、コピペで動くスクリプトで3ステップにまとめました。ConvertFrom-Json の使い方から、Invoke-RestMethod の認証ヘッダで詰まる所まで。
💡 この記事は、AD ユーザーを一括作成する や イベントログを監視してメール通知する と同じ「1人運用の自動化」シリーズの一本です。JSON と REST が扱えると、社内連携の幅がグッと広がります。
結論: ConvertFrom-Json で読む → Invoke-RestMethod で叩く → 返りをオブジェクトで扱う
先に全体像です。やることは3つだけ。
# 1. JSON文字列をオブジェクトにする
$obj = '{ "name": "田中", "age": 40 }' | ConvertFrom-Json
$obj.name # 田中
# 2. REST API を叩く (返りは自動でオブジェクト化される)
$res = Invoke-RestMethod -Uri "https://api.example.com/users/1" -Method Get
# 3. 返ってきたオブジェクトをそのまま使う
$res.name
ConvertFrom-Json で JSON をオブジェクトにして、Invoke-RestMethod で API を叩く。
返ってきた JSON は勝手にオブジェクトになってるので、$res.name でそのままたどれます。いい感じにシンプル。
ここまでで「あとは自分のケースに当てはめるだけ」と分かった人は、ページを閉じてもらってもかまいません! 以下は各ステップの詳細と、業務SEが最初に詰まるハマりポイントです。
そもそも: JSON をオブジェクトにする ConvertFrom-Json
ConvertFrom-Json は、JSON 文字列を PowerShell のオブジェクト(PSCustomObject)に変換する コマンドレットです。
一度オブジェクトにしてしまえば、あとは PowerShell のいつものドット記法でプロパティをたどれます。文字列を正規表現でパースする、みたいな消耗戦をしなくて済む。これが地味にありがたいんですよね。
逆に、オブジェクトを JSON 文字列に戻すのが ConvertTo-Json。API に POST する body を作る時に使います。この2つはセットで覚えておくと迷いません。
図にすると、こういう関係です。

最短3ステップ(コピペで動く)
ステップ1: JSON を読む(ConvertFrom-Json)
設定ファイルや API のレスポンスを、オブジェクトとして読みます。深い階層も配列も、そのままたどれます。
$json = @'
{
"department": "営業部",
"manager": { "name": "佐藤", "ext": "1234" },
"members": ["田中", "鈴木", "高橋"]
}
'@
$config = $json | ConvertFrom-Json
$config.department # 営業部
$config.manager.name # 佐藤 (深い階層はドットでたどる)
$config.members[0] # 田中 (配列はインデックス)
$config.members.Count # 3
実行結果:
![ConvertFrom-Json で JSON を PSCustomObject にし、config.manager.name=佐藤・config.members[0]=田中・Count=3 と階層と配列をたどった実行結果](/_next/image/?url=https%3A%2F%2Fcms.hiropon-progra.com%2Fwp-content%2Fuploads%2F2026%2F09%2Fblock-1-9.png&w=1200&q=75)
$config.manager.name みたいに、ネストした階層も . でつないでいくだけ。配列は [0] でインデックス指定、件数は .Count で取れます。
ファイルから読むなら Get-Content -Raw file.json | ConvertFrom-Json でいけます。-Raw を付けないと1行ずつ配列で渡っちゃうので、そこだけ注意です。
ステップ2: REST API を叩く(Invoke-RestMethod)
Invoke-RestMethod は、API を叩いて 返ってきた JSON を自動でオブジェクトにして返して くれます。JSON をパースする手間がゼロ。
# GET (シンプルな取得)
$res = Invoke-RestMethod -Uri "https://api.example.com/users/1" -Method Get
$res.name
# 認証ヘッダが必要な場合 (Bearer トークン)
$headers = @{ Authorization = "Bearer $token" }
$res = Invoke-RestMethod -Uri "https://api.example.com/users/1" -Headers $headers -Method Get
ヘッダはハッシュテーブル @{ } で作って -Headers に渡すだけ。Bearer トークン認証は、だいたいこの形が定番です。
ステップ3: 返ってきた JSON をオブジェクトとして扱う(POST も)
データを送る時は、PowerShell オブジェクトを ConvertTo-Json で JSON にして POST します。
# ハッシュテーブル → JSON にして POST
$body = @{ name = "田中"; age = 40 } | ConvertTo-Json
$res = Invoke-RestMethod -Uri "https://api.example.com/users" `
-Method Post -Body $body -ContentType "application/json"
# Teams の Webhook に通知を投げる例
$payload = @{ text = "夜間バッチが完了しました" } | ConvertTo-Json
Invoke-RestMethod -Uri $webhookUrl -Method Post -Body $payload -ContentType "application/json"
ConvertTo-Json で body を作って、-ContentType "application/json" を付けて POST。
Teams への完了通知なんかも、これだけで飛ばせます。バッチの最後に1行足すだけで「終わったらSlack/Teamsに通知」が実現できる。こんな感じで、運用がだいぶ楽になります。
ハマりポイント: 知らないと地味に詰まる3つ
ここが本番です。上のコードは動くんですが、実務だと下の3つで足を止められがち。全部踏んだことあるやつです。
① ConvertTo-Json は既定で -Depth 2 までしか変換しない
これ、一番やられます。ConvertTo-Json は 既定だと2階層までしか変換してくれません。
3階層以上ネストしたオブジェクトは、System.Collections.Hashtable みたいな文字列にサラッと潰れます。
$data = @{ a = @{ b = @{ c = @{ d = "深い値" } } } }
$data | ConvertTo-Json # 深い階層が "System.Collections.Hashtable" に潰れる
$data | ConvertTo-Json -Depth 10 # ちゃんと最後まで JSON になる
実行結果(既定は Hashtable に潰れ、-Depth 10 で最後まで展開):

「なんか JSON の中身が変な文字列になってる??」と思ったら、まず -Depth を疑ってください。PowerShell 7 なら WARNING: Resulting JSON is truncated as serialization has exceeded the set depth of 2. という警告も出してくれるので、これが出たら深さ不足のサインです。
私は昔これで、Webhook に送った通知の中身が全部潰れてて、30分くらい原因が分からず唸ってました。深めのオブジェクトを送るなら -Depth 10 くらい付けとくのが安全です。
② 配列を @() で受けないと、1件の時に配列にならない
PowerShell の罠として有名なやつ。API が配列を返しても、要素が1件だけだと配列じゃなく単一オブジェクトになる ことがあります。
$users = Invoke-RestMethod -Uri $uri -Method Get
# 1件だけ返ると配列じゃなく単一オブジェクト。件数分岐や [0] アクセスが崩れる
foreach ($u in @($users)) { # @() で囲んでおくと、1件でも0件でも安全に回る
Write-Host $u.name
}
実行結果:

@() で囲んでおくと、要素が1件でも0件でも「配列」として扱えます。件数で分岐するスクリプトが、データ1件の日だけ動かない……みたいな事故を防げます。
③ Invoke-RestMethod の認証ヘッダ・プロキシで 401 / タイムアウト
社内 API を叩くと、だいたいここで詰まります。「トークンは合ってるのに 401 が返る??」ってなったら、下のどれかが原因のことが多いです。
- 401 Unauthorized → トークンの有効期限切れか、
Content-Typeヘッダの付け忘れをまず疑う - 社内プロキシ越え →
-Proxy "http://proxy:8080" -ProxyUseDefaultCredentialsを付ける - 社内の自己署名証明書 → 証明書エラーで弾かれる(本番では例外を握るより、証明書をちゃんと入れるのが筋)
$headers = @{
Authorization = "Bearer $token"
"Content-Type" = "application/json"
}
$res = Invoke-RestMethod -Uri $uri -Headers $headers -Method Get `
-Proxy "http://proxy.example.com:8080" -ProxyUseDefaultCredentials
認証まわりは環境依存がマジで強いので、まず Invoke-RestMethod 単体で叩いて、ステータスコードを見ながら潰していくのが早いです。エラーの握り方は PowerShell の ErrorAction で踏む落とし穴 の話ともつながります。
現場メモ: 1人運用で JSON / REST が効く場面
1人で運用回してると、「手作業でポチポチやってた連携」を PowerShell に寄せられる場面が意外と多いんですよね。
- 設定を JSON ファイルで外出しして、スクリプトから読む(環境ごとの切り替えが楽)
- 夜間バッチの結果を Teams / Slack の Webhook に通知
- 社内の在庫 API や勤怠 API から JSON を取ってきて集計
どれも ConvertFrom-Json + Invoke-RestMethod の組み合わせで書けます。C# でガッツリ書くほどじゃない。でも手作業だと面倒……という「中間の自動化」に、PowerShell の JSON/REST はちょうどハマります。
ちなみに、同じ JSON 処理を C# 側でやるなら C# の Newtonsoft.Json で業務系 JSON を扱うガイド にまとめてます。アプリに組み込むなら C#、運用スクリプトなら PowerShell、で使い分けるといい感じです。
まとめ
ConvertFrom-Jsonで JSON をオブジェクトにすれば、$obj.a.bでドットでたどれるInvoke-RestMethodは返りの JSON を自動でオブジェクト化してくれる。GET も POST もこれ1つ- POST の body は
ConvertTo-Jsonで作る。ただし 既定 -Depth 2 の罠に注意 - 配列は
@()で受ける、認証は-Headers @{ Authorization = "Bearer ..." }、この2つを押さえれば実務はだいたい回る
JSON と REST を PowerShell で扱えるようになると、「これ手作業でやってたな」という連携がスクリプト1本に化けます。1人運用の武器がまた1つ増えます!!
よくある質問
Q1. PowerShell で JSON をオブジェクトとして読むには?
JSON 文字列を ConvertFrom-Json に渡すと PSCustomObject になります。あとは $obj.プロパティ名 でドットでたどれます。深い階層は $obj.a.b、配列は $obj.items[0] のようにインデックスで参照できます。ファイルから読むなら Get-Content -Raw file.json | ConvertFrom-Json です(-Raw を忘れずに)。
Q2. ConvertTo-Json で深い階層が消えるのはなぜ?
ConvertTo-Json は既定で -Depth 2 までしか変換しません。3階層以上ネストしたオブジェクトは System.Collections.Hashtable などの文字列に潰れます。-Depth 10 のように明示的に深さを指定してください。深いオブジェクトを API に送る時、これを忘れると中身が壊れたまま届きます。
Q3. Invoke-RestMethod で認証が必要な API を叩くには?
ハッシュテーブルで作ったヘッダを -Headers に渡します。Bearer トークンなら @{ Authorization = "Bearer $token" } の形です。401 が返る時は、トークンの有効期限か Content-Type ヘッダの付け忘れをまず疑ってください。社内プロキシ越えが必要なら -Proxy と -ProxyUseDefaultCredentials を足します。
Q4. Invoke-RestMethod と Invoke-WebRequest はどっちを使う?
JSON API を叩くだけなら Invoke-RestMethod です。返ってきた JSON を自動でオブジェクトに変換してくれます。Invoke-WebRequest のほうは生のレスポンス(ステータスコードやヘッダ含む)を返すので、HTTP のステータスやヘッダまで細かく見たい時に使い分けます。
次に読むべき記事




以上!
同じように JSON と REST で手作業してる人いたら、どんどんシェア待ってるぜ!!
執筆者
バイブス父さん — 業務 SE 7 年 (SIer 正社員 2 / フリーランス 5)。 現職は SEO 直轄部の AI アドバイザー兼 PL、 副業で中小 SIer の CTO。 SIer の正社員からフリーランスに転じ、 複数のエージェント経由で案件を回してきた経験ベースで「業務 SE 視点」 の技術 + キャリア記事を書いています。
🐦 X: @hiro_progra0524 (日々の現場メモ更新中)
📝 About Me で経歴詳細を見る


