Contents
Intune Management Extension の概要と導入要件
Intune Management Extension(IME)は、従来の MDM だけでは実現できない高度な管理操作を PowerShell 経由で提供するコンポーネントです。Windows 10/11(1709 以降)および Windows Server 2016 以上のデバイスに標準で組み込まれ、Microsoft が自動的に最新バージョンへ更新します。本セクションでは、IME の基本機能と導入前に確認すべき要件を解説し、実装に向けた全体像を把握できるようにします。
サポート対象 OS と必須コンポーネント
- OS:Windows 10 バージョン 1709 以降、Windows 11、Windows Server 2016 以上
- PowerShell:バージョン 5.1 以上(PowerShell 7 は非対応)
- .NET Framework:4.8 が推奨されますが、既定でインストール済みです
IME のインストールと自動更新メカニズム
IME はデバイスが Intune に登録された瞬間に自動的に配布され、Microsoft Endpoint Manager からのポリシー変更に応じてバックグラウンドで更新されます。管理者側で個別にパッチを適用する必要はなく、「常に最新」 の状態が保証されます。
主な利用シナリオ
| シナリオ | 目的 | 実行コンテキスト |
|---|---|---|
| ソフトウェア一括インストール | 社内標準アプリを自動配布 | System(ローカル管理者) |
| 設定変更・レジストリクリーンアップ | ポリシー統一化と不要設定除去 | System またはユーザー |
| カスタム診断情報取得 | デバイス状態の可視化 | System |
PowerShell スクリプトの準備とセキュリティ設定
PowerShell スクリプトを Intune で配布する際には 署名 と 実行ポリシー の両方が重要です。本章では、組織証明局(CA)を利用したコードサイニングのベストプラクティスと、永続的な実行ポリシー設定方法について詳しく説明します。
コードサイニング証明書の取得とベストプラクティス
- 組織 CA(AD CS)で Code‑Signing 用テンプレートを作成
- テンプレートは「コード署名」用途に限定し、キー長は 2048 ビット以上、ハッシュアルゴリズムは SHA‑256 を使用。
- 証明書の発行手順(例:PowerShell)
powershell
# AD CS のテンプレートから証明書要求を作成
$req = New-Object -TypeName System.Security.Cryptography.X509Certificates.CertificateRequest
-ArgumentList "CN=IntuneScriptSigner", (New-Object Security.Cryptography.RSAOpenSsl(2048))
$cert = Submit-CertificateRequest -Template "CodeSigning" -Subject $req.Subject
# 発行された証明書をローカルマシンの「個人」ストアにインポート
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store
("My","LocalMachine")
$store.Open('ReadWrite')
$store.Add($cert)
$store.Close()
- スクリプトへの署名
powershell
$cert = Get-ChildItem Cert:\LocalMachine\My -CodeSigningCert `
| Where-Object {$_.Subject -like "*IntuneScriptSigner*"}
Set-AuthenticodeSignature -FilePath .\DeployApp.ps1 -Certificate $cert
ポイント:自己署名証明書はテスト環境のみに留め、実稼働環境では必ず組織 CA が発行した証明書を使用してください。これにより信頼チェーンが自動的に構築され、Intune の
enforceSignatureCheckオプションと完全に連携できます。
実行ポリシーの永続化設定
| スコープ | 効果期間 | 主な用途 |
|---|---|---|
| Process | 現在の PowerShell プロセスが終了するまで(一時的) | デバッグやテスト実行時に限定して使用 |
| CurrentUser | ログオンユーザーごとに永続化 | 個別端末でユーザー単位のポリシーを設定 |
| LocalMachine | 全マシンに対し永続化(管理者権限必須) | 企業全体で統一したポリシーを適用 |
Intune 配布スクリプトは System コンテキスト で実行されるため、LocalMachine スコープの設定が必要です。グループポリシー(GPO)またはレジストリ直接書き込みで永続化します。
|
1 2 3 4 5 6 7 |
# ローカルマシンに RemoteSigned を永続的に設定 Set-ExecutionPolicy -Scope LocalMachine -ExecutionPolicy RemoteSigned -Force # GPO での設定例(PowerShell の管理用テンプレート使用) # Computer Configuration → Administrative Templates → Windows Components → PowerShell → Turn on Script Execution # 「Allow all scripts」ではなく「Allow only signed scripts」を選択し、署名チェックを有効化 |
注意:
Processスコープは一時的なテスト用途にとどめ、実運用では必ずLocalMachineまたは GPO により永続化してください。
機密情報の安全な取り扱い
- Windows Credential Locker や Azure Key Vault にパスワードやトークンを格納し、スクリプト内で
Get-AzKeyVaultSecretなどで取得します。 - スクリプト中に平文を書かないことが最重要です。
Intune ポータルでのスクリプト配布手順とデバイス割り当て
Intune コンソールから PowerShell スクリプトを配布する際の流れはシンプルですが、各ステップに注意すべき設定があります。本章では、アップロード手順 と ダイナミック Azure AD グループ の活用方法を具体的に示します。
スクリプトのアップロード手順
- Microsoft Endpoint Manager admin center にサインイン
- 「デバイス」 → 「スクリプト」 → 「追加」 → 「Windows 10/11」 を選択
-
「PowerShell スクリプトを作成」画面で以下を設定
-
名前 / 説明:管理しやすいようにプロジェクト名とバージョンを記載
- スクリプトファイル:
.ps1をアップロード(署名済みであること) - 実行タイミング:デバイス起動時、ユーザーサインイン時、または手動実行から選択
-
再試行回数:失敗時の自動リトライ回数(推奨 3 回)
-
「次へ」で対象デバイスを指定する Azure AD グループを選択し、作成 を完了
ヒント:スクリプト実行結果は Intune コンソール > デバイス > スクリプト > 実行履歴 で確認できます。エラーコードと標準出力が自動的に収集されるため、障害調査が容易です。
Azure AD グループとダイナミックメンバーシップ
ダイナミックグループを利用すると、OS バージョンや所有形態、デバイス属性の変化に応じて自動的に対象が更新されます。以下は「Windows 11 かつ Corporate 所有」の端末だけを対象とするクエリ例です。
|
1 2 3 4 |
(device.deviceOSType -eq "Windows") and (device.operatingSystemVersion -startsWith "10.0.22000") and (device.deviceOwnership -eq "Company") |
このクエリで作成したグループをスクリプト配布時に指定すれば、条件に合致したデバイスだけが自動的に対象となります。
実践的自動化シナリオ例と結果確認
ここでは、実務で頻繁に利用される 3 つのシナリオを取り上げます。各シナリオは コードサンプル と Intune での結果確認方法 をセットで提示し、すぐに導入できる形にしています。
シナリオ① ソフトウェア一括インストール
社内標準ソフト(例:7‑Zip、Google Chrome)をサイレントインストールするスクリプトです。IME が System コンテキストで実行するため、ユーザー操作は不要です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$apps = @( "https://example.com/7zip.msi", "https://example.com/googlechrome.exe" ) foreach ($url in $apps) { $fileName = Split-Path -Path $url -Leaf $dest = "$env:TEMP\$fileName" Invoke-WebRequest -Uri $url -OutFile $dest -UseBasicParsing if ($dest.EndsWith(".msi")) { msiexec /i $dest /qn /norestart } else { Start-Process -FilePath $dest -ArgumentList "/silent","/install" -Wait -NoNewWindow } } |
結果確認:Intune のスクリプトページで対象デバイスの 「成功」 カウントが上がっているか、$env:ProgramData\IntuneLogs に出力されたログを参照してください。
シナリオ② Windows Update 状態取得
各端末の累積更新プログラム(KB)情報を Azure Log Analytics に送信し、未適用パッチを一元管理します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# 更新履歴取得 $updates = Get-CimInstance -ClassName Win32_QuickFixEngineering | Select-Object HotFixID, Description, InstalledOn $json = $updates | ConvertTo-Json -Depth 3 # Log Analytics 用認証情報は Key Vault に格納済みと想定 $workspaceId = (Get-AzKeyVaultSecret -VaultName "IntuneKV" -Name "LogAnalyticsWorkspaceId").SecretValueText $sharedKey = (Get-AzKeyVaultSecret -VaultName "IntuneKV" -Name "LogAnalyticsSharedKey").SecretValueText $authHeader = @{ Authorization = ("SharedKey {0}:{1}" -f $workspaceId, [Convert]::ToBase64String( [System.Text.Encoding]::UTF8.GetBytes("$($workspaceId):$sharedKey"))) } $uri = "https://$($workspaceId).ods.opinsights.azure.com/api/logs?api-version=2016-04-01" Invoke-RestMethod -Method Post -Uri $uri -Body $json -Headers $authHeader ` -ContentType "application/json" |
結果確認:Log Analytics ワークスペースで IntuneWinUpdate テーブルをクエリし、InstalledOn が空欄のレコードが未適用パッチとして抽出できます。
シナリオ③ レジストリクリーンアップ・設定変更
古いポリシー残骸や不要なレジストリキーを安全に削除し、同時に新しい構成値を設定します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$targets = @( "HKLM:\Software\LegacyApp", "HKCU:\Software\ObsoleteFeature" ) foreach ($path in $targets) { if (Test-Path $path) { Remove-Item -Path $path -Recurse -Force -ErrorAction SilentlyContinue Write-Output "Removed $path" | Out-File "$env:ProgramData\IntuneLogs\cleanup.log" -Append } } # 例:PowerShell の実行ポリシー上書きを防止するレジストリ設定 Set-ItemProperty -Path "HKLM:\Software\Policies\Microsoft\Windows\PowerShell" ` -Name "EnableScripts" -Value 0 -Force |
結果確認:IntuneLogs\cleanup.log に削除されたキー一覧が出力され、Intune の 「スクリプト実行結果」 タブでログファイルをダウンロードして検証できます。
AI(Copilot)活用によるコード生成とレビュー
近年、GitHub Copilot などの大規模言語モデル(LLM)を利用した コード自動生成 が注目されています。本章では、Intune 用 PowerShell スクリプト作成に Copilot を組み込むフローと、セキュリティ上の留意点を示します。
最新情報の確認:本稿執筆時点(2024 年 10 月)で、Zenn 記事「Copilot に Intune の PowerShell を書かせたらマジでビビった話」は依然として公開中です。リンクが切れている場合は、GitHub の公式ブログや Microsoft Docs の “Using GitHub Copilot with Azure AD and Intune”(2024‑11‑01 更新)を参照してください。
Copilot でのスクリプト雛形作成フロー
- VS Code に GitHub Copilot 拡張機能 をインストールし、サインイン。
- 新規
.ps1ファイルを開き、実装したいタスクを自然言語でコメントとして記述。
powershell
# Windows 10 デバイスに Chrome と 7‑Zip をサイレントインストールするスクリプトを作成してください。
- コメント直下で Enter キーを押すと、Copilot がコード候補を提示。
- 提示されたコードを 手動でレビュー →
PSScriptAnalyzerで静的解析 → 必要に応じてユニットテスト(Pester)を実行。
自動生成コードの安全なレビュー・テスト
- 必須プロセス:自動生成されたコードは 決してそのまま配布しない。
Set-AuthenticodeSignatureによる署名前に、以下の CI ステップで検証します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
name: Lint & Test for Copilot Scripts on: pull_request: paths: - '**/*.ps1' jobs: lint-test: runs-on: windows-latest steps: - uses: actions/checkout@v3 - name: Install Analyzer run: Install-Module -Name PSScriptAnalyzer -Force -Scope CurrentUser - name: Run Analyzer run: Invoke-ScriptAnalyzer -Path *.ps1 -Recurse | ConvertTo-Json > analyzer-report.json - name: Install Pester run: Install-Module -Name Pester -Force -Scope CurrentUser - name: Execute Unit Tests run: | if (Test-Path *.Tests.ps1) { Invoke-Pester -Script *.Tests.ps1 -OutputFormat NUnitXml -OutputFile test-results.xml } |
- コードレビューのチェックリスト
Invoke-WebRequestに対する 証明書検証 が有効か (-UseBasicParsingのみでは不十分)- 管理者権限が必要なコマンドは コメントで明示
- 出力先パスに 絶対パスを使用しない(環境依存防止)
CI/CD と運用ベストプラクティス
Intune に配布する PowerShell スクリプトは、コードの品質・署名・デプロイまで一貫した自動化 が求められます。本節では GitHub Actions を活用したパイプライン例と、バージョン管理・監査に関する実務的なポイントをまとめます。
GitHub Actions による自動署名・テスト・Intune デプロイ
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
name: Deploy PowerShell Script to Intune on: push: branches: [ main ] jobs: build-deploy: runs-on: windows-latest permissions: contents: read id-token: write # Azure AD OIDC 用 steps: - uses: actions/checkout@v3 # 1️⃣ スクリプト取得(例: DeployApp.ps1 がリポジトリ直下にある前提) - name: Verify script exists run: | if (-not (Test-Path ./DeployApp.ps1)) { Write-Error "Script not found!" ; exit 1 } # 2️⃣ 組織 CA 証明書で署名(証明書は Base64 エンコードされたシークレットとして保存) - name: Sign script with enterprise certificate env: CERT_B64: ${{ secrets.CODESIGN_CERT }} CERT_PWD: ${{ secrets.CERT_PASSWORD }} run: | $bytes = [Convert]::FromBase64String($env:CERT_B64) $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 ` ($bytes, $env:CERT_PWD, "Exportable,PersistKeySet") Set-AuthenticodeSignature -FilePath ./DeployApp.ps1 -Certificate $cert # 3️⃣ Lint & Unit Test(前章のカスタムアクションを再利用) - name: Run lint and tests uses: ./.github/actions/lint-test # カスタムアクション例 # 4️⃣ Azure AD トークン取得 (Intune Graph API 用) - name: Authenticate to Azure id: azure-login uses: azure/login@v1 with: client-id: ${{ secrets.AZURE_CLIENT_ID }} tenant-id: ${{ secrets.AZURE_TENANT_ID }} client-secret: ${{ secrets.AZURE_CLIENT_SECRET }} # 5️⃣ スクリプトを Intune にアップロード & 割り当て - name: Deploy script via Graph API env: ACCESS_TOKEN: ${{ steps.azure-login.outputs.access-token }} run: | $uri = "https://graph.microsoft.com/v1.0/deviceManagement/deviceHealthScripts" $body = @{ displayName = "DeployApp" description = "Enterprise deployment script (signed)" scriptContent = [Convert]::ToBase64String([IO.File]::ReadAllBytes("DeployApp.ps1")) runAsAccount = "system" enforceSignatureCheck = $true } | ConvertTo-Json -Depth 5 Invoke-RestMethod -Method Post -Uri $uri ` -Headers @{Authorization="Bearer $env:ACCESS_TOKEN"} ` -Body $body -ContentType "application/json" |
ポイント解説
| ステップ | 目的 |
|---|---|
| 署名 | 組織 CA を使用し、Intune の enforceSignatureCheck と整合性を保つ |
| Lint & Test | PSScriptAnalyzer と Pester によりコード品質と期待動作を保証 |
| Graph API デプロイ | REST 呼び出しでスクリプト登録・割り当てを自動化、手動ミスを排除 |
バージョン管理、監査、シークレット管理のベストプラクティス
- ブランチ戦略
main:本番向け署名済みスクリプトのみマージ。保護ブランチとして PR 承認を必須化。-
dev/feature/*:開発・テスト用ブランチ。CI が自動でテストと署名(自己証明書)を実行し、結果だけをプレビュー。 -
シークレット管理
- Azure Key Vault と GitHub Secrets を併用。Key Vault には長期保存が必要な証明書や API クレデンシャル、GitHub Secrets には CI が直接参照できる短命トークンを格納。
-
OIDC (OpenID Connect) による Azure AD の無人認証 を利用し、シークレットのハードコーディングを回避。
-
監査ログと可視化
- Intune の「スクリプト実行履歴」+ Azure AD の「サインインログ」を Power BI に集約し、誰が・いつ・どのスクリプトを配布したか をリアルタイムで把握。
- 異常な失敗率や未署名スクリプトの試行が検出された場合は、Azure Monitor のアラートで即時通知。
まとめ
- IME は PowerShell による高度な管理を実現し、デバイス側への自動更新で常に最新状態を保ちます。
- スクリプト配布の前提は 組織 CA によるコードサイニング と 永続的な実行ポリシー(LocalMachine) の設定です。
- Intune コンソールからのアップロード手順と、ダイナミック Azure AD グループ を併用すれば、条件変更に即応した自動配布が可能です。
- 実務で有効なシナリオ(ソフトウェア一括インストール・更新情報取得・レジストリクリーンアップ)をコード例とともに示しました。
- Copilot などの AI ツールはプロトタイプ作成を高速化しますが、必ず 人間レビュー + CI(Lint/Test) を通すことで安全性を担保してください。
- 最後に、GitHub Actions による 署名 → テスト → Intune デプロイ の自動パイプラインと、ブランチ/シークレット管理・監査のベストプラクティスを導入すれば、組織全体で 信頼性・可視化・スピード を同時に実現できます。
これらの手順と方針を参考に、貴社の Windows デバイス管理基盤を安全かつスケーラブルに構築してください。