tech.guitarrapc.cóm

C#, PowerShell, Unity, Cloud, Serverless Technical Update and Features

PowerShellでCIM cmdletを用いて対象PCのユーザーや所属するユーザーグループを調べる

サーバー管理において、そのサーバーに存在するユーザー/グループを管理することは重要ですね。 今回の例は、PowerShell 3.0で、PowerShellのCIM関連コマンドレットを利用してローカル/リモートのユーザーやグループを調べる方法です。 ====

CIM関連コマンドレットの利用要件

TechNetに記載がある通り、CIM関連コマンドレットはWMI 3.0、つまりPowerShell 3.0からの追加分です。 そのため、Windows 7やWindows Server 2008R2の初期状態であるWMI2.0 (PowerShell 2.0)では利用できません。 しかし、Windows7、 Windows Server 2008R2でも、「WMI3.0をインストールしてPowerShell 3.0環境にする」ことで同コマンドレットを利用できます。 Windows 8、Windows Server 2012は標準でWMI 3.0ですので問題ありません。

CIM関連コマンドレット

まずは、お決まりのGet-CommnadでCIMに関するコマンドレットには何があるかを調べてみましょう。

Get-Command -Name "*CIM*" -CommandType Cmdlet

Windows 8 Pro x64で出力された一覧です。

CommandType Name                        ModuleName
----------- ----                        ----------
Cmdlet      Get-CimAssociatedInstance   CimCmdlets
Cmdlet      Get-CimClass                CimCmdlets
Cmdlet      Get-CimInstance             CimCmdlets
Cmdlet      Get-CimSession              CimCmdlets
Cmdlet      Invoke-CimMethod            CimCmdlets
Cmdlet      New-CimInstance             CimCmdlets
Cmdlet      New-CimSession              CimCmdlets
Cmdlet      New-CimSessionOption        CimCmdlets
Cmdlet      Register-CimIndicationEvent CimCmdlets
Cmdlet      Remove-CimInstance          CimCmdlets
Cmdlet      Remove-CimSession           CimCmdlets
Cmdlet      Set-CimInstance             CimCmdlets

ついでにAliasも調べてみました。

Get-Command -Name "*CIM*" -CommandType Alias

結果です。

CommandType Name                       ModuleName
----------- ----                       ----------
Alias       gcim -> Get-CimInstance              
Alias       icim -> Invoke-CimMethod             
Alias       ncim -> New-CimInstance              
Alias       rcim -> Remove-CimInstance           
Alias       scim -> Set-CimInstance              

TechNetを見てみる

「利用前の確認」、大事ですね。

TechNet - Get-CimInstance TechNet - Get-CimAssociatedInstance

ユーザーを取得する

今回は、調査が主目的なのでGet-*を用います。 Get-CimInstatanceを調べてみると……想定通り、Wmi同様に使えそうですね。  ローカルの全ユーザーを調べるならこれで出ます。

Get-CimInstance -ClassName Win32_UserAccount

リモートPCの全ユーザーを調べるなら-ComputerNameパラメータで対象を指定しましょう。

Get-CimInstance -ClassName Win32_UserAccount -ComputerName Server01

SIDなどがジャマで、NameとCaptionだけが欲しい場合はSelect-Objectコマンドレットで絞れます。

Get-CimInstance -ClassName Win32_UserAccount | select Name, Caption

さらにユーザーを絞るなら、-Filterパラメータが使えますね。

Get-CimInstance -ClassName Win32_UserAccount -Filter "Name='foo'" | select Name, Caption

もし、完全なName一致ではなく曖昧検索(ワイルドカード)を利用したいなら、LIKE演算子を用いて%(ワイルドカード文字)を利用します。 例えばaから始まるユーザー名なら…?

Get-CimInstance -ClassName Win32_UserAccount -Filter "Name like 'a%'" | select Name, Caption

リモートPCで今ログインしているユーザーで調べるなら? -Filterで、環境変数の$env:UserNameをNameに指定すれば出来ますね。

Get-CimInstance -ClassName Win32_UserAccount -Filter "Name='$env:UserName'" -ComputerName Server01 | select Name, Caption

ユーザーが所属するユーザーグループを取得する

簡単です。 Get-CimAssociatedInstanceコマンドレットに、-AssociationパラメータでWin32_GroupUserを指定すればいいのです。 このコマンドレットは、-Inputパラメータが必須となります。 が、先ほどGet-CimInstanceコマンドレットで取得した結果を|(パイプ)で渡すことで、調べたユーザーが所属するグループを取得できます。 ローカルユーザーが所属している全ユーザーグループを取得するにはこうなりますね。

Get-CimInstance -ClassName Win32_UserAccount | Get-CimAssociatedInstance -Association Win32_GroupUser

やはりSIDが出ています。 もし、邪魔な場合は、NameとCaptionとDomainなどに絞ってみましょう。

Get-CimInstance -ClassName Win32_UserAccount `
| Get-CimAssociatedInstance -Association Win32_GroupUser `
| select Name, Caption, Domain

ここまで理解できれば、ローカル、リモートを問わず所属するユーザーグループが自在に取得出来ますね。 例えば、ローカルPCで現在ログインしているユーザーが所属するユーザーグループを取得するには。

Get-CimInstance -ClassName Win32_UserAccount -Filter "Name='$env:UserName'" `
| Get-CimAssociatedInstance -Association Win32_GroupUser `
| Select-Object Name, Caption, Domain

これをリモートPCに対して実行するには、-ComputerNameパラメータを指定するだけです。

Get-CimInstance -ClassName Win32_UserAccount -Filter "Name='$env:UserName'"  -ComputerName localhost `
| Get-CimAssociatedInstance -Association Win32_GroupUser `
| Select-Object Name, Caption, Domain

おまけ

さて、せっかくなので指定したユーザーのグループを調査する際にユーザー名も一緒に表示されるように書いてみましょう。 同じ結果ですが、二つの書き方があります。 1. 単純にスクリプトブロックでUserを表示させるやり方。

Get-CimInstance -ClassName Win32_UserAccount -Filter "Name='$env:UserName'" `
| %{
    $user = $_.Name;
    Get-CimAssociatedInstance -Association Win32_GroupUser -InputObject $_ `
    | select @{label="User";expression={$user}},
        Name,
        Caption,
        Domain
}

2. Select-Objectで、そのオブジェクトに存在しないプロパティを指定すると、自動的にNew-Objectされることを利用した書き方。(UserはWin32_GroupUserにはないプロパティです。)

Get-CimInstance -ClassName Win32_UserAccount -Filter "Name='$env:UserName'" `
| %{
    $user = $_.Name;
    Get-CimAssociatedInstance -Association Win32_GroupUser -InputObject $_ `
    | %{ 
        $result = $_ | select -Property User, Name, Caption, Domain
        $result.User = $user
        $result
    }
}

いずれも出力結果は一緒です。  あるいは、Captionにユーザー名が出てるのを利用してもいいかもです。

Get-CimInstance -ClassName Win32_UserAccount | Get-CimAssociatedInstance -Association Win32_GroupUser | sort Caption | Format-Table Caption, Name, Domain

改行するとこうです。

Get-CimInstance -ClassName Win32_UserAccount `
| Get-CimAssociatedInstance -Association Win32_GroupUser `
| sort Caption `
| Format-Table Caption, Name, Domain

まとめ

CIM系のコマンドは、サーバー管理には必須ですね。 非常に有用なので活用していきたいところです。

参考

#PSTip Using CIM cmdlets to find the user group membership WMI クエリでの LIKE 演算子の使用