2026年10月13日に Office LTSC 2021 のサポート完全終了、Windows 10 ESU Year 1 終了(Year 2 は倍額の $122/台)、Windows Server 2012/R2 ESU 最終終了 という3つの節目が重なります。
この記事では、Microsoft Graph PowerShell SDK を使って Intune/Entra ID に登録されたデバイスの Windows バージョンと Office バージョンを棚卸しするスクリプトを解説します。情シス担当者がゼロから手動で調べるのではなく、スクリプト1本で CSV 出力まで完結させることを目標とします。
前提条件
| 要件 | 内容 |
|---|---|
| PowerShell | 7.4 以上推奨(Windows PowerShell 5.1 でも動作可) |
| Microsoft Graph PowerShell SDK |
Microsoft.Graph モジュール v2.x |
| Entra ID ロール |
Device.Read.All、DeviceManagementManagedDevices.Read.All
|
| Intune | デバイスが Intune に登録済みであること |
モジュールのインストール
# Microsoft Graph PowerShell SDK のインストール
Install-Module -Name Microsoft.Graph -Scope CurrentUser -Force
# バージョン確認
Get-Module Microsoft.Graph -ListAvailable | Select-Object Name, Version
Part 1:Entra ID 登録デバイスから Windows 10 端末を抽出する
Entra ID(旧 Azure AD)に登録されたすべてのデバイスを取得し、OS バージョンで絞り込む方法です。Intune 未登録の BYOD や Azure AD 参加のみの端末も含まれます。
スクリプト:Windows 10 端末の一覧取得
<#
.SYNOPSIS
Entra ID 登録デバイスから Windows 10 端末を抽出して CSV に出力する
.DESCRIPTION
Microsoft Graph API の /devices エンドポイントを使用する
必要スコープ: Device.Read.All
.NOTES
実行前に Connect-MgGraph を行うこと
#>
[CmdletBinding()]
param(
[string]$OutputPath = ".\win10-devices-$(Get-Date -Format 'yyyyMMdd').csv"
)
# --- 認証 ---
Connect-MgGraph -Scopes "Device.Read.All" -NoWelcome
Write-Host "デバイス情報を取得中..." -ForegroundColor Cyan
# Entra ID に登録されたすべての Windows デバイスを取得(ページング対応)
$allDevices = Get-MgDevice -Filter "operatingSystem eq 'Windows'" -All -Property `
DisplayName, `
OperatingSystem, `
OperatingSystemVersion, `
ApproximateLastSignInDateTime, `
AccountEnabled, `
DeviceId, `
TrustType, `
ProfileType
Write-Host "取得デバイス総数: $($allDevices.Count)" -ForegroundColor Green
# Windows 10 の判定:バージョンが "10.0.1" で始まり "10.0.22" 未満
# Windows 10 の最終ビルドは 10.0.19045.x (22H2)
# Windows 11 は 10.0.22000 以上
$win10Devices = $allDevices | Where-Object {
$osVer = $_.OperatingSystemVersion
if ([string]::IsNullOrEmpty($osVer)) { return $false }
# Windows 10 は 10.0.10240 〜 10.0.19045 の範囲
$buildNumber = ($osVer -split '\.')[2] -as [int]
return ($buildNumber -ge 10240 -and $buildNumber -le 19045)
}
Write-Host "Windows 10 デバイス数: $($win10Devices.Count)" -ForegroundColor Yellow
# 結果を整形
$results = $win10Devices | Select-Object `
@{N='デバイス名'; E={$_.DisplayName}},
@{N='OSバージョン'; E={$_.OperatingSystemVersion}},
@{N='最終サインイン'; E={
if ($_.ApproximateLastSignInDateTime) {
[DateTime]$_.ApproximateLastSignInDateTime | Get-Date -Format 'yyyy-MM-dd HH:mm'
} else { '不明' }
}},
@{N='有効'; E={$_.AccountEnabled}},
@{N='デバイスID'; E={$_.DeviceId}},
@{N='参加形態'; E={$_.TrustType}}
# CSV 出力
$results | Export-Csv -Path $OutputPath -Encoding UTF8BOM -NoTypeInformation
Write-Host "CSV 出力完了: $OutputPath" -ForegroundColor Green
# サマリー表示
Write-Host "`n=== Windows OS バージョン別集計 ===" -ForegroundColor Cyan
$allDevices | Group-Object {
$ver = $_.OperatingSystemVersion
if ([string]::IsNullOrEmpty($ver)) { return '不明' }
$build = ($ver -split '\.')[2] -as [int]
switch ($true) {
($build -ge 22000) { 'Windows 11'; break }
($build -ge 10240) { 'Windows 10'; break }
default { "その他 (Build $build)" }
}
} | Sort-Object Name | Format-Table Name, Count -AutoSize
Disconnect-MgGraph
Part 2:Intune 管理デバイスから詳細情報を取得する
Intune 登録デバイスからは、OS バージョンに加えてインストール済みアプリ情報も取得できます。ただしアプリ一覧の取得は API の制限により端末ごとの個別取得になるため、台数が多い場合は時間がかかります。
スクリプト:Intune デバイス棚卸し + OS 集計
<#
.SYNOPSIS
Intune 管理デバイスの Windows バージョンを棚卸しして CSV に出力する
.DESCRIPTION
Microsoft Graph API の /deviceManagement/managedDevices エンドポイントを使用
必要スコープ: DeviceManagementManagedDevices.Read.All
#>
[CmdletBinding()]
param(
[string]$OutputPath = ".\intune-inventory-$(Get-Date -Format 'yyyyMMdd').csv"
)
# --- 認証 ---
Connect-MgGraph -Scopes "DeviceManagementManagedDevices.Read.All" -NoWelcome
Write-Host "Intune 管理デバイスを取得中..." -ForegroundColor Cyan
# Intune 登録デバイスを全件取得
$managedDevices = Get-MgDeviceManagementManagedDevice -All -Property `
DeviceName, `
OperatingSystem, `
OsVersion, `
LastSyncDateTime, `
ComplianceState, `
EnrolledDateTime, `
UserDisplayName, `
UserPrincipalName, `
Manufacturer, `
Model, `
SerialNumber, `
Id
Write-Host "Intune 管理デバイス総数: $($managedDevices.Count)" -ForegroundColor Green
# Windows デバイスのみ絞り込み
$windowsDevices = $managedDevices | Where-Object { $_.OperatingSystem -eq 'Windows' }
# バージョン分類関数
function Get-WindowsCategory {
param([string]$OsVersion)
if ([string]::IsNullOrEmpty($OsVersion)) { return '不明' }
# OsVersion の形式: "10.0.19045.4529" など
$parts = $OsVersion -split '\.'
if ($parts.Count -lt 3) { return '不明' }
$build = $parts[2] -as [int]
switch ($true) {
($build -ge 22000) { return 'Windows 11' }
($build -eq 19045) { return 'Windows 10 22H2(最終版)' }
($build -ge 10240 -and $build -lt 19045) { return 'Windows 10(旧バージョン)' }
default { return "不明 (Build $build)" }
}
}
# 結果整形
$results = $windowsDevices | Select-Object `
@{N='デバイス名'; E={$_.DeviceName}},
@{N='OSバージョン'; E={$_.OsVersion}},
@{N='Windowsカテゴリ'; E={Get-WindowsCategory $_.OsVersion}},
@{N='最終同期'; E={
if ($_.LastSyncDateTime) {
[DateTime]$_.LastSyncDateTime | Get-Date -Format 'yyyy-MM-dd HH:mm'
} else { '未同期' }
}},
@{N='コンプライアンス'; E={$_.ComplianceState}},
@{N='ユーザー名'; E={$_.UserDisplayName}},
@{N='UPN'; E={$_.UserPrincipalName}},
@{N='メーカー'; E={$_.Manufacturer}},
@{N='モデル'; E={$_.Model}},
@{N='シリアル番号'; E={$_.SerialNumber}},
@{N='登録日'; E={
if ($_.EnrolledDateTime) {
[DateTime]$_.EnrolledDateTime | Get-Date -Format 'yyyy-MM-dd'
} else { '不明' }
}}
$results | Export-Csv -Path $OutputPath -Encoding UTF8BOM -NoTypeInformation
Write-Host "CSV 出力完了: $OutputPath" -ForegroundColor Green
# 集計表示
Write-Host "`n=== Windows バージョン別台数 ===" -ForegroundColor Cyan
$results | Group-Object 'Windowsカテゴリ' | Sort-Object Count -Descending |
Format-Table Name, Count -AutoSize
Write-Host "`n=== コンプライアンス状態別 ===" -ForegroundColor Cyan
$results | Group-Object 'コンプライアンス' | Sort-Object Count -Descending |
Format-Table Name, Count -AutoSize
Disconnect-MgGraph
Part 3:Intune でインストール済み Office バージョンを確認する
Intune 管理下のデバイスでは、Graph API 経由でインストール済みアプリを取得できます。ただし /deviceAppManagement/managedDevices/{id}/detectedApps エンドポイントは1デバイスごとの取得となるため、件数が多い場合はバッチ処理が必要です。
<#
.SYNOPSIS
Intune デバイスから Office 2021 インストール台数を集計する
.NOTES
デバイス数が多い場合は -MaxDevices で上限を設定して段階的に実行すること
必要スコープ: DeviceManagementManagedDevices.Read.All
DeviceManagementApps.Read.All
#>
[CmdletBinding()]
param(
[int]$MaxDevices = 50, # 一度に処理するデバイス数の上限(API負荷軽減)
[string]$OutputPath = ".\office-inventory-$(Get-Date -Format 'yyyyMMdd').csv"
)
Connect-MgGraph -Scopes `
"DeviceManagementManagedDevices.Read.All",
"DeviceManagementApps.Read.All" `
-NoWelcome
$managedDevices = Get-MgDeviceManagementManagedDevice `
-Filter "operatingSystem eq 'Windows'" `
-Top $MaxDevices `
-Property DeviceName, Id, UserDisplayName
Write-Host "対象デバイス数: $($managedDevices.Count)(上限: $MaxDevices)" -ForegroundColor Cyan
$officeResults = [System.Collections.Generic.List[PSCustomObject]]::new()
$counter = 0
foreach ($device in $managedDevices) {
$counter++
Write-Progress -Activity "アプリ情報取得中" `
-Status "$counter / $($managedDevices.Count): $($device.DeviceName)" `
-PercentComplete (($counter / $managedDevices.Count) * 100)
try {
# デバイスの検出済みアプリを取得
$detectedApps = Get-MgDeviceManagementManagedDeviceDetectedApp `
-ManagedDeviceId $device.Id `
-All
# Office 2021 / Office LTSC 2021 を含むアプリを抽出
$officeApps = $detectedApps | Where-Object {
$_.DisplayName -match 'Office' -and (
$_.DisplayName -match '2021' -or
$_.DisplayName -match 'LTSC'
)
}
if ($officeApps) {
foreach ($app in $officeApps) {
$officeResults.Add([PSCustomObject]@{
デバイス名 = $device.DeviceName
ユーザー = $device.UserDisplayName
アプリ名 = $app.DisplayName
バージョン = $app.Version
要対応 = '対象(Office 2021)'
})
}
} else {
# Office 系アプリが見つからない、または Microsoft 365 Apps の場合
$m365Apps = $detectedApps | Where-Object {
$_.DisplayName -match 'Microsoft 365' -or
($_.DisplayName -match 'Office' -and $_.DisplayName -notmatch '2021|2019|2016|2013')
}
$officeResults.Add([PSCustomObject]@{
デバイス名 = $device.DeviceName
ユーザー = $device.UserDisplayName
アプリ名 = if ($m365Apps) { $m365Apps[0].DisplayName } else { '未検出' }
バージョン = if ($m365Apps) { $m365Apps[0].Version } else { '-' }
要対応 = if ($m365Apps) { '対象外(M365 Apps)' } else { '要確認' }
})
}
} catch {
$officeResults.Add([PSCustomObject]@{
デバイス名 = $device.DeviceName
ユーザー = $device.UserDisplayName
アプリ名 = 'エラー'
バージョン = '-'
要対応 = "取得失敗: $($_.Exception.Message)"
})
}
}
Write-Progress -Completed -Activity "完了"
$officeResults | Export-Csv -Path $OutputPath -Encoding UTF8BOM -NoTypeInformation
Write-Host "`nCSV 出力完了: $OutputPath" -ForegroundColor Green
Write-Host "`n=== Office 対応状況サマリー ===" -ForegroundColor Cyan
$officeResults | Group-Object '要対応' | Sort-Object Count -Descending |
Format-Table Name, Count -AutoSize
Disconnect-MgGraph
Part 4:3スクリプトの実行順序と運用のポイント
推奨実行順序
1. Part 1(Entra ID 全デバイス)
└─ 全社 Windows 端末の全体像を掴む
2. Part 2(Intune 詳細)
└─ 詳細なバージョン・コンプライアンス状態を確認
3. Part 3(Office バージョン)
└─ Office 2021 対象台数を特定
Intune 未登録デバイスへの対応
Intune に登録されていないデバイスは、これらのスクリプトでは検出されません。BYOD デバイスや古い端末が登録されていない場合は、Active Directory の Get-ADComputer や WSUS のレポート機能を補完的に使用してください。
# Active Directory から Windows 10 端末を抽出する補完スクリプト
# 必要: RSAT ActiveDirectory モジュール
Import-Module ActiveDirectory
$adWin10 = Get-ADComputer -Filter {
OperatingSystem -like "*Windows 10*"
} -Properties Name, OperatingSystem, OperatingSystemVersion, LastLogonDate |
Select-Object Name, OperatingSystem, OperatingSystemVersion,
@{N='最終ログオン'; E={$_.LastLogonDate | Get-Date -Format 'yyyy-MM-dd'}}
$adWin10 | Export-Csv -Path ".\ad-win10-$(Get-Date -Format 'yyyyMMdd').csv" `
-Encoding UTF8BOM -NoTypeInformation
Write-Host "AD 上の Windows 10 端末: $($adWin10.Count) 台"
棚卸し後の対応
棚卸しで現状が把握できたら、次のアクションに移ります:
- Windows 10 端末:TPM 2.0 確認 → Windows 11 アップグレード可否判定 → PC更新計画策定
- Office 2021:Microsoft 365 Apps(サブスク)または Office LTSC 2024(買い切り)への移行計画
- Windows Server 2012(別スクリプトが必要):Azure 移行 / オンプレ更改の判断
情シス365 では、こうした棚卸しの代行から移行計画策定・実行支援まで、中小企業向けに提供しています。スクリプトの実行環境がない、Intune を導入していないというケースでも対応可能です。
まとめ
| スクリプト | 取得情報 | 必要ロール |
|---|---|---|
| Part 1 | Entra ID 全デバイス + OS バージョン | Device.Read.All |
| Part 2 | Intune デバイス + 詳細バージョン | DeviceManagementManagedDevices.Read.All |
| Part 3 | インストール済み Office バージョン |
DeviceManagementManagedDevices.Read.All + DeviceManagementApps.Read.All
|
2026年10月13日まで約4か月。まず棚卸しから始めることで、対応の優先順位と必要コストを正確に把握できます。
著者:亀田 英佑
株式会社BTNコンサルティング 代表取締役 / 情シス365 運営
中小企業の IT リスク管理・アウトソーシングを専門とする。