Workflow for last logon

PowerShell Workflows have been a bit of an underachiever in terms of their adoption and use.

Something I read prompted the thought that there are a number of activities when working with Active Directory where you have to interrogate a number of machines to get the result.

That’s something that workflows are good at.

A common problem is when did that user last logon. Using the Microsoft cmdlets you get this:

£> Get-ADUser -Identity Richard -Properties * -Server server02  | fl lastlogon* lastLogon          : 130677233108205070
LastLogonDate      : 30/01/2015 14:05:58
lastLogonTimestamp : 130671003582718505

£> Get-ADUser -Identity Richard -Properties * -Server W12R2SCDC01  | fl lastlogon*
lastLogon          : 130671225126188854
LastLogonDate      : 30/01/2015 14:05:58
lastLogonTimestamp : 130671003582718505

Lastlogontimestamp is the identical across the 2 DCs because it’s replicated – however its not always up to date. It can be up to 14 days out.

Now the lastlogon and lastlogontimestamp are not in a readable format – so need a bit of work on that

$dc = “server02”

Get-ADUser -Identity Richard -Properties lastLogon, LastLogonDate, lastLogonTimestamp -Server $dc  |
select Name, LastLogondate,
@{N=’LastLogon’; E={[datetime]::FromFileTime([int64]::Parse($_.lastlogon))}},
@{N=’LastLogonTimestamp’; E={[datetime]::FromFileTime([int64]::Parse($_.lastlogonTimestamp))}},
@{N= ‘Domain Controller’; E={$dc}}

Name               : Richard
LastLogondate      : 30/01/2015 14:05:58
LastLogon          : 06/02/2015 19:08:30
LastLogonTimestamp : 30/01/2015 14:05:58
Domain Controller  : server02

You can see that the lastlogondate (Introduced with Windows 2008 R2) is the lastlogontimestamp in a readable format.  Notoce the difference between the lastlogon and the lastlogontimestamp.

The calculation to get the date is relatively straightforward. Start by converting the property to a int64


Then treat that as a filetime and convert to a datetime


Now lets look at getting that data from multiple machines in parallel

workflow get-lastlogon {
param (

foreach -parallel ($dc in $computername) {
    Get-ADUser -Identity Richard -Properties lastLogon, LastLogonDate, lastLogonTimestamp -Server $dc  |
  Select-Object -Property Name, LastLogondate,
  @{N=’LastLogon’; E={[datetime]::FromFileTime([int64]::Parse($_.lastlogon))}},
  @{N=’LastLogonTimestamp’; E={[datetime]::FromFileTime([int64]::Parse($_.lastlogonTimestamp))}} |
  Add-Member -MemberType NoteProperty -Name ‘DomainController’ -Value $dc -PassThru

get-lastlogon -computername (Get-ADDomainController -Filter * | select -ExpandProperty Name)

The workflow accepts an array of computer names. A foreach –parallel  loop is use do run the Get-Aduser command.

One oddity was setting the Domain Controller name into the output object. It wouldn’t accept the value when I used a select calculated field but I could use Add-Member. 

if I figure out what’s going on I post the  information

This entry was posted in PowerShell and Active Directory. Bookmark the permalink.

One Response to Workflow for last logon

  1. bgwest says:

    I’ve had some good luck with the Domain Controller thing.
    do something like this
    $domains = (Get-ADForest).Domains
    Workflow Check-Users
    foreach -Parallel ($Domain in $Domains)
    $ndc = Get-ADDomainController -Domain $Domain -Discover -NextClosestSite -Service ADWS

    The caveat here is that you have to refer to the Domain Controller by the property .HostName with the array position
    ex $ndc.Hostname[0]

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s