Operations Lab.

WMI 経由でレジストリの値を取得する

leave a comment »

Windows Server を管理していると、複数のコンピュータから特定のレジストリキー配下の値を一括で取得したい、と思うことがあります。ただ、Windows Server 2008 などの若干古い OS を対象とした場合、管理対象で PowerShell Remoting が有効になっていなかったり、WMF (Windows Management Framework)のバージョンが古かったりなどで、PowerShell だけでは一括処理が難しい場合があります。

今回は、PowerShell から WMI 経由で複数のリモートコンピューターに接続し、レジストリのサブキー配下の値を再帰的に取得してみます。

前提条件

  • ターゲットコンピューターに WMI で接続できること
  • クライアント(管理側・スクリプト実行側)コンピューター上で PowerShell 3.0 以降が実行できること(2.0 でも動く気がしますが、未検証)

※認証や委任周りで大変面倒なことになるので、今回試している環境はドメイン環境かつ Domain Admins に種族しているアカウントでスクリプトを実行しています。

リモートから複数コンピューターのレジストリ値を取得する

以下のコードは GitHub 上でも参照できます

Param(
    [parameter(Mandatory=$true)]
    [string[]]$ComputerName
)

$HKEY_LOCAL_MACHINE = 2147483650
$ns = "root\default"
$cls = "StdRegProv"
$regkey = "SOFTWARE\Policies\Microsoft"

$result = New-Object System.Collections.ArrayList

$ComputerName | % {
    $c = $_
    $wmi = Get-WmiObject -List $cls -Namespace $ns -ComputerName $c
    $r = $wmi.EnumKey($HKEY_LOCAL_MACHINE, $regkey)
    $r.sNames | % {
        $obj = New-Object -TypeName PSObject
        Add-Member -InputObject $obj -MemberType NoteProperty -Name ComputerName -Value $c
        Add-Member -InputObject $obj -MemberType NoteProperty -Name Name -Value $_
        Add-Member -InputObject $obj -MemberType NoteProperty -Name Type -Value "SubKey"
        Add-Member -InputObject $obj -MemberType NoteProperty -Name Value -Value $null
        $result.Add($obj) | Out-Null
    }
    $r = $wmi.EnumValues($HKEY_LOCAL_MACHINE, $regkey)
    if($r.ReturnValue -eq 0) {
        for($i = 0; $i -lt $r.sNames.Count; $i++) {
            $obj = New-Object -TypeName PSObject
            Add-Member -InputObject $obj -MemberType NoteProperty -Name ComputerName -Value $c
            Add-Member -InputObject $obj -MemberType NoteProperty -Name Name -Value $r.sNames[$i]
            switch ($r.Types[$i]) {
                1 { # REG_SZ
                    Add-Member -InputObject $obj -MemberType NoteProperty -Name Type -Value "REG_SZ"
                    $val = $wmi.GetStringValue($HKEY_LOCAL_MACHINE, $regkey, $r.sNames[$i])
                    Add-Member -InputObject $obj -MemberType NoteProperty -Name Value -Value $val.sValue
                }
                2 { # REG_EXPAND_SZ
                    Add-Member -InputObject $obj -MemberType NoteProperty -Name Type -Value "REG_EXPAND_SZ"
                    $val = $wmi.GetExpandedStringValue($HKEY_LOCAL_MACHINE, $regkey, $r.sNames[$i])
                    Add-Member -InputObject $obj -MemberType NoteProperty -Name Value -Value $val.sValue
                }
                3 { # REG_BINARY
                    Add-Member -InputObject $obj -MemberType NoteProperty -Name Type -Value "REG_BINARY"
                    $val = $wmi.GetBinaryValue($HKEY_LOCAL_MACHINE, $regkey, $r.sNames[$i])
                    Add-Member -InputObject $obj -MemberType NoteProperty -Name Value -Value $val.uValue
                }
                4 { # REG_DWORD
                    Add-Member -InputObject $obj -MemberType NoteProperty -Name Type -Value "REG_DWORD"
                    $val = $wmi.GetDWORDValue($HKEY_LOCAL_MACHINE, $regkey, $r.sNames[$i])
                    Add-Member -InputObject $obj -MemberType NoteProperty -Name Value -Value $val.uValue
                }
                7 { # REG_MULTI_SZ
                    Add-Member -InputObject $obj -MemberType NoteProperty -Name Type -Value "REG_MULTI_SZ"
                    $val = $wmi.GetMultiStringValue($HKEY_LOCAL_MACHINE, $regkey, $r.sNames[$i])
                    Add-Member -InputObject $obj -MemberType NoteProperty -Name Value -Value $val.sValue
                }
                11 { # REG_QWORD
                    Add-Member -InputObject $obj -MemberType NoteProperty -Name Type -Value "REG_QWORD"
                    $val = $wmi.GetQWORDValue($HKEY_LOCAL_MACHINE, $regkey, $r.sNames[$i])
                    Add-Member -InputObject $obj -MemberType NoteProperty -Name Value -Value $val.uValue
                }
                default { # Invalid Object
                }
            }
            $result.Add($obj) | Out-Null
        }
    }
}

return $result

$regkey に設定したレジストリ サブキー配下を取得しますので、適当に書き換えてください。(本来はパラメーター化すべきですが、今回は面倒だったのでそのままです。)接続先コンピューターは、スクリプトのパラメーター –ComputerName で指定できます。配列(PowerShell Console 上だとカンマ区切り)で渡せば、複数コンピューターを指定できます。

広告

Written by kazu

2016/08/21 @ 16:09

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。