Powershell - last logged on user - same input, different output

你。 提交于 2019-12-25 03:14:05

问题


UPDATE

@ HAL9256

Your answer really made me think!

I did some more googling, and found this website which offers another approach

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

So far, it works!

I remote into another server to run a powershell script that displays the last logged on user.

Several things

  1. It only works when I run it in the context of a service account, not the Administrator
  2. It takes several minutes to output

But when I run it in the contenxt of a service account, I get different output for the same input

$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

For instance, I invoke the script on commandline with

script.ps1 "sender-ip=10.10.10.10"

The first time I run it, it outputs the user's Window's logon name

The second time I run the same script with same input, it outputs the same service account I used to run the powershell script with

And when I try to run same script with same input, I get the output of this same service account.

~~~~~~~

Next, I try to run the script with another IP address

First time I run the script it outputs the Window's logon name

Second time I run the script, it outputs that same service account from which the powershell script is running

~~~~~~~

This seems to be a pattern. First time script it run, it return correct input, second time it is run, it returns the service account.

Why is this happening?

How to make the script always return the correct output no matter how many times it is invoked?

How to troubleshoot this?


回答1:


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


来源:https://stackoverflow.com/questions/18488892/powershell-last-logged-on-user-same-input-different-output

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!