none
Get inactive users through "Lastlogon" attribute RRS feed

Answers

  • The PSLastLogon.ps1 script linked on this page (PSLastLogon.txt) is very similar to the one I posted, but uses the DirectorySearcher object:

    http://www.rlmueller.net/Last%20Logon.htm

    It should be much faster (in my experience). The filter must be changed to restrict the query to enabled users, as follows:

    $Searcher.Filter = "(&(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2))"
    

    Notice that the final loop is very similar. You could add the statements to retrieve Name and sAMAccountName, but that would slow the script. I would like feedback on relative performance.

    If the PowerShell script using DirectorySearcher is still too slow, then try the VBScript version on the page I linked above (LastLogon.txt). That should be faster still (again, in my experience).


    Richard Mueller - MVP Directory Services

    Wednesday, October 7, 2015 10:36 PM
    Moderator

All replies

  • Hi,

    Use -Filter "Enabled -eq 'True'" for Get-ADUser instead of specifying a username to get all enabled users.


    Wednesday, October 7, 2015 4:06 PM
  • Hi Mike,

    I tried, but this error was showed:

    Program 'w32tm.exe' failed to run: The filename or extension is too longAt line:1 char:201
    + ...  echo "$DC - $(w32tm /ntte $user.lastlogon)" }  )
    +                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~.
    At line:1 char:201
    + ...  echo "$DC - $(w32tm /ntte $user.lastlogon)" }  )
    +                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : ResourceUnavailable: (:) [], ApplicationFailedException
        + FullyQualifiedErrorId : NativeCommandFailed

    I need only the name, samaccountname and last logon of enabled users. (Greater than or equal to 60 days).


    David Soares MCTS:MBS - MCTS - MCITP

    Wednesday, October 7, 2015 4:19 PM
  • Drop that entire portion and do the conversion in the select statement.

    Wednesday, October 7, 2015 4:21 PM
  • Could you give me a example?

    David Soares MCTS:MBS - MCTS - MCITP

    Wednesday, October 7, 2015 4:27 PM
  • http://stackoverflow.com/questions/13091719/converting-lastlogon-to-datetime-format

    Get-ADUser tester1 -Properties LastLogon |
        Select @{N='LastLogon';E={[DateTime]::FromFileTime($_.LastLogon)}}



    Wednesday, October 7, 2015 4:36 PM
  • I assume you don't need the lastLogon value on every DC, but just the most recent value (the largest). Here is a script I used some time ago. I revised it to also retrieve Name and sAMAccountName, but this will slow the script somewhat.

    # Create hash table of users and their last logon dates.
    $arrUsers = @{}
    
    # Enumerate every Domain Controller in the domain.
    # All DC's must support the AD Module cmdlets.
    $DCs = Get-ADDomainController -Filter *
    ForEach ($DC In $DCs) {
        $Server = $DC.Name
        # Retrieve DN and lastLogon for all enabled users on this DC.
        $Users = Get-ADUser -Filter {Enabled -eq $True} `
            -Properties lastLogon -Server $($Server)
        ForEach ($User In $Users) {
            $DN = $User.distinguishedName
            $LL = $User.lastLogon
            If ($LL -eq $Null)
            {
                $T = [Int64]0
            }
            Else
            {
                $T = [Int64]::Parse($LL)
            }
            $D = [DateTime]::FromFileTime($T)
            If ($arrUsers.ContainsKey("$DN"))
            {
                If ($D -gt $arrUsers["$DN"])
                {
                    $arrUsers["$DN"] = $D
                }
            }
            Else
            {
                $arrUsers.Add("$DN", $D)
            }
        }
    }
    
    # Output latest last logon date for each user.
    $Users = $arrUsers.Keys
    ForEach ($DN In $Users)
    {
        $Date = $arrUsers["$DN"]
        # Bind to user to retrieve other attributes.
        # It makes little sense to retain these values in the hash table.
        $User = Get-ADUser -Identity $DN
        $Name = $User.Name
        $NTName = $User.sAMAccountName
        # Output in comma delimited format.
        """$DN"",$Date,$Name,$NTName"
    }
    

    The script outputs in comma delimited format. You can redirect to a text file and open the file in Excel.

    Richard Mueller - MVP Directory Services

    Wednesday, October 7, 2015 5:05 PM
    Moderator
  • Mike, it's possible to use this script retrieving just the most recent value? (Some users are showed with last logon 14 days ago)

    David Soares MCTS:MBS - MCTS - MCITP

    Wednesday, October 7, 2015 9:45 PM
  • The purpose of the script I posted is to only keep track of the latest lastLogon value for each user. It uses a hash table to keep track of every user and only update lastLogon from a DC if the value is greater than any other for the user. The script is longer, but that is necessary to do this.


    Richard Mueller - MVP Directory Services


    Wednesday, October 7, 2015 9:48 PM
    Moderator
  • Richard thanks for tip.

    I have 13000 enabled users at company.



    It's possible remove some items to speed up the outputs?


    David Soares MCTS:MBS - MCTS - MCITP

    Wednesday, October 7, 2015 9:51 PM
  • To be honest, the part that may be slowing the script down is in the last loop where the script binds to each user object to retrieve Name and sAMAccountName. You might try removing that, and just use:

    # Output latest last logon date for each user.
    $Users = $arrUsers.Keys
    ForEach ($DN In $Users)
    {
        $Date = $arrUsers["$DN"]
        # Output in comma delimited format.
        """$DN"",$Date"
    }
    

    This is how my original script looked. When I get a chance, I will look at the rest of the script, but any time you must contact all DC's in the domain, that can take a long time. But other than the extra binding in the last loop, the query on each DC is efficient, as the information on all the users is retrieved in one query. The processing in local memory to format the datetime value should not take much time.

    Another thought is to use the DirectorySearcher object and PowerShell V1. In the past, that has been faster for me. I will look for a script using this later today.


    Richard Mueller - MVP Directory Services

    Wednesday, October 7, 2015 10:07 PM
    Moderator
  • The PSLastLogon.ps1 script linked on this page (PSLastLogon.txt) is very similar to the one I posted, but uses the DirectorySearcher object:

    http://www.rlmueller.net/Last%20Logon.htm

    It should be much faster (in my experience). The filter must be changed to restrict the query to enabled users, as follows:

    $Searcher.Filter = "(&(objectCategory=person)(objectClass=user)(!userAccountControl:1.2.840.113556.1.4.803:=2))"
    

    Notice that the final loop is very similar. You could add the statements to retrieve Name and sAMAccountName, but that would slow the script. I would like feedback on relative performance.

    If the PowerShell script using DirectorySearcher is still too slow, then try the VBScript version on the page I linked above (LastLogon.txt). That should be faster still (again, in my experience).


    Richard Mueller - MVP Directory Services

    Wednesday, October 7, 2015 10:36 PM
    Moderator
  • Great!!!

    The script worked perfectly, Richard.

    Thank you very much!


    David Soares MCTS:MBS - MCTS - MCITP

    Thursday, October 8, 2015 5:16 PM