web-dev-qa-db-ja.com

RDPを使用してユーザーを一覧表示する

Windows Server 2008 R2

PowerShellを使用して、過去1日間にリモートデスクトップサービス(以前のターミナルサービス)にログインしたユーザーのリストを取得しようとしています。理解がほとんどなく、コピーと貼り付けが多いので、次の小さなスクリプトがあります。

$a = (Get-Date).AddDays(-1)
Get-EventLog -LogName Security -after $a | Where-Object {($_.EventID -eq '4624') -and  $_.EntryType -eq 'SuccessAudit') -and ($_.Message | Select-String "Logon Type:\t\t\t10")}

デフォルトの出力は、物事が起こったことと、それらがいつ起こったかを教えてくれます。これは良いスタートです。 本当に好きなのは、ユーザーも表示することです。ユーザーを取得する方法や表示する方法を理解できれば、とんでもない。

それが私の質問です。そのイベントID4624 /ログオンタイプ10イベントに関連付けられたユーザー名を追加するにはどうすればよいですか?理想的には、ログイン時間とユーザー名を表示したいだけです。

3
Chris_K

まず、Get-WinEventを使用し、ハッシュを渡してそこで可能な限り多くのフィルタリングを行うことをお勧めします(したがって、Where-Objectが破棄するオブジェクトを大量に作成しないようにします)。

Get-WinEvent -filterHashtable @{LogName='Security'; StartTime=$a; Id=4624; Level=0}

レベル0は成功監査です。これは、-computerパラメーターを使用してリモートで実行できます。次に、結果をフィルタリングしてログインタイプを取得します。

... | Where-Object { $_.Message -match 'Logon Type:\s+10'}

空白をハードコーディングしないように正規表現を使用する。

メッセージからユーザーとドメインを抽出するのは、2つの「アカウント名」の値があるため少し厄介です。1つはコンピューター用、もう1つはユーザー用です。ただし、(ローカライズ可能な)メッセージテキストに挿入されるすべての置換可能な値は、イベントのPropertiesプロパティなので、サンプルでインデックスを確認するために少しチェックします1

... | Select-Object *, @{l='LogonAccount';e={$_.Properties[6].Value + "\" + $_.Properties[5].Value }}

他の詳細(SID、クライアントIPなど)を明確にキャプチャすることも同じパターンに従います。

したがって:

Get-WinEvent -filterHashtable @{LogName='Security'; StartTime=$a; Id=4624; Level=0} |
  Where-Object { $_.Properties[8].Value -eq 10} |
  Select-Object *, @{l='LogonAccount';e={$_.Properties[6].Value + "\" + $_.Properties[5].Value }}

1$evの単一のイベントで使用しました:

0..($ev.Properties.Count-1) | Select @{l='Idx';e={$_}},@{l='Property';e={$ev.Properties[$_].Value}} |
  ft -auto

与える(少しの検閲で、インデックス#8でログオンタイプを取得するためのより良い方法に注意してください):

 Idxプロパティ
 --- -------- 
 0 S-1-5-18 
 1 *コンピューターのアカウント* 
 2 *コンピューターのドメイン* 
 3 999 
 4 *ユーザーのSID * 
 5 *ユーザーのユーザー名* 
 6 *ユーザーのドメイン* 
 7 151556 
 8 10 
 9 User32 
 10ネゴシエート
 11 *コンピューター名* 
 12 00000000-0000-0000-0000-000000000000 
 13-
 14-
 15 0 
 16 2964 
 17 C:\ Windows\System32\winlogon.exe 
 18 *クライアントIP * 
 19 15532 
6
Richard

私はそれを次のようにします-

$filter = "<QueryList>" + `
               "<Query Id=`"0`" Path=`"Security`">" + `
                    "<Select Path=`"Security`">" + `
                        "*[System[(EventID=4624) and " + `
                        "TimeCreated[@SystemTime&gt;='2011-09-21T06:00:00Z' and @SystemTime&lt;'2011-09-22T06:00:00Z']]] and " + `
                        "*[EventData[Data[@Name=`'LogonType`']=10]]" + `
                    "</Select>" + `
                    "<Suppress Path=`"Security`">" + `
                        "*[EventData[Data[@Name=`'LogonGuid`']=`'{00000000-0000-0000-0000-000000000000}`']]" + `
                    "</Suppress>" + `
               "</Query>" + `
          "</QueryList>"

Get-WinEvent -FilterXML $filter | 
%{ [xml]$xml = $_.ToXml()
   $xml.getElementsByTagName("Data") | where{$_.name -eq "TargetUserName"} | 
   select '#text'
}

編集:これで個人の名前が返されるようになりました。そのXMLドキュメントから正確に抽出したいものを試してみることができます。

注:TimeCreated値を使用する必要があります(おそらくその場で生成します)。必要なフォーマットがわかるように、これらを含めました。

フィルタリングはパイプラインではなくサーバー側で行われるため、Get-WinEventはGet-EventLogよりもはるかに高速になります。 FilterXMLパラメーターを使用して、クエリをもう少し具体的にすることもできます。ログオンイベントに関連付けられたユーザー名は、返されたMessageEventLogRecordプロパティにあります。

3
pk.