0

アップデート

@ HAL9256

あなたの答えは本当に私を考えさせました!

さらにグーグルで調べたところ、別のアプローチを提供するこのWebサイトが見つかりました

http://blogs.technet.com/b/heyscriptingguy/archive/2012/02/19/use-powershell-to-find-last-logon-times-for-virtual-workstations.aspx

これまでのところ、うまくいきます!

最後にログオンしたユーザーを表示する powershell スクリプトを実行するために、別のサーバーにリモート接続します。

いくつかのこと

  1. 管理者ではなく、サービスアカウントのコンテキストで実行した場合にのみ機能します
  2. 出力には数分かかります

しかし、サービス アカウントのコンテキストで実行すると、同じ入力に対して異なる出力が得られます

$line_array = @()
$multi_array = @()
[hashtable]$my_hash = @{}

foreach ($i in $args){
   $line_array+= $i.split(" ")
}

foreach ($j in $line_array){
    $multi_array += ,@($j.split("="))
}

foreach ($k in $multi_array){
    $my_hash.add($k[0],$k[1])
}

$Sender_IP = $my_hash.Get_Item("sender-ip")


$eventList = @()
Get-EventLog "Security" -computername $Sender_IP `
    | Where -FilterScript {$_.EventID -eq 4624 -and $_.ReplacementStrings[4].Length -gt 10 -and $_.ReplacementStrings[5] -notlike "*$"} `
    | Select-Object -First 2 `
    | foreach-Object {
        $row = "" | Select UserName, LoginTime
        $row.UserName = $_.ReplacementStrings[5]
        $row.LoginTime = $_.TimeGenerated
        $eventList += $row
        }
$userId = $eventList[0].UserName
$userId

たとえば、コマンドラインでスクリプトを呼び出します

script.ps1 "sender-ip=10.10.10.10"

初めて実行すると、ユーザーのウィンドウのログオン名が出力されます

同じ入力で同じスクリプトを 2 回目に実行すると、powershell スクリプトの実行に使用したのと同じサービス アカウントが出力されます。

そして、同じ入力で同じスクリプトを実行しようとすると、この同じサービス アカウントの出力が得られます。

~~~~~~~

次に、別の IP アドレスでスクリプトを実行してみます

初めてスクリプトを実行すると、ウィンドウのログオン名が出力されます

スクリプトを 2 回目に実行すると、powershell スクリプトが実行されているのと同じサービス アカウントが出力されます。

~~~~~~~

これがパターンのようです。スクリプトを初めて実行すると正しい入力が返され、2 回目に実行するとサービス アカウントが返されます。

なぜこうなった?

スクリプトが何度呼び出されても常に正しい出力を返すようにする方法は?

これをトラブルシューティングする方法は?

4

1 に答える 1

2

これは、スクリプトが最後にログオンしたユーザーに関する情報を取得する方法によるものです。

セキュリティ イベント ログから最後にログオンしたユーザーを取得しています。これにより、コンピューターに「ログオン」するすべての人がログに記録されます... WMI、サービスアカウントなどによるアクセスを含みます.

何が起こっているのですか:

  • スクリプト実行前
    • Contoso\User1がコンピューターにログオンする
    • EventID 4624 - ログオン成功 - Contoso\User1がログに記録されます
  • 初めてスクリプトを実行する
    • スクリプトはContoso\ServiceAccountとして実行されます
    • WMI 経由でコンピューターにアクセスして、セキュリティ イベント ログをプルするスクリプト
    • セキュリティ イベント ログには、最後にログオンしたユーザーがContoso\User1であることが示されています
    • EventID 4624 - ログオン成功 - Contoso\ServiceAccountがログに記録されます
    • EventID 4634 - ログオフの成功 - Contoso\ServiceAccountがログに記録されます
  • スクリプトを 2 回実行する
    • スクリプトはContoso\ServiceAccountとして実行されます
    • WMI 経由でコンピューターにアクセスして、セキュリティ イベント ログをプルするスクリプト
    • セキュリティ イベント ログには、最後にログオンしたユーザーがContoso\ServiceAccountであることが示されています
    • EventID 4624 - ログオン成功 - Contoso\ServiceAccountがログに記録されます
    • EventID 4634 - ログオフの成功 - Contoso\ServiceAccountがログに記録されます

これは、WMI にアクセスするには、コンピューターで認証する必要があるためです。基本的に、WMI はサービス アカウントを使用してコンピュータに "ログオン" し、必要な情報にアクセスし、情報を返し、ログオフします。

これが、奇妙な結果が得られる理由です。

これを修正するには、次の 3 つのオプションがあります。

1. 引き続き同じスクリプトを使用して、イベント ログ エントリを引き出します。サービス アカウント名を除外するコードを追加します。つまり、これを使用してユーザー名を取得します。

[System.Security.Principal.WindowsIdentity]::GetCurrent().Name

次に、「Where -FilterScript」を使用して、スクリプトを実行しているユーザーを除外します。

この方法の唯一の欠点は、さまざまなスケジュールされたタスクを実行している他の多くのサービス アカウント、または「最後に」ログオンしたユーザーを変更する起動スクリプトが存在する可能性があることです。最後にログオンした 5 人のユーザーをプルするほうがよい場合があります。そうすれば、何が起こっているかをよりよく理解できます。

2.次のコードを使用して、現在ログオンしているユーザーを取得します。

(gwmi -class win32_computerSystem -computer "ComputerName").username 

3.最後にログオンしたユーザーを取得する別の独自の方法は、ユーザー プロファイル ファイル (ntuser.dat) の最終書き込みアクセス時刻を使用することです。通常、「対話的に」ログインしているユーザーのみが、ユーザー プロファイルを作成されます。

(Get-ChildItem C:\users\*\ntuser.dat -Force | select @{e={(Split-path $_.Directory -Leaf)}},last* | sort lastwritetime -Descending
于 2013-08-28T16:59:55.947 に答える