WMI と CIM
Windows PowerShell には、Windows Management Instrumentation (WMI) などの他のテクノロジを操作するためのコマンドレットが既定で付属しています。 WMI コマンドレットは非推奨であり、PowerShell 6 以降では使用できませんが、Windows PowerShell で実行されている古いスクリプトで発生する可能性があるため、ここで説明します。 新しい開発では、代わりに CIM コマンドレットを使用します。
PowerShell には、他のソフトウェアやモジュールをインストールしなくても、いくつかのネイティブ WMI コマンドレットが存在します。
Get-Command
を使用して、Windows PowerShell に存在する WMI コマンドレットを確認できます。 次の結果は、PowerShell バージョン 5.1 を実行している Windows 11 システムからの結果です。 実行している PowerShell のバージョンによって結果が異なる場合があります。
Get-Command -Noun WMI*
CommandType Name Version
----------- ---- -------
Cmdlet Get-WmiObject 3.1.0.0
Cmdlet Invoke-WmiMethod 3.1.0.0
Cmdlet Register-WmiEvent 3.1.0.0
Cmdlet Remove-WmiObject 3.1.0.0
Cmdlet Set-WmiInstance 3.1.0.0
Common Information Model (CIM) コマンドレットは PowerShell 3.0 で導入され、専用モジュール内でグループ化されています。 使用可能なすべての CIM コマンドレットを一覧表示するには、次の例に示すように、 Get-Command
コマンドレットと Module パラメーターを使用します。
Get-Command -Module CimCmdlets
CommandType Name Version
----------- ---- -------
Cmdlet Export-BinaryMiLog 1.0.0.0
Cmdlet Get-CimAssociatedInstance 1.0.0.0
Cmdlet Get-CimClass 1.0.0.0
Cmdlet Get-CimInstance 1.0.0.0
Cmdlet Get-CimSession 1.0.0.0
Cmdlet Import-BinaryMiLog 1.0.0.0
Cmdlet Invoke-CimMethod 1.0.0.0
Cmdlet New-CimInstance 1.0.0.0
Cmdlet New-CimSession 1.0.0.0
Cmdlet New-CimSessionOption 1.0.0.0
Cmdlet Register-CimIndicationEvent 1.0.0.0
Cmdlet Remove-CimInstance 1.0.0.0
Cmdlet Remove-CimSession 1.0.0.0
Cmdlet Set-CimInstance 1.0.0.0
CIM コマンドレットでは引き続き WMI を操作できるため、" PowerShell CIM コマンドレットを使用して WMI にクエリを実行する場合" と表示された場合は混乱しないでください。
前述のように、WMI は PowerShell とは別のテクノロジであり、CIM コマンドレットを使用して WMI にアクセスするだけです。 次の例のように、WMI クエリ言語 (WQL) を使用して WMI のクエリを実行する古い VBScript が見つかる場合があります。
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\CIMV2")
Set colBIOS = objWMIService.ExecQuery _
("Select * from Win32_BIOS")
For each objBIOS in colBIOS
Wscript.Echo "Manufacturer: " & objBIOS.Manufacturer
Wscript.Echo "Name: " & objBIOS.Name
Wscript.Echo "Serial Number: " & objBIOS.SerialNumber
Wscript.Echo "SMBIOS Version: " & objBIOS.SMBIOSBIOSVersion
Wscript.Echo "Version: " & objBIOS.Version
Next
VBScript から WQL クエリを取得し、変更せずに Get-CimInstance
コマンドレットで使用できます。
Get-CimInstance -Query 'Select * from Win32_BIOS'
SMBIOSBIOSVersion : 090006
Manufacturer : American Megatrends Inc.
Name : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
SerialNumber : 3810-1995-1654-4615-2295-2755-89
Version : VRTUAL - 4001628
前の例は、通常、PowerShell を使用して WMI にクエリを実行する方法ではありません。 ただし、機能し、既存の Visual Basic スクリプトを PowerShell に簡単に移行できます。 WMI に対してクエリを実行するワンライナーを記述するときは、次の構文を使用します。
Get-CimInstance -ClassName Win32_BIOS
SMBIOSBIOSVersion : 090006
Manufacturer : American Megatrends Inc.
Name : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
SerialNumber : 3810-1995-1654-4615-2295-2755-89
Version : VRTUAL - 4001628
シリアル番号のみが必要な場合は、出力をパイプ処理して Select-Object
し、 SerialNumber プロパティのみを指定します。
Get-CimInstance -ClassName Win32_BIOS |
Select-Object -Property SerialNumber
SerialNumber
------------
3810-1995-1654-4615-2295-2755-89
既定では、WMI に対してクエリを実行すると、使用されない複数のプロパティがバックグラウンドで取得されます。 ローカル コンピューターで WMI に対してクエリを実行する場合は、それほど重要ではありません。 しかし、リモート コンピューターのクエリを開始すると、その情報を返すのに余分な処理時間だけでなく、ネットワーク経由で送信する不要な情報も増えます。
Get-CimInstance
には、取得する情報を制限する Property パラメーターがあり、WMI クエリの効率が向上します。
Get-CimInstance -ClassName Win32_BIOS -Property SerialNumber |
Select-Object -Property SerialNumber
SerialNumber
------------
3810-1995-1654-4615-2295-2755-89
前の結果はオブジェクトを返しました。 文字列を返すには、 ExpandProperty パラメーターを使用します。
Get-CimInstance -ClassName Win32_BIOS -Property SerialNumber |
Select-Object -ExpandProperty SerialNumber
3810-1995-1654-4615-2295-2755-89
また、点線の構文スタイルを使用して文字列を返すこともできます。パイプを使用して Select-Object
する必要がなくなります。
(Get-CimInstance -ClassName Win32_BIOS -Property SerialNumber).SerialNumber
3810-1995-1654-4615-2295-2755-89
CIM コマンドレットを使用してリモート コンピューターにクエリを実行する
ローカル管理者およびドメイン ユーザーとして PowerShell を実行している必要があります。
Get-CimInstance
コマンドレットを使用してリモート コンピューターから情報を照会しようとすると、アクセス拒否エラー メッセージが表示されます。
Get-CimInstance -ComputerName dc01 -ClassName Win32_BIOS
Get-CimInstance : Access is denied.
At line:1 char:1
+ Get-CimInstance -ComputerName dc01 -ClassName Win32_BIOS
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (root\cimv2:Win32_BIOS:Stri
ng) [Get-CimInstance], CimException
+ FullyQualifiedErrorId : HRESULT 0x80070005,Microsoft.Management.Infra
structure.CimCmdlets.GetCimInstanceCommand
+ PSComputerName : dc01
多くのユーザーが PowerShell に関するセキュリティ上の懸念を抱えていますが、PowerShell のアクセス許可は GUI と同じです。 過不足がありません。 前の例の問題は、PowerShell を実行しているユーザーに、DC01 サーバーから WMI 情報を照会する権限がないという点です。
Get-CimInstance
には Credential パラメーターがないため、ドメイン管理者として PowerShell を再起動できます。 ただし、PowerShell から実行するものはドメイン管理者として実行されるため、これは良い考えではありません。状況によっては、そのシナリオはセキュリティの観点から危険な場合があります。
最小特権の原則を使用して、コマンドに Credential パラメーターがある場合は、コマンドごとにドメイン管理者アカウントに昇格します。
Get-CimInstance
には Credential パラメーターがないため、このシナリオの解決策は、最初に CimSession を作成することです。
次に、コンピューター名の代わりに CimSession を使用して、リモート コンピューター上の WMI に対してクエリを実行します。
$CimSession = New-CimSession -ComputerName dc01 -Credential (Get-Credential)
cmdlet Get-Credential at command pipeline position 1
Supply values for the following parameters:
Credential
CIM セッションは、 $CimSession
という名前の変数に格納されました。 また、新しいセッションを作成する前に、 Get-Credential
コマンドレットをかっこで囲んで指定し、代替資格情報の入力を求めて最初に実行することに注意してください。 この章の後半で代替資格情報を指定するもう 1 つのより効率的な方法を紹介しますが、この基本的な概念を理解してから複雑にすることが重要です。
前の例で作成した CIM セッションを Get-CimInstance
コマンドレットと共に使用して、リモート コンピューター上の WMI から BIOS 情報を照会できるようになりました。
Get-CimInstance -CimSession $CimSession -ClassName Win32_BIOS
SMBIOSBIOSVersion : 090006
Manufacturer : American Megatrends Inc.
Name : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
SerialNumber : 0986-6980-3916-0512-6608-8243-13
Version : VRTUAL - 4001628
PSComputerName : dc01
コンピューター名を指定するだけではなく、CIM セッションを使用する利点は他にもいくつかあります。 同じコンピューターに対して複数のクエリを実行する場合、CIM セッションを使用する方が、クエリごとにコンピューター名を使用するよりも効率的です。 CIM セッションを作成すると、接続は 1 回だけ設定されます。 その後、複数のクエリがその同じセッションを使用して情報を取得します。 コンピューター名を使用するには、コマンドレットで各クエリとの接続を設定して破棄する必要があります。
Get-CimInstance
コマンドレットは既定で WSMan プロトコルを使用します。つまり、リモート コンピューターに接続するには PowerShell バージョン 3.0 以降が必要です。 実際に重要なのは PowerShell バージョンではなく、スタック バージョンです。 スタックのバージョンは、 Test-WSMan
コマンドレットを使用して決定できます。
バージョン 3.0 である必要があります。これは、PowerShell バージョン 3.0 以降で確認できます。
Test-WSMan -ComputerName dc01
wsmid : http://schemas.dmtf.org/wbem/wsman/identity/1/wsmanidentit
y.xsd
ProtocolVersion : http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd
ProductVendor : Microsoft Corporation
ProductVersion : OS: 0.0.0 SP: 0.0 Stack: 3.0
古い WMI コマンドレットは、古いバージョンの Windows と互換性のある DCOM プロトコルを使用します。
ただし、ファイアウォールは通常、新しいバージョンの Windows で DCOM をブロックします。
New-CimSessionOption
コマンドレットを使用すると、New-CimSession
で使用する DCOM プロトコル接続を作成できます。 このオプションを使用すると、 Get-CimInstance
コマンドレットは、Windows Server 2000 と同じ古いバージョンの Windows と通信できます。また、この機能は、DCOM プロトコルを使用するように構成された CimSession で Get-CimInstance
コマンドレットを使用する場合に、リモート コンピューターで PowerShell が必要ないことを意味します。
New-CimSessionOption
コマンドレットを使用して DCOM プロトコル オプションを作成し、変数に格納します。
$DCOM = New-CimSessionOption -Protocol Dcom
効率を高めるために、ドメイン管理者または管理者特権の資格情報を変数に格納できるため、コマンドごとに常に入力する必要はありません。
$Cred = Get-Credential
cmdlet Get-Credential at command pipeline position 1
Supply values for the following parameters:
Credential
Windows Server 2008 (R2 以外) を実行する SQL03 という名前のサーバーがあります。 これは、PowerShell が既定でインストールされていない最新の Windows Server オペレーティング システムです。
DCOM プロトコルを使用して SQL03 への CimSession を作成します。
$CimSession = New-CimSession -ComputerName sql03 -SessionOption $DCOM -Credential $Cred
前のコマンドで、資格情報をもう一度手動で入力するのではなく、 $Cred
という名前の変数を Credential パラメーターの値として指定していることに注意してください。
クエリの出力は、基になるプロトコルに関係なく同じです。
Get-CimInstance -CimSession $CimSession -ClassName Win32_BIOS
SMBIOSBIOSVersion : 090006
Manufacturer : American Megatrends Inc.
Name : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
SerialNumber : 7237-7483-8873-8926-7271-5004-86
Version : VRTUAL - 4001628
PSComputerName : sql03
Get-CimSession
コマンドレットを使用して、現在接続されている CimSessions とその使用プロトコルを確認します。
Get-CimSession
Id : 1
Name : CimSession1
InstanceId : 80742787-e38e-41b1-a7d7-fa1369cf1402
ComputerName : dc01
Protocol : WSMAN
Id : 2
Name : CimSession2
InstanceId : 8fcabd81-43cf-4682-bd53-ccce1e24aecb
ComputerName : sql03
Protocol : DCOM
以前に作成した CimSessions を取得し、 $CimSession
という名前の変数に格納します。
$CimSession = Get-CimSession
1 つのコマンドを使用して両方のコンピューターにクエリを実行します。1 つは WSMan プロトコルを使用し、もう 1 つは DCOM を使用します。
Get-CimInstance -CimSession $CimSession -ClassName Win32_BIOS
SMBIOSBIOSVersion : 090006
Manufacturer : American Megatrends Inc.
Name : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
SerialNumber : 0986-6980-3916-0512-6608-8243-13
Version : VRTUAL - 4001628
PSComputerName : dc01
SMBIOSBIOSVersion : 090006
Manufacturer : American Megatrends Inc.
Name : Intel(R) Xeon(R) CPU E3-1505M v5 @ 2.80GHz
SerialNumber : 7237-7483-8873-8926-7271-5004-86
Version : VRTUAL - 4001628
PSComputerName : sql03
WMI および CIM コマンドレットに関するブログ記事の 1 つは、WSMan と DCOM のどちらを使用するかを自動的に検出し、適切な CIM セッションを設定する PowerShell 関数を備えています。 詳細については、「 Dcom へのフォールバックを使用してリモート コンピューターに CimSession を作成する PowerShell 関数」を参照してください。
CIM セッションを終了したら、 Remove-CimSession
コマンドレットを使用してそれらを削除します。 すべての CIM セッションを削除するには、Get-CimSession
の出力を Remove-CimSession
にパイプします。
Get-CimSession | Remove-CimSession
概要
この章では、PowerShell を使用してローカル コンピューターとリモート コンピューターで WMI を操作する方法について説明しました。 また、CIM コマンドレットを使用して、WSMan プロトコルと DCOM プロトコルを使用してリモート コンピューターを操作する方法についても学習しました。
レビュー
- WMI コマンドレットと CIM コマンドレットの違いは何ですか?
- 既定では、
Get-CimInstance
コマンドレットはどのプロトコルを使用しますか? -
Get-CimInstance
でコンピューター名を指定する代わりに CIM セッションを使用する利点は何ですか? -
Get-CimInstance
で使用する既定のプロトコル以外の代替プロトコルを指定するにはどうすればよいですか? - CIM セッションを閉じるか削除する方法
リファレンス
PowerShell