0

更新

@HAL9256

你的回答真让我深思!

我做了一些谷歌搜索,发现这个网站提供了另一种方法

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"

我第一次运行它时,它会输出用户的 Window 的登录名

我第二次使用相同的输入运行相同的脚本时,它输出的服务帐户与我用于运行 powershell 脚本的服务帐户相同

当我尝试使用相同的输入运行相同的脚本时,我得到了相同服务帐户的输出。

~~~~~~~

接下来,我尝试使用另一个 IP 地址运行脚本

第一次运行脚本时,它会输出 Window 的登录名

我第二次运行脚本时,它会输出与运行 powershell 脚本相同的服务帐户

~~~~~~~

这似乎是一种模式。第一次运行脚本,它返回正确的输入,第二次运行,它返回服务帐户。

为什么会这样?

无论调用多少次,如何使脚本始终返回正确的输出?

如何解决这个问题?

4

1 回答 1

2

This is because of how your script gets the information about the last logged on user.

You are getting the last logged on user from the security event log. This logs everyone who "logs on" to the computer... including accesses by WMI, service accounts, etc.

What's happening is:

  • Before Script Runs
    • Contoso\User1 logs onto computer
    • EventID 4624 - Logon Success - Contoso\User1 is Logged
  • Run Script the First time
    • Script runs as Contoso\ServiceAccount
    • Script access computer Via WMI to pull Security Event Log
    • Security Event Log shows last logged on user was Contoso\User1
    • EventID 4624 - Logon Success - Contoso\ServiceAccount is Logged
    • EventID 4634 - Logoff Success - Contoso\ServiceAccount is Logged
  • Run Script the Second time
    • Script runs as Contoso\ServiceAccount
    • Script access computer Via WMI to pull Security Event Log
    • Security Event Log shows last logged on user was Contoso\ServiceAccount
    • EventID 4624 - Logon Success - Contoso\ServiceAccount is Logged
    • EventID 4634 - Logoff Success - Contoso\ServiceAccount is Logged

This is because in order to access WMI, you have to authenticate on the computer. Essentially, WMI uses your service account to "log onto" the computer, access the information that it needs, returns the information, and logs off.

This is why you are getting the weird results.

To fix this, you have 3 options:

1.Continue to use the same script to pull out the event log entries. Add code to Filter out the service account name. i.e. use this to get the username:

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

Then use the "Where -FilterScript" to filter out the user that the script is running as.

The only downside to this method, is that there could be a lot of other service accounts that are running various scheduled tasks, or startup scripts that could change who the "last" logged on user was. It may be better to pull the last 5 logged on users, and then you would have a better idea of what's going on.

2.Use this code to get the currently logged on user:

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

3.A different and unique way of getting the last logged on user is to use the last write access time on the user profile file (ntuser.dat). Typically only a user logging in "Interactively" will get have a user profile created.

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