WMI/CIMをC#・PowerShellから使う ── ハードウェア情報取得・プロセス監視・リモート照会の実務ガイド

· 更新日: · · Windows, C#, .NET, PowerShell, WMI, CIM, 業務アプリ, Windows開発

更新履歴(5件・最終更新 2026年09月07日)

この記事に加えた変更の記録です。アーカイブした更新前のバージョンは、DOI付きの固定URLから読めます。

WMI/CIMの解説を、用途の判断、仕組み、PowerShellでの試作、リモート接続、C#への組み込み、イベント監視、障害切り分けの順に整理した。元の主張・条件、コード例、比較表、出典、FAQと知識マップを保持し、接続方式と前提条件、照会と購読、型と日付の扱いを近接させた。図番号と章参照を更新した。
知識マップの関係を総点検し、説明文と食い違っていた関係(向きの逆転・過剰な一般化・述語の取り違え)を修正しました。本文の説明は変えていません。
知識マップの関係を総点検し、説明文と食い違っていた関係(向きの逆転・過剰な一般化・述語の取り違え)を修正しました。本文の説明は変えていません。
知識マップの「イベント購読はポーリングに推奨される」という関係を、「イベント購読はポーリングを置き換える」に改めました。本文の説明は変えていません。
仕組みの説明を図で追えるよう、Mermaid図を19点追加しました。業務アプリの定番要求とWMI/CIMの対応、CIM標準とWMI実装の関係、WQL照会が名前空間からプロバイダーへたどる構造、CimInstanceのメソッド呼び出し、新規スクリプトをCIMコマンドレットで書く理由、リモート接続方式の選び方とWinRMの前提構成、PowerShellでの試作からC#への書き写し、プロパティのキャストの落とし穴、エージェントなしディスク監視の土台、プロセス起動イベント購読の流れと2つの購読方式の対比、常駐監視の購読再登録、照会の絞り込みによる性能対策、一般ユーザー環境での監視構成、64bit環境でのプロバイダー選択、リポジトリ不整合時の切り分け手順、DMTF日付形式の扱い、手段の判断の軸を図にしています。本文の文章とコード、参考リンクは変えていません。
初版公開
この記事を引用する(DOI: 10.5281/zenodo.22054225)

この記事はZenodoにアーカイブされています。常に最新版へ解決されるDOIと、いま表示している版に固定されたDOIの両方を下に示します。

小村 豪(2026)「WMI/CIMをC#・PowerShellから使う ── ハードウェア情報取得・プロセス監視・リモート照会の実務ガイド」合同会社小村ソフト. https://doi.org/10.5281/zenodo.22054225 https://comcomponent.com/blog/wmi-cim-practical-guide/

DOI(最新版)
10.5281/zenodo.22054225
DOI(この版)
10.5281/zenodo.22639733

「PCのシリアル番号と機種名を表示したい」「サーバーのディスク空きを調べたい」「プロセスの起動を検知したい」。Windowsの業務アプリや管理ツールで、こうした情報を共通の方法で扱えるのが WMI/CIM です。

CIMは管理情報を表す標準モデル、WMIはその標準を使うWindowsの管理基盤です。PowerShellのCIMコマンドレットとC#のAPIは、この基盤へアクセスする入口になります。1

定番要求とWMI/CIMシリアル番号と機種名の表示、ディスク空き容量の監視、プロセス起動の検知、リモートPCの照会という業務アプリ定番の要求への定番の答えがWMIであり、管理情報の表現にはCIM標準を使うシリアル番号・機種名WMI(CIM標準を使う基盤)ディスク空き容量の監視プロセス起動の検知リモートPCの照会

図1: 業務アプリ定番の4つの要求に対する定番の答えがWMI/CIM。

迷いやすいのは、入口が複数あることです。検索結果には旧Get-WmiObjectGet-CimInstanceが混在し、C#にもSystem.ManagementMicrosoft.Management.Infrastructureがあります。旧WMIコマンドレットはWindows PowerShell 5.1では使えても、PowerShell 7にはありません。2

この記事は、ハードウェア情報取得・プロセス監視・リモートPC照会を実装するC#/PowerShell開発者向けです。まずWMIを選ぶべきかを判断し、PowerShellで試し、接続条件を確認してC#へ組み込み、監視と障害対応まで整える順に説明します。2026年8月時点の一次情報を土台に、実例と注意点を整理しています。

1. まず結論:用途と接続先から入口を選ぶ

新しく書くPowerShellはCIMコマンドレットを使い、C#は用途に応じてAPIを選びます。ただし、専用の仕組みで済む処理までWMIへ寄せる必要はありません。

判断・作業 基本方針 説明する章
WMIを使うべきか決める 横断的な情報取得・リモート照会に使い、設定や高頻度の性能監視は専用の仕組みを選ぶ 2章
何を照会するか決める 名前空間、クラス、プロパティを選び、WQLで対象を絞る。日常の既定はroot/CIMV23 3章・4章
PowerShellで試す Get-CimInstanceで読み、Invoke-CimMethodで操作する。5.1向けの新規コードもCIM側で書く2 4章
リモートへ広げる WSMan/WinRMを基本にし、同じ相手への複数操作はCIMセッションを使い回す。必要ならDCOMを選ぶ34 5章
C#へ組み込む ローカルの手軽な照会はSystem.Management、リモートや監視の組み込みはMI APIを検討する56 6章
プロセス起動を監視する イベント購読を使い、権限、購読の解除、切断後の再登録も設計する78 7章
遅い・値が違う・クラスが見つからない原因を調べる 照会の量と頻度、プロバイダーのビット数、リポジトリの整合性を切り分ける 8章

特に、一覧を取得できることと、イベントを購読できることは別です。Win32_ProcessStartTraceの購読例は管理者権限で実行します。7 また、SELECT *や短周期ポーリングを惰性で使わず、-Filter-Property-KeyOnlyで必要な情報に絞ります。3

図の実線は常に成り立つ関係、破線は条件付きの関係です(成立条件は詳細ページの各関係の説明に記載)。関係すべての一覧(全26件、根拠・確度つき)と主要概念の定義は知識マップ詳細ページにまとめています。データ: JSON-LD / Turtle

2. WMI/CIMを使う場面・専用の仕組みを選ぶ場面

WMIは「統一された読み取り口」としては優秀ですが、常に最適解ではありません。実務での使い分けの目安です。

やりたいこと 適した手段 WMIを選ばない理由
ハードウェア情報・OS構成の取得、エージェントなしのリモート照会 WMI/CIM ここがWMIの本領。専用APIを個別に叩くより統一的
自アプリの設定の読み書き レジストリ直読(Microsoft.Win32.Registry)・構成ファイル WMI経由のレジストリ操作は遠回りで、8.2節のビット数問題も背負い込む
CPU使用率などの高頻度・連続的な性能監視 パフォーマンスカウンター(System.Diagnostics.PerformanceCounter 等) counterはそのための仕組み。WMIの短周期ポーリングは負荷と精度で不利
単発のOS機能呼び出し・低レイテンシーが必要な処理 Win32 API(P/Invoke) WMIはCOM/プロバイダーを経由する分のオーバーヘッドがある
自プロセス権限で足りるローカルのプロセス列挙・操作 System.Diagnostics.Process 標準ライブラリで完結し、依存が減る
ファイアウォール・ネットワーク等のWindows管理機能の構成 Get-NetFirewallRule などの専用CIMベースコマンドレット 生のWMIクラスを探すより、用途別に整備されたコマンドレット群が正確で安全
ファイル・フォルダーの変更検知 FileSystemWatcher 専用APIがある領域にWMIを持ち込まない

判断の軸は単純で、「専用の仕組みがある領域では専用の仕組みを使い、横断的な照会・リモート照会にWMI/CIMを使う」です。表の Get-NetFirewallRule などは内部的にはCIMの上に構築されたコマンドレット群であり、「WMI/CIMを直接触らずに、その恩恵だけ受ける」形と言えます。

手段の判断の軸専用の仕組みがある領域では専用の仕組みを使い、ない領域の横断的な照会やリモート照会にWMIとCIMを使うのが判断の軸で、専用CIMベースコマンドレットはWMIとCIMを直接触らずに恩恵だけ受ける形であるあるない専用の仕組みがある?専用の仕組みを使うWMI / CIMを使う横断的な照会・リモート照会専用CIMベースコマンドレット恩恵だけ受ける形

図2: 専用の仕組みがある領域では専用を使い、横断的な照会とリモート照会にWMI/CIMを使う。

3. 仕組みを押さえる:標準、名前空間、クラス、WQL

3.1. CIMは標準、WMIはWindows上の実装

まず用語の関係を1回で整理します。

用語 正体
CIM (Common Information Model) システム・アプリ・ネットワーク・デバイスなどの管理対象を表現する業界標準モデル。DMTF(Distributed Management Task Force)が策定・維持1
WBEM (Web-Based Enterprise Management) 企業環境の管理情報へアクセスする標準技術を作る業界イニシアティブ1
WMI WBEMのMicrosoft実装。CIM標準を使って管理対象を表現し、Windowsに組み込まれている1
MI (Windows Management Infrastructure) WMIの次世代版。従来のWMIと完全互換で、新しいプロバイダーの多くはMIで書かれている1
CIM標準とWMI実装の関係DMTFが策定・維持するCIM標準をWBEMイニシアティブの枠組みで使い、そのMicrosoft実装がWMIで、次世代版のMIは従来のWMIと完全互換であり、CIM系APIの接続先は同じWMI基盤であるDMTFが策定・維持CIM(業界標準モデル)WBEM(業界イニシアティブ)WMI(Microsoft実装)MI(次世代版・完全互換)CIM系API(PowerShell / C#)

図3: CIMが仕様、WMIがWindows上の実装。CIM系APIの接続先は同じWMI基盤。

3.2. 名前空間・クラス・プロバイダー・WQLをつなげて読む

開発者として押さえるべき構造は次の4つです。

  • 名前空間(namespace): クラスを束ねる階層です。日常の照会で使うのはほぼ root/CIMV2 で、CIMコマンドレットの既定もここです。3 ほかに root\default(レジストリプロバイダーなど)等があります。
  • クラス: Win32_ComputerSystem(コンピューター本体)、Win32_LogicalDisk(論理ドライブ)、Win32_Process(プロセス)のような管理対象の型です。CIM標準のクラス(CIM_LogicalDisk など)を継承したWindows固有クラスが Win32_ の接頭辞を持ちます。9
  • プロバイダー: クラスの実体を提供するコンポーネントです。照会するとプロバイダーがその場でOSに問い合わせて値を作ります。
  • WQL: SQLに似た照会言語です。SELECT Name, State FROM Win32_Service WHERE StartMode = 'Auto' のように、クラスをテーブルに見立てて絞り込みます。CIMコマンドレットの既定の照会言語もWQLです。3

「OSやハードウェアの情報を、統一されたクラスとクエリ言語で読める」── これがWMIの価値です。ただし、すべてのクラスで書き込みや操作ができるわけではありません。メソッドのあるクラスはInvoke-CimMethodで操作し、書き込み可能なプロパティの変更はSet-CimInstanceで行います。4.1節の対応表のとおり、クラスが提供する機能に合わせて入口を選びます。

WMI照会の構造WQLの照会は名前空間root/CIMV2の中のWin32_*クラスに向けられ、クラスの実体を提供するプロバイダーがその場でOSに問い合わせて値を作り、結果が返るWQLで照会名前空間 root/CIMV2Win32_*クラスプロバイダーその場でOSに問い合わせ結果を返す

図4: 照会は名前空間、クラス、プロバイダーの順にたどり、値はその場で作られる。

4. PowerShellで試す:読み取り・メソッド呼び出し・資産情報

ここからはWindows上のPowerShellで試します。旧コードから移す場合も、最初にコマンドレットの対応と、戻り値の扱いの違いを確認してください。

4.1. 新規コードはCIMコマンドレットで書く

PowerShell 6以降(現行のPowerShell 7)では、次のWMI v1コマンドレットが削除されています。同じ機能はCimCmdletsモジュール(WMI v2)が提供します。2

旧(Windows PowerShell 5.1まで) 現行(CIMコマンドレット) 補足
Get-WmiObject Get-CimInstance -Filter / -Query の考え方は同じ
Get-WmiObject -List Get-CimClass クラスの探索・定義の確認
Invoke-WmiMethod Invoke-CimMethod 引数は -Arguments @{ } のハッシュテーブルで渡す
Register-WmiEvent Register-CimIndicationEvent イベント購読(7章)
Set-WmiInstance Set-CimInstance 書き込み可能プロパティの変更
Remove-WmiObject Remove-CimInstance インスタンスの削除

Windows PowerShell 5.1でもCIMコマンドレットは使えるので、新しく書くものは5.1で動かす場合でもCIM側で書くのが移行コストを残さない書き方です。5.1と7の共存・移行の全体像は「Windows PowerShell 5.1とPowerShell 7の違い」にまとめています。

新規スクリプトをCIMで書く理由WMIコマンドレットで書いたスクリプトは5.1では動くもののPowerShell 6以降で削除済みのため移行時に書き直しが必要になり、CIMコマンドレットは5.1でも使えるため新しく書くものはCIM側で書けば移行コストが残らないWMIコマンドレットCIMコマンドレット新しく書くスクリプトどちらで書く?5.1では動く5.1でも使えるPowerShell 7で削除済み移行時に書き直し移行コストが残らない

図5: 新規はCIMコマンドレットで書いておけば、PowerShell 7への移行時に書き直しが要らない。

4.2. Get-CimInstanceで行と列を絞って読む

# クラス指定(既定の名前空間 root/CIMV2)
Get-CimInstance -ClassName Win32_OperatingSystem

# WHERE句だけを -Filter に書く(WHEREキーワードは書かない)
Get-CimInstance -ClassName Win32_Service -Filter "StartMode = 'Auto' AND State <> 'Running'"

# 必要なプロパティだけ取得して転送量を減らす
Get-CimInstance -ClassName Win32_Process -Property Name, ProcessId, CreationDate

# WQLをそのまま書くなら -Query
Get-CimInstance -Query "SELECT * FROM Win32_Process WHERE Name LIKE 'p%'"

-Filter はWQLのWHERE句そのもの、-Property は取得列の限定です。3 戻り値は CimInstance オブジェクトで、日付プロパティ(CreationDateLastBootUpTime など)は DateTime に変換済みで返ります。

4.3. メソッドはInvoke-CimMethodで呼ぶ

Get-WmiObject と違い、取得したオブジェクトからWMIのメソッドを直接呼ぶ形ではないため、メソッド呼び出しは Invoke-CimMethod に渡します。

CimInstanceのメソッド呼び出しGet-CimInstanceが返すCimInstanceは日付プロパティがDateTime変換済みで返る一方でWMIメソッドを直接呼び出す形ではないため、メソッド呼び出しはインスタンスをInvoke-CimMethodに渡して行うGet-CimInstanceCimInstanceオブジェクト日付はDateTime変換済みWMIメソッドは別の入口へInvoke-CimMethodに渡すメソッド呼び出し

図6: CimInstanceのWMIメソッドは直接呼び出さず、メソッド呼び出しはInvoke-CimMethodに渡して行う。

# インスタンスのメソッドを呼ぶ: 各プロセスの所有者を取得
Get-CimInstance -ClassName Win32_Process -Filter "Name = 'notepad.exe'" |
    Invoke-CimMethod -MethodName GetOwner

# クラスの静的メソッドを呼ぶ: プロセスを起動
Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments @{ CommandLine = 'notepad.exe' }

# クラス定義(プロパティ・メソッド一覧)を調べる
Get-CimClass -ClassName Win32_Process

4.4. 取得したい情報からクラスを選ぶ

取りたい情報 クラス 主なプロパティ
メーカー・機種名 Win32_ComputerSystem Manufacturer, Model
本体シリアル番号 Win32_BIOS SerialNumber
OSの版・起動時刻 Win32_OperatingSystem Caption, Version, LastBootUpTime
ディスク空き容量 Win32_LogicalDisk DeviceID, FreeSpace, Size, DriveType9
サービス状態 Win32_Service Name, State, StartMode
プロセス一覧 Win32_Process Name, ProcessId, CommandLine

4.5. 資産管理の例:機種・シリアル番号・ディスク空き

# 機種情報とシリアル番号(PC資産台帳の突合せに)
$cs   = Get-CimInstance -ClassName Win32_ComputerSystem -Property Manufacturer, Model
$bios = Get-CimInstance -ClassName Win32_BIOS -Property SerialNumber
[pscustomobject]@{
    Manufacturer = $cs.Manufacturer
    Model        = $cs.Model
    Serial       = $bios.SerialNumber
}

# ローカルディスク(DriveType = 3)の空き容量
Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType = 3" |
    Select-Object DeviceID,
        @{ Name = 'FreeGB'; Expression = { [math]::Round($_.FreeSpace / 1GB, 1) } },
        @{ Name = 'SizeGB'; Expression = { [math]::Round($_.Size / 1GB, 1) } }

DriveType = 3 は「ローカルディスク」を表す値で、リムーバブル(2)やネットワークドライブ(4)、CD(5)を除外します。9 5章の接続条件を満たしたうえで、このスクリプトをCIMセッション経由で各サーバーに回すと、エージェントなしのディスク監視の土台ができます。

エージェントなしディスク監視の土台DriveType 3の絞り込みでリムーバブルやネットワークドライブやCDを除外してローカルディスクだけを対象にし、同じスクリプトをCIMセッション経由で各サーバーに回すことで、エージェントなしのディスク監視の土台ができる空き容量取得スクリプトDriveType = 3で絞るリムーバブル等を除外CIMセッション経由各サーバーに回すエージェントなし監視

図7: ローカルディスクに絞ったスクリプトをCIMセッションで各サーバーに回すのが監視の土台。

5. リモートへ広げる:接続方式と前提条件

5.1. ローカルとリモートで接続方式が変わる

-CimSessionを渡さないCIMコマンドレットは、-ComputerNameも指定しなければローカルのWMIにCOMで接続し、-ComputerName を指定するとWSMan(WinRM)プロトコルで一時セッションを作って接続します。同じコンピューターに複数の操作を行う場合は、CIMセッションを作って使い回す方が性能上有利です。3

CIM接続方式の選択CimSessionを渡さない場合、ComputerName指定なしはローカルWMIへCOM接続、ComputerName指定はWSManの一時セッションが照会のたびに作られ、同じ相手への複数操作はNew-CimSessionの使い回しが性能上有利で、WinRM未構成の相手にはDCOMプロトコルオプションがあるなしあり単発複数CimSessionを渡さず実行ComputerName指定?ローカルWMIへCOM接続同じ相手に複数操作?WSManの一時セッションNew-CimSessionを使い回す照会のたびに作成されるWinRM未構成の相手DCOMプロトコルオプション

図8: リモート照会はWSManが既定で、同じ相手への複数操作はCIMセッションの使い回しが定石。

5.2. WinRM・ファイアウォール・認証・権限を準備する

WSMan/WinRMで照会する場合の前提は次のとおりです。接続処理を書く前に、サービス・通信経路・認証・権限を分けて確認します。

  • 接続先でWinRMが構成されていること。winrm quickconfig が、サービスの自動起動化・HTTPリスナー(既定ポート5985)の作成・ファイアウォール例外の登録を一括で行います。10 HTTPS(既定ポート5986)で接続したい場合はこれだけでは足りず、サーバー証明書を用意したうえで winrm quickconfig -transport:https などでHTTPSリスナーを別途構成する必要があります。10
  • 経路のファイアウォールで該当ポートが開いていること。受信規則の設計と登録の実務は「Windowsファイアウォールと業務アプリ」の記事で扱ったとおりです。
  • 認証。ドメイン環境ならKerberosで相互認証されます。ワークグループではKerberosが使えないため、クライアント側の TrustedHosts への登録が必要になる場合があります。登録先は必要最小限に絞ります。10
  • 権限。既定の構成では、リモートのWMI照会・操作は接続先の管理者グループに属するアカウントで行うのが基本です。一般ユーザーに開放する場合は、WinRMとWMI名前空間の両方でアクセス許可の構成が必要になります。10
リモート照会の前提の確認接続先ではwinrm quickconfigがサービスの自動起動化とHTTPリスナー作成とファイアウォール例外登録を一括で行い、HTTPSリスナーは証明書を用意して別途構成し、ワークグループ環境ではTrustedHostsへの登録が必要になる場合があるwinrm quickconfigサービスの自動起動化HTTPリスナー作成(5985)ファイアウォール例外HTTPSリスナー(5986)証明書を用意し別途構成ワークグループ環境必要な場合に限定して登録

図9: winrm quickconfigは既定構成を一括で行い、HTTPSリスナーとワークグループの認証は別途対応する。

5.3. 同じ相手への複数操作はCIMセッションを使い回す

# 単発なら -ComputerName(1回ごとに一時セッションが作られる)
Get-CimInstance -ClassName Win32_ComputerSystem -ComputerName Server01, Server02

# 繰り返し照会するならCIMセッションを使い回す
$session = New-CimSession -ComputerName Server01
Get-CimInstance -ClassName Win32_OperatingSystem -CimSession $session
Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType = 3" -CimSession $session
Remove-CimSession $session

5.4. WinRMを構成できない相手にはDCOMを検討する

WinRMを構成できない古いマシンなど、WSManで接続できない相手にはDCOMプロトコルを選べます。4

$dcom = New-CimSessionOption -Protocol Dcom
$session = New-CimSession -ComputerName OldServer -SessionOption $dcom

DCOMはRPCの動的ポートも使うため、ファイアウォールをまたぐ設計が難しくなります。これから作る仕組みはWSManを既定と考えるのが無難です。

セッション例は接続方法を示したものです。組み込み時には、途中で照会に失敗してもRemove-CimSessionへ到達するよう、try / finallyなどで後始末を保証してください。DCOMの例で作ったセッションも同様に解除します。

6. C#へ組み込む:二つのAPIと型・日付の扱い

6.1. 二つのAPIを用途で選ぶ

C#からWMIを使うAPIは2系統あります。どちらもWindows専用です。

  System.Management Microsoft.Management.Infrastructure (MI API)
導入 .NET Frameworkは標準。現行の.NETではNuGetパッケージ System.Management5 NuGetパッケージ Microsoft.Management.Infrastructure6
入口クラス ManagementObjectSearcher(WQLを渡して照会)5 CimSession(Create → QueryInstances / InvokeMethod / Subscribe)6
型体系 ManagementObject / ManagementEventWatcher11 CimInstance / CimSession ── CIMコマンドレットと同じ型3
リモート DCOMベース WSMan(CIMセッション)ベース。非同期版(*Async)あり6
向いている場面 ローカルの情報取得。既存コード資産の維持 リモート照会・監視の組み込み。PowerShell併用の設計

6.2. System.Management:WQLを渡し、CIM型に合わせて読む

WQLを文字列で渡し、Get() で結果コレクションを受け取ります。5

// NuGet: System.Management(Windows専用)
using System.Management;

using var searcher = new ManagementObjectSearcher(
    @"root\cimv2",
    "SELECT DeviceID, FreeSpace, Size FROM Win32_LogicalDisk WHERE DriveType = 3");

foreach (ManagementObject disk in searcher.Get())
{
    var freeGb = (ulong)disk["FreeSpace"] / 1024.0 / 1024.0 / 1024.0;
    var sizeGb = (ulong)disk["Size"] / 1024.0 / 1024.0 / 1024.0;
    Console.WriteLine($"{disk["DeviceID"]} 空き {freeGb:F1} GB / 全体 {sizeGb:F1} GB");
}

プロパティはインデクサーで object として返るため、クラスのドキュメントでCIM型(この例では FreeSpace / Size は uint649)を確認してキャストします。型を確認せず int と思い込んでキャストすると InvalidCastException になる、というのが最初の定番のつまずきです。

プロパティ取得とキャストの落とし穴System.Managementのプロパティはインデクサーでobjectとして返るため、クラスのドキュメントでCIM型を確認してキャストする必要があり、intと思い込んでキャストするとInvalidCastExceptionになるインデクサーで取得objectとして返るドキュメントでCIM型確認正しい型へキャストintと思い込みキャストInvalidCastException

図10: プロパティはobjectで返るため、CIM型を確認してからキャストする。

6.3. MI API:PowerShellと同じ型で照会する

CimSession はローカル・リモートを同じ形で扱えます。列挙・照会・メソッド呼び出し・イベント購読と非同期版まで一通り揃っています。6

// NuGet: Microsoft.Management.Infrastructure(Windows専用)
using Microsoft.Management.Infrastructure;

// ローカルなら CimSession.Create(null)、リモートならコンピューター名を渡す
using CimSession session = CimSession.Create(null);

IEnumerable<CimInstance> disks = session.QueryInstances(
    @"root\cimv2", "WQL",
    "SELECT DeviceID, FreeSpace, Size FROM Win32_LogicalDisk WHERE DriveType = 3");

foreach (CimInstance disk in disks)
{
    var deviceId = (string)disk.CimInstanceProperties["DeviceID"].Value;
    var free = (ulong)disk.CimInstanceProperties["FreeSpace"].Value;
    Console.WriteLine($"{deviceId} 空き {free / 1024.0 / 1024 / 1024:F1} GB");
}

PowerShellのCIMコマンドレットが返すのと同じ CimInstance を扱うので、「PowerShellで試してからC#に書き写す」という開発の流れが素直につながります。C#とPowerShellの連携そのものを設計するなら「C#からPowerShellを実行してオブジェクトで受け取る方法」も参照してください。

PowerShellで試してC#に書き写す流れPowerShellのCIMコマンドレットとC#のMI APIは同じCimInstance型を扱うため、PowerShellで試作してからC#に書き写す開発の流れが素直につながるPowerShellで試作CIMコマンドレットC#で本実装MI API同じCimInstance型書き写しが素直につながる

図11: CIMコマンドレットとMI APIは同じCimInstance型を扱うため、試作から本実装へつながる。

6.4. DMTF日付は手で切り貼りせず変換APIへ渡す

WMIの日付は、CIM仕様のDMTF形式 yyyymmddHHMMSS.mmmmmm±UUU(末尾はUTCからのオフセット分。例: 20260801100000.000000+540)の文字列で格納されています。生の値を文字列処理で切り貼りするのはやめて、変換APIを使います。

  • C# (System.Management): ManagementDateTimeConverter がDMTF形式と DateTime / TimeSpan の相互変換を提供します。11
  • CIM系API(Get-CimInstance / MI API): 日付プロパティは DateTime に変換済みで返るため、そもそもこの問題に遭遇しません。(Get-CimInstance Win32_OperatingSystem).LastBootUpTime はそのまま DateTime として計算に使えます。
DMTF日付形式の扱いWMIの日付はDMTF形式の文字列で格納されており、System.Managementで生の値を読んだ場合はManagementDateTimeConverterで変換し、CIM系APIならDateTimeに変換済みで返るため、自前の文字列の切り貼りはしないSystem.ManagementCIM系APIDMTF形式の文字列どのAPIで取得?ManagementDateTimeConverterDateTime変換済みで返るDateTime / TimeSpanへ変換自前の文字列切り貼り使わない

図12: DMTF文字列の変換は変換APIに任せ、CIM系APIなら変換済みのDateTimeをそのまま使う。

ここでのコードはAPIの基本形です。実際のアプリでは、取得失敗や未設定の値の扱いに加え、結果コレクション・取得オブジェクト・セッションの破棄を、利用するAPIに合わせて実装します。

7. プロセス起動を監視する:権限・購読・解除・再登録

「ポーリングで Win32_Process を定期取得して差分を見る」のではなく、イベント購読にします。プロセスの起動は Win32_ProcessStartTrace(カーネルトレースプロバイダーのイベントクラス。ProcessName / ProcessID / ParentProcessID などを持ちます8)を購読するのが簡単です。

7.1. 最初に実行権限と監視の置き場所を決める

Register-CimIndicationEvent はクラス名またはWQLイベントクエリで購読を登録し、-Action のスクリプトブロックが着信のたびに実行されます。7 このクラスの購読には管理者権限が必要です。7 イベントを誰が受信できるかはイベントクラスのセキュリティ記述子で制御されており、一般ユーザーのままではアクセス拒否になります。8

Win32_ProcessStartTrace 系の購読は管理者権限が前提です。7 「開発機(管理者で実行)では動いたのに、客先の一般ユーザー環境で監視が動かない」という事故は、ファイアウォールの通知ダイアログと並ぶ定番です。一般ユーザーで動かす業務アプリに監視を組み込むなら、監視部分をWindowsサービス(LocalSystem等)に分離し、アプリ本体とはプロセス間通信でつなぐ構成を検討してください。

一般ユーザー環境での監視構成管理者権限が前提の購読は一般ユーザーで動くアプリ本体から切り出し、LocalSystem等で実行するWindowsサービスに監視部分を分離して、アプリ本体とはプロセス間通信でつなぐプロセス間通信監視用Windowsサービス起動トレースを購読LocalSystem等で実行アプリ本体(一般ユーザー)

図13: 管理者権限が要る購読はサービス側に分離し、アプリ本体とはプロセス間通信でつなぐ。

7.2. PowerShellで購読し、監視終了時に解除する

# 管理者権限のPowerShellで実行すること
$action = {
    $name = $Event.SourceEventArgs.NewEvent.ProcessName
    $id   = $Event.SourceEventArgs.NewEvent.ProcessID
    Write-Host "プロセス起動: $name (PID=$id)"
}
Register-CimIndicationEvent -ClassName Win32_ProcessStartTrace `
    -SourceIdentifier ProcessStarted -Action $action

購読は登録したPowerShellセッションに結び付いており、正常に継続している間は、プロセスが起動するたびに -Action が実行されます。解除コマンドまで続けて一気に実行してしまうと、監視が始まる前に購読が消えるだけなので注意してください。

解除は監視を終えるときに実行します。

# 監視を終えるとき: 購読の解除
Unregister-Event -SourceIdentifier ProcessStarted
プロセス起動イベント購読の流れ管理者権限のPowerShellセッションでRegister-CimIndicationEventが購読を登録し、プロセスが起動するたびにイベントが着信してActionが実行され、監視を終えるときにUnregister-Eventで解除するWMIPowerShellセッションWMIPowerShellセッション管理者権限で実行Register-CimIndicationEventで購読登録プロセス起動のたびにイベント着信-Actionを実行Unregister-Eventで解除(監視終了時)

図14: 購読は登録したセッションに結び付き、解除は監視を終えるときに行う。

7.3. WITHINを使う汎用イベントはポーリングである

もう1つの方法が、クラスのインスタンス生成を監視する汎用のインスタンス生成イベント(__InstanceCreationEvent)です。こちらはWMIが WITHIN で指定した間隔でポーリングして差分をイベント化する仕組みなので、検知間隔と負荷のトレードオフを自分で決めることになります。

プロセス起動検知の2つの購読方式Win32_ProcessStartTraceはカーネルトレースプロバイダーのイベントクラスを購読する方式で、汎用の__InstanceCreationEventはWMIがWITHIN指定の間隔でポーリングして差分をイベント化するため検知間隔と負荷のトレードオフを自分で決めるプロセス起動の検知Win32_ProcessStartTrace__InstanceCreationEventカーネルトレースの購読WITHIN間隔でポーリング間隔と負荷のトレードオフ

図15: 専用のイベントクラスを購読するか、汎用のインスタンス生成イベントをポーリング間隔付きで使うか。

# 5秒間隔のポーリングでWin32_Processの新規インスタンスを監視
$query = "SELECT * FROM __InstanceCreationEvent WITHIN 5 WHERE TargetInstance ISA 'Win32_Process'"
Register-CimIndicationEvent -Query $query -SourceIdentifier ProcPoll -Action {
    Write-Host "起動: $($Event.SourceEventArgs.NewEvent.TargetInstance.Name)"
}

7.4. C#ではManagementEventWatcherで受け取る

C#(System.Management)では ManagementEventWatcher が同じ役割です。11

using System.Management;

// 管理者として実行しているプロセスで
var watcher = new ManagementEventWatcher(
    new WqlEventQuery("SELECT * FROM Win32_ProcessStartTrace"));
watcher.EventArrived += (_, e) =>
{
    var name = (string)e.NewEvent["ProcessName"];
    var pid  = (uint)e.NewEvent["ProcessID"];
    Console.WriteLine($"プロセス起動: {name} (PID={pid})");
};
watcher.Start();
// 監視終了時は watcher.Stop() と Dispose を忘れずに

7.5. 常駐監視は購読が切れた後の再登録まで設計する

常駐監視に組み込む場合は、購読が切れたときの再登録(サービス再起動時・エラー時)まで設計に含めてください。デバイス監視を含む「状態の確認と表示」の設計論は「外部機器の状態確認と表示のベストプラクティス」で扱っています。

常駐監視の購読ライフサイクル常駐監視では購読中の状態がサービス再起動やエラーで切れることがあるため、切れたことを検知して再登録し購読中に戻す設計までを含めるサービス再起動・エラー購読中購読が切れた状態再登録

図16: 常駐監視では、購読が切れたときに再登録して購読中へ戻す設計まで含める。

8. 障害を切り分ける:性能・ビット数・リポジトリ

接続できない場合は5.2節、購読だけが拒否される場合は7.1節、キャストや日付の扱いは6.2・6.4節へ戻って確認します。ここでは、それ以外によく出会う「遅い」「値が違う」「クラスが見つからない」を分けます。

8.1. 遅い:取得する量・頻度・セッションを見直す

WMIの照会は「プロバイダーがその場で値を作る」処理であり、タダではありません。定番のアンチパターンは2つです。

  • SELECT * の惰性使用。Win32_Process を全プロパティで全件取得すれば、その分プロバイダーの仕事とネットワーク転送(リモート時)が膨らみます。-Filter で行を、-Property で列を絞り、後続操作のためにキーだけ欲しいなら -KeyOnly を使います。いずれも「オブジェクトのサイズとネットワークトラフィックを減らすため」の公式に用意された手段です。3
  • 短周期ポーリング。「1秒ごとに Get-CimInstance Win32_Process」のような設計は、7章のイベント購読に置き換えます。どうしてもポーリング型(WITHIN)を使う場合も、要件に対して必要十分な間隔まで広げます。

また、リモートに対して1台ずつ -ComputerName で繰り返すのもムダが大きい形です。一時セッションの作成が照会のたびに走るため、複数操作はCIMセッションの使い回しに変えます。3

性能アンチパターンと置き換え先SELECTアスタリスクの惰性使用はFilterとPropertyで行と列を絞りキーだけならKeyOnlyを使い、短周期ポーリングはイベント購読へ、1台ずつのComputerName指定の繰り返しはCIMセッションの使い回しへ置き換えるSELECT *の惰性使用FilterとPropertyで絞るキーだけならKeyOnly短周期ポーリングイベント購読に置き換え1台ずつComputerNameCIMセッションを使い回す

図17: 行・列・キーの絞り込み、適切な監視方式、セッション再利用で不要な負荷を抑える。

8.2. 値が違う:32bit/64bitのプロバイダーを確認する

64bit Windowsではプロバイダーに32bit版と64bit版が併存するものがあり、既定では呼び出し元アプリのビット数に一致する側が応答します。12 典型が root\default のレジストリプロバイダー(StdRegProv)で、32bitアプリから読むと Wow6432Node 側(32bitビュー)の値が返ります。12 「WMIで読んだレジストリ値が、regeditで見た値と違う」ときはまずこれを疑ってください。

逆側のビューが必要な場合は、接続時のコンテキストに __ProviderArchitecture(と、必須にするなら __RequiredArchitecture)を指定して明示的に要求できます。12 ビット数問題の全体像は「C#からWin32 APIを安全に呼ぶ ── P/Invoke実務ガイド」でも扱っています。

64bit環境でのプロバイダー選択既定では呼び出し元アプリのビット数に一致するプロバイダーが応答し、32bitアプリのレジストリ照会はWow6432Node側の値を受け取るが、__ProviderArchitecture指定で逆側のビューを明示的に要求できる32bit64bit呼び出し元のビット数は?32bitプロバイダーが応答64bitプロバイダーが応答レジストリはWow6432Node側の値__ProviderArchitecture指定逆側のビューを明示的に要求

図18: 既定では呼び出し元のビット数に一致する側が応答するため、32bitアプリはWow6432Node側を読む。

8.3. クラスが見つからない:リポジトリは確認してから修復する

WMIのクラス定義はリポジトリ(単一ファイルではなく、Repositoryフォルダー内のファイル群がデータベースとして機能します13)に格納されています。これが不整合を起こすと、「存在するはずのクラスが見つからない」「名前空間が無効」といったエラーが、アプリ側は何も変えていないのに出始めます。

切り分けと修復には winmgmt.exe を使います。13

rem 整合性チェック(結果が inconsistent なら不整合あり)
winmgmt /verifyrepository

rem 整合性チェック+不整合があれば再構築(読める内容はマージされる)
winmgmt /salvagerepository

注意すべきは、リポジトリの削除や初期化を最初の一手にしないことです。WMI経由で出るエラーはOSの他の部分に起因することもあり、Microsoftはリポジトリの削除を最初の対処にすると「システムやインストール済みアプリへの損傷につながり得る」と明言しています。13 /verifyrepository での確認 → /salvagerepository での修復、の順を守ります。

WMIリポジトリ不整合の切り分け手順クラスが見つからない等のエラーが出たらwinmgmtのverifyrepositoryで整合性を確認し、不整合ならsalvagerepositoryで再構築し、リポジトリの削除や初期化を最初の一手にしないはいいいえクラスが見つからない等のエラーwinmgmt /verifyrepository結果は inconsistent?winmgmt /salvagerepositoryOSの他の部分の原因を疑う読める内容はマージされるリポジトリの削除・初期化最初の一手にしない

図19: verifyで確認してからsalvageで修復する順を守り、削除を最初の一手にしない。

9. まとめ:照会から監視・運用までをつなげる

WMI/CIMは、Windowsの管理情報を横断的に照会するための共通の入口です。専用APIで済む処理まで、すべてWMIへまとめる道具ではありません。

組み込む段階 確認すること
道具を選ぶ 設定・高頻度の性能監視・単発のOS操作は専用の仕組みを優先し、情報取得・リモート照会にWMI/CIMを使う
PowerShellで試す 5.1向けでもCIMコマンドレットで書く。root/CIMV2のクラスを選び、行・列・キーを絞る
リモートへ広げる WSMan/WinRMの接続条件を整え、複数操作はセッションを使い回す。必要な相手にはDCOMオプションを検討する
C#へ移す ローカル照会向きのSystem.Managementと、リモート・監視向きのMI APIを選び分ける。型と日付の扱いを確認する
常駐監視にする Win32_ProcessStartTraceの権限を確認し、購読・解除・切断後の再登録まで一続きで設計する
障害を調べる 短周期ポーリング、プロバイダーのビット数、リポジトリの整合性を切り分ける。削除を最初の対処にしない

CIMという標準とWMIという実装、照会とイベント購読、接続とアクセス許可を分けて考えると、どの道具を選び、どこを確認すべきかが明確になります。まずPowerShellで必要な情報を取得し、その結果をC#の実装と運用設計へつなげてください。

関連記事

関連する相談領域

合同会社小村ソフトでは、WMI/CIMを使ったハードウェア情報取得・プロセス監視・リモートPC照会の業務アプリへの組み込み、Get-WmiObjectベースの社内スクリプトのCIMコマンドレットへの移行、「開発機では動くのに客先で権限エラーになる」類の原因調査を扱っています。PowerShellでの試作からC#への本実装までを一続きでご相談いただけます。

参考リンク

  1. Microsoft Learn, About WMI. WMIがWBEM(企業環境の管理情報アクセスの標準技術を開発する業界イニシアティブ)のMicrosoft実装であること、管理対象の表現にCIM(Common Information Model)業界標準を使い、CIMはDMTF(Distributed Management Task Force)が開発・維持していること、次世代版のMI(Windows Management Infrastructure)が従来のWMIと完全互換であること、リモートWMI接続がDCOMで行われ、代替としてWS-ManagementベースのWinRMがあることについて。  2 3 4 5

  2. Microsoft Learn, Differences between Windows PowerShell 5.1 and PowerShell 7.x. WMI v1コマンドレット(Register-WmiEvent / Set-WmiInstance / Invoke-WmiMethod / Get-WmiObject / Remove-WmiObject)がPowerShellから削除されたこと、CimCmdletsモジュール(WMI v2)のコマンドレットが同じ機能を提供し、新機能と再設計された構文を持つことについて。  2 3

  3. Microsoft Learn, Get-CimInstance (CimCmdlets). ComputerNameもCimSessionも指定しない場合はローカルWMIにCOMセッションで接続し、-ComputerName指定時はWsManプロトコルの一時セッションを作ること、同一コンピューターへの複数操作にはCIMセッションでの接続が性能上推奨されること、-FilterがWHEREキーワードを含めないWQL/CQLのwhere句であること、-Propertyや-KeyOnlyでオブジェクトサイズとネットワークトラフィックを削減できること、既定の名前空間がroot/CIMV2で既定の照会言語(-QueryDialect)がWQLであること、出力がMicrosoft.Management.Infrastructure.CimInstanceであること、Invoke-CimMethodと組み合わせたGetOwner呼び出し例、Windows専用のコマンドレットであることについて。  2 3 4 5 6 7 8 9 10

  4. Microsoft Learn, New-CimSessionOption (CimCmdlets). CIMセッションオプションにWsMan用とDCOM用の2つのパラメーターセットがあること、-ProtocolにDcom / Default / Wsmanを指定できること、New-CimSessionOption -Protocol Dcomで作成したオプションをNew-CimSessionの-SessionOptionに渡してDCOMのCIMセッションを作成する例、DCOMセッションの既定の偽装レベルがImpersonateであることについて。  2

  5. Microsoft Learn, ManagementObjectSearcher Class (System.Management). 指定したWQLクエリにもとづいて管理オブジェクトのコレクションを取得する、管理情報取得の最も一般的な入口クラスであること、ObjectQueryとManagementScope(WMI名前空間)を受け取りGet()でManagementObjectCollectionを返すこと、System.Management.dllがNuGetパッケージSystem.Managementとして提供されることについて。  2 3 4

  6. Microsoft Learn, CimSession Class (Microsoft.Management.Infrastructure). Microsoft.Management.Infrastructure.dllがNuGetパッケージMicrosoft.Management.Infrastructureとして提供されること、Create(computerName)によるセッション作成、QueryInstances(namespace, queryDialect, query)によるクエリ実行、EnumerateInstances / GetInstance / InvokeMethod / Subscribeおよびそれぞれの非同期版(*Async)を備えIDisposableを実装することについて。  2 3 4 5

  7. Microsoft Learn, Register-CimIndicationEvent (CimCmdlets). クラス名またはクエリ式でインディケーション(イベント)を購読し-SourceIdentifierで購読名を付けること、Win32_ProcessStartTraceの購読例とその実行にPowerShellの管理者実行が必要である旨の注記、-Actionスクリプトブロック内で$Event.SourceEventArgs.NewEventからProcessName / ProcessIdを参照する例、-ComputerName指定時はWsManの一時セッション・未指定時はローカルにCOMで接続すること、購読解除にUnregister-Eventを使うことについて。  2 3 4 5

  8. Microsoft Learn, Win32_ProcessStartTrace class. 新しいプロセスの開始を示すイベントクラスであり、ProcessName / ProcessID / ParentProcessID / SessionID / Sidなどのプロパティを持つこと、SECURITY_DESCRIPTORプロパティがどのユーザーがイベントを受信できるかをイベントプロバイダーが決定するための記述子であること、名前空間がRoot\CIMV2でカーネルトレースプロバイダー(Krnlprov.dll)により提供されることについて。  2 3

  9. Microsoft Learn, Win32_LogicalDisk class. Win32_LogicalDiskがCIM_LogicalDisk派生のローカルストレージデバイスを表すクラスであること、DriveTypeの値(2=リムーバブル、3=ローカルディスク、4=ネットワークドライブ、5=CD等)、FreeSpace / Sizeがuint64のバイト値であること、DeviceIDがキーであること、DriveType = 3で絞り込むVBScript / C#のクエリ例について。  2 3 4

  10. Microsoft Learn, Installation and configuration for Windows Remote Management. 既定ではWinRMリスナーが構成されておらずWS-Managementメッセージを送受信できないこと、winrm quickconfigがサービスの自動起動化・HTTP/HTTPSリスナーの構成・ファイアウォール例外の登録を行うこと、WinRM 2.0の既定ポートがHTTP 5985 / HTTPS 5986であること、ワークグループ等で相互認証(Kerberos)が確立できない場合はTrustedHostsを可能な限り限定して設定すること、リスナーへのリモートアクセスを制御する既定のセキュリティ記述子(RootSDDL)や、管理者以外のユーザーにWMIプラグイン利用を許可する場合の追加構成について。  2 3 4

  11. Microsoft Learn, System.Management Namespace. WMI基盤への照会をManagementObjectSearcher系クラスで、イベント購読をManagementEventWatcherで行う名前空間であること、WqlEventQueryがWQL形式のイベントクエリを表すこと、ManagementDateTimeConverterがDMTF日時・時間間隔とCLRのDateTime / TimeSpanの相互変換メソッドを提供することについて。  2 3

  12. Microsoft Learn, Requesting WMI Data on a 64-bit Platform. プロバイダーに32bit版と64bit版が併存する場合、既定では32bitアプリ(スクリプト含む)には32bitプロバイダーが、64bitアプリには64bitプロバイダーが応答すること、コンテキストの__ProviderArchitecture(32または64)と__RequiredArchitectureで非既定側のプロバイダーを要求・強制できること(強制時に該当版がなければWBEM_E_PROVIDER_LOAD_FAILURE)、レジストリプロバイダーの例で32bitクライアントがHKLM\SOFTWARE\Wow6432Node側のデータを受け取ることについて。  2 3

  13. Microsoft Learn, winmgmt. winmgmt.exeの/verifyrepositoryがWMIリポジトリの整合性チェックを行うこと、/salvagerepositoryが整合性チェックのうえ不整合検出時にリポジトリを再構築し読み取れた内容をマージすること、/resetrepositoryがOS初期インストール時の状態へ戻すこと、リポジトリがRepositoryフォルダー内のファイル群でデータベースとして機能すること、WMI経由のエラーがOSの他の部分に起因する場合もあり、最初の対処としてのリポジトリ削除はシステムやインストール済みアプリの損傷につながり得るため行わないべきことについて。  2 3

同じタグを共有する最新の記事です。さらに近い話題で知識を深められます。

このテーマと近いトピックページです。記事を起点に、関連するサービスや他の記事へ進めます。

この記事は次のサービスページにつながります。近い入口からご覧ください。

よくある質問

この記事のテーマについて、相談時によくある質問をまとめています。

WMIとCIMは何が違うのですか?
CIMは、DMTF(Distributed Management Task Force)が策定・維持している「システムやデバイスなどの管理対象を表現するための業界標準モデル」です。WMIは、その標準を使うWBEMというイニシアティブのMicrosoft実装で、Windowsに組み込まれています。つまりCIMが仕様、WMIがWindows上の実装という関係です。PowerShellのGet-CimInstanceやC#のMicrosoft.Management.Infrastructureが「CIM」を名乗っているのは、この標準に沿ったAPIだからで、接続先は同じWMIの基盤です。日常の開発では「WMIのクラス(Win32_*など)をCIM系のAPIで照会する」と理解しておけば実務上は困りません。
Get-WmiObjectはもう使えないのですか?
Windows PowerShell 5.1では今も動きますが、PowerShell 6以降(現行のPowerShell 7)ではGet-WmiObject・Invoke-WmiMethod・Register-WmiEvent・Set-WmiInstance・Remove-WmiObjectのWMI v1コマンドレットが削除されており、実行できません。同じ機能はCimCmdletsモジュール(Get-CimInstance / Invoke-CimMethod / Register-CimIndicationEventなど)が提供しています。新しく書くスクリプトは、5.1で動かす場合でもCIMコマンドレットで書いておくのが安全です。そうしておけば、PowerShell 7への移行時にWMI部分を書き直す必要がなくなります。
C#からWMIを使うにはSystem.ManagementとMicrosoft.Management.Infrastructureのどちらを使うべきですか?
どちらもWindows専用で、現行の.NETからはNuGetパッケージとして利用します。System.ManagementはManagementObjectSearcherにWQLを渡すだけで使える古典的なAPIで、ローカルの情報取得が中心ならこれで十分です。DMTF日付を変換するManagementDateTimeConverterもこちらに含まれます。一方Microsoft.Management.Infrastructure(MI API)は、PowerShellのCIMコマンドレットと同じ型体系(CimSession / CimInstance)を持ち、WSMan経由のリモート照会、非同期版メソッド、イベント購読(Subscribe)まで一貫して扱えます。リモートPCの照会や監視を本格的に組み込むならMI APIを選ぶのが合理的です。
リモートPCにGet-CimInstanceがつながりません。何を確認すべきですか?
まず接続先でWinRMが構成されているかを確認してください。-ComputerNameを指定したCIM操作はWSMan(WinRM)プロトコルで一時セッションを作るため、接続先でWinRMサービスとリスナーが動いていることが前提です。winrm quickconfigで既定構成(サービス起動・リスナー作成・ファイアウォール例外)を行えます。既定ポートはHTTPが5985、HTTPSが5986なので、経路のファイアウォールも確認します。ワークグループ環境ではKerberosの相互認証が使えないため、クライアント側のTrustedHostsへの登録が必要になる場合があります。どうしてもWinRMを構成できない相手には、New-CimSessionOption -Protocol Dcomで作ったオプションを使いDCOMで接続する手もあります。
WMIの日付が「20260801100000.000000+540」のような形式で返るのはなぜですか?
WMIの日付は、DMTFのCIM仕様で定められた文字列形式(yyyymmddHHMMSS.mmmmmm±UUU、末尾はUTCからのオフセット分)で格納されているためです。旧Get-WmiObjectやSystem.Managementで生の値を読むと、この文字列がそのまま返ります。C#(System.Management)ではManagementDateTimeConverterにDMTF形式とDateTime / TimeSpanの相互変換メソッドが用意されているので、自前で文字列を切り貼りせずこれを使ってください。なお、Get-CimInstanceなどのCIM系APIで取得した場合は、日付プロパティはDateTimeに変換済みで返るため、この問題自体に遭遇しません。

著者プロフィール

記事の著者プロフィールページです。

小村 豪

合同会社小村ソフト 代表

Windows ソフト開発、技術相談、不具合調査を中心に、既存資産が残る案件や原因が見えにくい障害調査に強みがあります。

ブログ一覧に戻る