When we look at the computer account attributes (which we can retrieve using PowerShell), we see a number of interesting values.
Import-Module ActiveDirectory Get-ADComputer -Identity <computer-name> -Properties *
The computer or user account in Active Directory has the lastLogonTimestamp attribute. This value indicates when the computer or user last logged in to the domain. Unfortunately, this value is not accurate for (by default) values shorter than 14 days. It's due to the way it works, each time a user logs in, the value is read and checked if it is older than current_time - msDS-LogonTimeSyncInterval, if so, it is updated. By default, msDS-LogonTimeSyncInterval is 14 days minus a random number up to 5 days. The lastLogonTimestamp value is replicated between domain controllers.
The msDS-LogonTimeSyncInterval value is set on the domain, and we can view/change it using Active Directory Users and Computers (right-click on the domain name - Properties - Attribute Editor). If the value is not-set, it means the default is 14 days. If we set a value less than 5, the random value is not subtracted, if we set 0, the use of lastLogontimeStamp is disabled. This is all set up to avoid replicating too much data. But in smaller environments, this is not a problem.
If we use the PowerShell command Get-ADComputer (interestingly, this command also returns the IP address, which is not a computer account attribute, it seems to be taken from DNS data), we can return the lastLogonTimestamp attribute value of type System.Int64 or convert it based on the current time zone to a date from the LastLogonDate attribute (type System.DateTime).
Get-ADComputer -Identity <computer-name> -Properties * | FT Name, LastLogonDate, LastLogon, lastLogonTimestamp, IPv4Address
Then we also have the lastLogon attribute, which contains the actual time of the last login, but it is not replicated, so we would have to ask all DCs and take the newest value. It is also stored as a number and we can convert it to a date using a function.
[DateTime]::FromFileTime([Int64]::Parse((Get-ADComputer -Identity <computer-name> -Properties lastLogon).lastLogon))
If we want to find accounts that haven't logged in for a long time, the lastLogonTimestamp value is usually sufficient if we're happy with values older than 14 days. For example, we can search for computers that haven't logged in for more than 30 days in the following way.
$ldate = [DateTime]::Now - [TimeSpan]::Parse("30")
Get-ADComputer -Filter { lastLogonTimestamp -le $ldate } -Properties * | FT Name, LastLogonDate, Enabled, LockedOut -AutoSize
If we were to do more detailed tests, we might run into the fact that some accounts don't show up in the output. These are the ones that have never logged in, and their lastLogonTimestamp value is empty, which probably happens more with user accounts. I don't know why, but we can't compare the null value in the filter, so we need to rewrite the previous command a bit.
$ldate = ([DateTime]::Now - [TimeSpan]::Parse("30")).ToFileTime()
Get-ADComputer -Filter * -Properties * | Where-Object { ($_.lastLogonTimestamp -le $ldate) -or ($_.lastLogonTimestamp -eq $null) } | FT Name, LastLogonDate, Enabled, LockedOut -AutoSize
We also have a simpler option using the Search-ADAccount command, but this command doesn't return all the attributes.
Search-ADAccount -ComputersOnly -AccountInactive -TimeSpan "30" | FT Name, LastLogonDate, Enabled, LockedOut -AutoSize
If we want to find the time when the computer last booted up, we can't use either the lastLogonTimestamp or lastLogon value, because computer authentication also occurs during its runtime. The value of when the computer last started up is probably only on the computer itself. We can get it using WMI.
[System.DateTime]::ParseExact((Get-WmiObject -Class Win32_OperatingSystem -ComputerName <computer-name>).LastBootUpTime.split('.')[0],'yyyyMMddHHmmss',$null)
We can then, for example, do a test that goes through computers from a given container in AD, checks if the computer is turned on, and if so, finds the date of the last start.
Get-ADComputer -Filter * -SearchBase "OU=Computers,DC=firm,DC=local" |
ForEach-Object {
$str = $_.Name + ", "
if(Test-Connection -ComputerName $_.Name -Count 1 -Quiet) {
$str += "running, "
$str += [System.DateTime]::ParseExact((Get-WmiObject -Class Win32_OperatingSystem -ComputerName $_.Name).LastBootUpTime.split('.')[0],'yyyyMMddHHmmss',$null)
}
$str
}
Dobry den, mozna jsem prehledl .... nicmene lze pomoci podobneho powershell scriptu ziskat vypis vsech pocitacu v AD na kterych se uzivatel zalogoval v nejake definovane dobe (posledni dva tydny) vcetne casovych udaju. Jinymi slovy ziskat vypis typu: uzivatel 'user1' se zalogoval behem minuleho tydne na techto hostnames v v techto casech. Snad dava smysl :-). Dekuji Ondrej
respond to [1]Ondrej: hoj, zkusil bych utilitku ze sysinternals "PsLoggedOn"
Dobrý den, chtěl bych se zeptat, je možné vypsat pro konkrétní počítač, který uživatel se na něj kdy zalogoval? Nedaří se mi najít návod jak to zjistit
respond to [3]Radek: Hodně těžko. Takový údaj je pouze v Security logu a záleží na logování. Vytahuje se to složitě.