List users logged on to your machines

Password policies are best😀 Sometimes they lead to account logouts when someone forgot to logout of session somewhere on the network though. それは、四半期に一度、報告のために使用する TS セッションかもしれませんし、サーバーに RDP したら、他の 2 人の管理者がログオフするのを忘れてロックされているのを発見したときの感覚を知っているかもしれませんね。 (とにかく、私はネットワーク上のどこかにあるユーザーセッションを探さなければなりませんでした。 最悪なのは、自分のパスワードが期限切れになったときです。 自分のアカウントがロックされてしまうのは嫌ですね。 そこで、パスワードを変更する前に、すべてのサーバーをチェックすることにした。 これを行うには複数の方法がありますが、私はもちろんPowerShellのルートを取ることが多いです。

Research

私が最初に使用した方法は TechNet gallery

のものです。 これは、サービスとして実行されているものまですべて見つけるのでクールですが、最も効率的な方法だとは思えません。

Google で調べてみると、自分のマシンに誰がログオンしているかをチェックするクリエイティブな方法がたくさん見つかりました。

2015-08-28 (1)

これは素晴らしいです。出力は少し異なりますが、Get-CimInstance でも動作するようです。

2015-08-28

learn-powershell.net/…/Quick-hit-find-currently-logged-on-users/ はもう少し古いアプローチで、少し荒っぽく、テンプレート ベースの解析で遊ばざるを得ないので、私はこれが好きです。

2015-08-28 (2)

どの方法がより速いのかよく分からないので、モジュールで 3 つすべてを実装してテストしてみてはいかがでしょうか。

Pseudo code:Get-ActiveUser -ComputerName -Method Wanted output:Username ComputerName-------- ------------TestUser1 Svr3TestUser3 Svr3DonaldDuck Client2

GitHub リポジトリを設定するのに必要なすべての情報が揃いました。

github.com/mrhvid/Get-ActiveUser

コード

まず、私が興味を持っているパラメーターは ComputerName と Method です。

 Param ( # Computer name, IP, Hostname ] $ComputerName, # Choose method, WMI, CIM or Query $Method )

私はすでに3種類の Method を考えているので、3種類の可能性を ValidateSet と設定しました。

 Process { switch ($Method) { 'WMI' { } 'CIM' { } 'Query' { } } }

関数の処理部分では、パラメータで許可した 3 つの異なるメソッドのスイッチを使用するだけです。

WMI

My old solution is simple and works fine.

$WMI = Get-WmiObject -Class Win32_Process -ComputerName $ComputerName -ErrorAction Stop$ProcessUsers = $WMI.getowner().user | Select-Object -Unique

2015-08-28 (3)

But now that I found Win32_LoggedOnUser it to do it this way is wrong.このようにすると、このソリューションはうまくいきます。

2015-08-28 (4)

gwmi-Wmi32_LoggedOnUser_gm

これはすべて正しいデータですが、文字列形式のようなので、少し操作する必要がありそうです。 これはいくらでもできる。

function Get-MyLoggedOnUsers { param($Computer) Get-WmiObject Win32_LoggedOnUser -ComputerName $Computer | Select Antecedent -Unique | %{"{0}{1}" -f $_.Antecedent.ToString().Split('"'), $_.Antecedent.ToString().Split('"')} }

Peter の前述のワンライナーは、私にはあまり読みやすいとは思えなかったので、ワンライナーとしてはいいのですが、できればもう少し読みやすくしてほしいです。

$WMI = (Get-WmiObject Win32_LoggedOnUser).Antecedent$ActiveUsers = @()foreach($User in $WMI) { $StartOfUsername = $User.LastIndexOf('=') + 2 $EndOfUsername = $User.Length - $User.LastIndexOf('=') -3 $ActiveUsers += $User.Substring($StartOfUsername,$EndOfUsername)}

2015-08-28 (5)

This seams right 🙂 出力を $ActiveUsers 変数に保存して、CIM と Query で同じことをします

CIM

Lets try with CIM.SIM.SIM.Lots。

2015-08-28 (6)

この方がずっと構造化されているように見えます。

2015-08-28 (7)

CIMは結局わかりやすいワンライナーになりました😀

$ActiveUsers = (Get-CimInstance Win32_LoggedOnUser -ComputerName $ComputerName).antecedent.name | Select-Object -Unique

Query

Using the good ol’ Query.を使ってみました。exe を使用すると、以前説明したテンプレートベースの解析が非常に便利であることがわかりました。

$Template = @' USERNAME SESSIONNAME ID STATE IDLE TIME LOGON TIME>{USER*:jonas} console 1 Active 1+00:27 24-08-2015 22:22 {USER*:test} 2 Disc 1+00:27 25-08-2015 08:26'@$Query = query.exe user$ActiveUsers = $Query | ConvertFrom-String -TemplateContent $Template | Select-Object -ExpandProperty User

Output

あとは、ユーザーをうまくフォーマットして出力する必要があるだけです。 ComputerNameとUserNameできれいなオブジェクトが欲しいです。

# Create nice output format$UsersComputersToOutput = @()foreach($User in $ActiveUsers) { $UsersComputersToOutput += New-Object psobject -Property @{ ComputerName=$ComputerName; UserName=$User } }}# output data$UsersComputersToOutput

Testing

さて、問題が発生しました。 私は自由に使える多くのテスト サーバーを持っていないので、これをテストすることはできません。 私のテストはすべて、私自身の Windows 10 ボックスに対して行われました。 クエリはローカルで実行したほうがずっと速いようですが、WMI/CIM はどのサービスが実行されているかをより完全に表示することができます。

get-activeuser_wmi_highlight

出力から削除するとよいかもしれない標準サービス アカウントの束を実行させています。 また、これが有用であるためには、多くのマシンに対して実行する必要があります。

get-activeuser_query

Get-ActiveUser と Start-Multithread の組み合わせは、先週の投稿から意図したように機能しているようです。

Start-Multithread -Script { param($C) Get-ActiveUser -ComputerName $C -Method Query } -ComputerName ::1,Localhost | Out-GridView

上記を Out-GridView にパイプすることは、本当に有用なことを達成する個人的に好きな方法です。 また、ネットワーク上のルージュ ユーザーをチェックする簡単な方法でもあります。

公開とフィードバック

コードは PowerShellGallery で公開されています。 これが実世界で動作するかどうか知りたいです🙂

# To install Get-ActiveUserInstall-Module Get-ActiveUser#To install Start-MultithreadInstall-Module Start-Multithread

これは WMF 5 + をインストールし、Windows 10 で箱から出しているときに動作するはずです。

コメントを残す

メールアドレスが公開されることはありません。