• Powershell script to get all computers last logon time

    by  • 2011/05/29 • Tech • 26 Comments

    Update:

    I’ve posted an updated version of this script in a new section of my blog. Because all the comments below relate to the original version of the script I’m going to leave that version posted here. You can find the new version of the script here.

    I wrote a script to get the last time each computer logged into the domain.

    This script is very similar to my script that gets user last logon times, which you can find here.

    This script requires the Quest AD Cmdlets, which you can download here. (Check the box agreeing to the terms to see the download options.)

    <br />
    ##==============================================================================<br />
    ##==============================================================================<br />
    ## SCRIPT.........: Get-AllComputerLastLogon<br />
    ## AUTHOR.........: Clint McGuire<br />
    ## EMAIL..........:<br />
    ## VERSION........: 1<br />
    ## DATE...........: 2011_05_26<br />
    ## COPYRIGHT......: 2011, Clint McGuire<br />
    ## LICENSE........:<br />
    ## REQUIREMENTS...: Powershell v2.0, Quest AD Cmdlets<br />
    ## DESCRIPTION....: Gets all computer accounts' last logon times and exports to CSV file.<br />
    ## NOTES..........:<br />
    ## CUSTOMIZE......:<br />
    ##==============================================================================<br />
    ## REVISED BY.....:<br />
    ## EMAIL..........:<br />
    ## REVISION DATE..:<br />
    ## REVISION NOTES.:<br />
    ##<br />
    ##==============================================================================<br />
    ##==============================================================================<br />
    ##==============================================================================<br />
    ## START <code><br />
    ##==============================================================================<br />
    $DCs = Get-QADComputer -ComputerRole DomainController<br />
    $LastLogon = @{}<br />
    ForEach ($DC in $DCs) {<br />
    $Computers = Get-QADcomputer -Service $dc.dnshostname -ip lastlogontimestamp<br />
    ForEach ($Computer in $Computers)<br />
    {<br />
    If ($Computer.lastlogontimestamp -ne $null)<br />
    {<br />
    $Time = $Computer.lastlogontimestamp | Get-Date -format u<br />
    }<br />
    Else<br />
    {<br />
    $Time = $Computer.lastlogontimestamp<br />
    }<br />
    $ComputerName = $Computer.ComputerName<br />
    If ($LastLogon.ContainsKey($ComputerName))<br />
    {<br />
    If ($LastLogon.Get_Item($ComputerName) -le $Time)<br />
    {<br />
    $LastLogon.Set_Item($ComputerName, $Time)<br />
    }<br />
    }<br />
    Else<br />
    {<br />
    $LastLogon.Add($ComputerName, $Time)<br />
    }<br />
    }<br />
    }<br />
    $LastLogon.GetEnumerator() | Sort-Object Name |export-csv $home\ComputerLastLogon.csv -NoTypeInformation<br />
    ##==============================================================================<br />
    ## END <code><br />
    ##==============================================================================

    About

    Clint McGuire is a Computer Consultant based out of Vancouver Canada. He specializes in VMware and Storage.

    26 Responses to Powershell script to get all computers last logon time

    1. Martin Spencer
      2011/08/11 at 7:02 PM

      Hi Clint,
      Thanks for this script it was very handy for me to do an AD cleanup. My scripting knowledge is non-existent and I’m just learning the ropes now. How easy is it to include in the CSV file the machine type. I have seen the variable is $machineType I’m just a bit lost as too where to put it.
      Thanks alot,
      Marty

      • clint
        2011/08/14 at 10:47 AM

        $machineType isn’t a property of the Computer Object in AD. “Type” is a property, but in my tests it only returned “Computer”.
        Run this command to see if you can find what you are looking for:
        Get-QADComputer somecomputername | Get-Member
        This will give you a list of all the Methods and Properties for the computer “somecomputername”.
        Once you find a Property in the list that looks interesting run this command:
        (Get-QADComputer somecomputername ).PropertyName [Where “PropertyName” is the interesting option from the list returned above.]
        This will return the value of the property for that computer.
        Once you find something useful you can add it to the array. If you are looking for more than 2 values (eg: computer name, last logon time and OS Version) then you will probably not want to use an array.

    2. Martin Spencer
      2011/08/18 at 3:07 PM

      Thanks for the help Clint got it sorted

    3. Rodrigo Gomes
      2011/08/30 at 4:31 AM

      Obrigado por sua contribuição.

      Rodrigo – Brasil.

    4. Par Wallin
      2012/02/23 at 11:58 AM

      This is what I get!

      The term ‘Get-QADComputer’ is not recognized as the name of a cmdlet, function,
      script file, or operable program. Check the spelling of the name, or if a path
      was included, verify that the path is correct and try again.
      At C:\Users\sepawa0.DELLNER\desktop\powershell\LastLogonPC.ps1:25 char:24
      + $DCs = Get-QADComputer <<<< -ComputerRole DomainController
      + CategoryInfo : ObjectNotFound: (Get-QADComputer:String) [], Com
      mandNotFoundException
      + FullyQualifiedErrorId : CommandNotFoundException

      The term 'Get-QADcomputer' is not recognized as the name of a cmdlet, function,
      script file, or operable program. Check the spelling of the name, or if a path
      was included, verify that the path is correct and try again.
      At C:\Users\sepawa0.DELLNER\desktop\powershell\LastLogonPC.ps1:28 char:30
      + $Computers = Get-QADcomputer <<<< -Service $dc.dnshostname -ip lastlogontim
      estamp
      + CategoryInfo : ObjectNotFound: (Get-QADcomputer:String) [], Com
      mandNotFoundException
      + FullyQualifiedErrorId : CommandNotFoundException

      Exception calling "ContainsKey" with "1" argument(s): "Key cannot be null.
      Parameter name: key"
      At C:\Users\sepawa0.DELLNER\desktop\powershell\LastLogonPC.ps1:40 char:28
      + If ($LastLogon.ContainsKey <<<< ($ComputerName))
      + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
      + FullyQualifiedErrorId : DotNetMethodException

    5. Eric
      2012/03/08 at 6:05 AM

      This won’t do any damage to current OU’s in a production AD environment will it?

      -Eric

      • clint
        2012/03/12 at 10:53 PM

        No, it wont. I grabs a list of all your domain controllers, then asks each DC for the last time each computer account logged in. It builds a table in a variable and checks to see if there is a more recent login time on a different DC, keeping only the latest login. Once it has checked all DCs it dumps the table into a CSV file.
        It doesn’t make any changes.

    6. Anthony
      2012/03/16 at 1:38 AM

      Hi Clint,
      I was wondering how to point this script at a specific container? I manage a container on our domain in which we put hundreds, sometimes thousands of computer objects depending on the event. We want to know if we may be putting out to many computers in some instances so we would like to have some last logon data from this container to analyze. Any help would be greatly appreciated.

      • clint
        2012/03/18 at 10:57 PM

        You can modify this line “$Computers = Get-QADcomputer -Service $dc.dnshostname -ip lastlogontimestamp” to specify the container/OU by adding “-SearchRoot” and specifying the DN, GUID or canonical name of the container/OU you want to search.
        You might want to check out the documentation for this cmdlet for a few other things you can add. http://wiki.powergui.org/index.php/Get-QADComputer

    7. Paul
      2012/05/24 at 12:07 AM

      Hi Clint,

      The output I’m getting in the .csv file looks just like this:

      #TYPE System.Collections.DictionaryEntry
      Name Key Value
      $DUPLICATE-2d36 $DUPLICATE-2d36
      105COACH1$ 105COACH1$
      105MICROFILM$ 105MICROFILM$

      I do not get any dates or times. Any ideas why that may be?

      Cheers,

      Paul.

    8. Eric
      2012/05/24 at 8:55 AM

      Here is what my final version looked like and worked. We have specific a Domain Controller and a specific “computer group” that I monitor for asset management. I just wanted to view the corporate laptops and desktops instead of all the computers in the domain controller. Does basically the same thing as Clint’s…

      #########################
      # AD Cleanup for Desktops
      # Author: Eric
      # Version 1.2
      #########################

      cls

      ######################################
      #Begin script
      ######################################

      $NumberDays=90
      $COMPAREDATE=GET-DATE
      disconnect-QADService
      Connect-QADService your domain control address (ex: i.like.food.org:389)
      $Comps = get-qadcomputer -searchroot ” OU=CORPORATE DESKTOPS,OU=CORPORATE COMPUTERS,DC=I,DC=LIKE,DC=FOOD,DC=ORG ” -LdapFilter ‘(!(userAccountControl:1.2.840.113556.1.4.803:=2))’ -IncludedProperties LastLogonTimeStamp | where { ($CompareDate-$_.LastLogonTimeStamp).Days -gt $NumberDays } | Select-Object Name, LastLogonTimeStamp, OSName | Sort-Object ModificationDate, Name
      disconnect-QADService
      $Comps | Export-Csv -NoTypeInformation DESKTOP_List.csv

    9. Prasad
      2012/06/15 at 7:46 AM

      Thanks for the script,but its giving list from only current domain.how to get reports from multiple domains.

      • clint
        2012/06/15 at 11:12 AM

        Look at the documentation from Quest for the Get-QADComputer cmdlet.

      • Eric
        2012/06/18 at 5:44 AM

        Sorry about that. the get-QADComputer script should be above that.

        ######################################
        #Load Needed Snapins (Just in case)
        ######################################
        $Snapins = “Quest.ActiveRoles.ADManagement”
        $LoadedSnapins = get-pssnapin
        foreach ($Snapin in $Snapins)
        {
        if ((select-string -simplematch $snapin -inputobject $LoadedSnapins) -eq $null)
        {
        write-host “Loading Snap-in: $snapin”
        Add-PSSnapin $snapin
        }
        }

        $LoadedSnapins = get-pssnapin
        foreach ($Snapin in $Snapins)
        {
        if ((select-string -simplematch $snapin -inputobject $LoadedSnapins) -eq $null)
        {
        write-host ‘ERROR: Unable to load one or more Snap-ins’
        exit 1
        }
        }

    10. Jim
      2012/10/10 at 8:20 AM

      Clint,

      I tried running the script but I am getting an strange error:

      Get-QADComputer : Cannot validate argument on parameter ‘Service’. The argument is null or empty. Supply an argument that is not null or empty and then try the command again.
      At line:2 char:38
      + $Computers = Get-QADcomputer -Service <<<< $dc.dnshostname -ip lastlogontimestamp
      + CategoryInfo : InvalidData: (:) [Get-QADComputer], ParameterBindingValidationException
      + FullyQualifiedErrorId : ParameterArgumentValidationError,Quest.ActiveRoles.ArsPowerShellSnapIn.Powershell.Cmdlet s.GetComputerCmdlet

      Can you assist, I've attempted to search for an answer but can't really find anything relative to this particular error.
      Thanks in advance.

      • clint
        2012/10/10 at 11:43 AM

        Hi Jim,

        I have been unable to re-create this error.
        Are you running this script locally on a DC or remotely on another machine?
        Can you post your entire script here or email it to me? (Email address on Contact page)

        Thanks,

        Clint

    11. Wayne Lundquist
      2012/12/03 at 10:41 AM

      When I run the script I get an error that the search is only configured to retrieve the first 1000 computers. How to do set it so there is now size limit.

      • Clint
        2012/12/04 at 12:06 PM

        Hi Wayne,
        Try this out…
        Add “-ResultSize Unlimited” to line 4 of the actual code.
        It should look like this:
        $Computers = Get-QADcomputer -ResultSize Unlimited -Service $dc.dnshostname -ip lastlogontimestamp

        I don’t have an environment large enough to test this in, so let me know how it goes.
        If you have further issues you can email, address on Contacts page.

    12. 2012/12/05 at 8:33 AM

      Hi Clint,
      I am trying to run the script you posted, I am getting the following error

      [PS] C:\WINDOWS>$Computers = Get-QADcomputer -Service $dc.dnshostname -ip lastlogontimestamp
      Get-QADComputer : Cannot validate argument on parameter ‘Service’. The argument is null or empty. Supply an argument th
      at is not null or empty and then try the command again.
      At line:1 char:38
      + $Computers = Get-QADcomputer -Service <<<< $dc.dnshostname -ip lastlogontimestamp
      + CategoryInfo : InvalidData: (:) [Get-QADComputer], ParameterBindingValidationException
      + FullyQualifiedErrorId : ParameterArgumentValidationError,Quest.ActiveRoles.ArsPowerShellSnapIn.Powershell.Cmdlet
      s.GetComputerCmdlet

      I have the snapin installed and i am running it local as a domain admin, hope you can help.

      • Clint
        2012/12/14 at 2:58 PM

        Hi Sean,
        It looks from that snip that you are not running the script as a whole but just that one line…
        Are you running the whole script at once?
        If so, please post the script (or email, my details are on the contact page).
        If not, please try that.

        Thanks,
        Clint

    13. Goni
      2014/02/19 at 1:32 AM

      Hi Clint,

      how to find together with the lastlogontimestamp, the user that had lastlogon to that computer?

      Thanks

      • Clint
        2014/02/19 at 9:15 AM

        Check the event log to see if you can find the last entry for a user logon.

    14. Martin
      2014/10/24 at 8:36 AM

      Hi Clint

      Awesome script, I’m kinda new on this, how can I modify the script so it gets an specific list of computers from a .txt file instead of the entire domain?

      Thanks in advance!

      • Clint
        2015/01/05 at 9:42 AM

        Hi Martin,

        You can use Get-Content to read from your text file. You will need to move the Get-QADComputer into the ForEach loop, so that you only look up the specific computers.

        Instead of:
        $Computers = Get-QADcomputer -Service $dc.dnshostname -ip lastlogontimestamp
        ForEach ($Computer in $Computers)

        You would have something like:
        $Computers = Get-Content $home\computernames.txt
        ForEach ($Computer in $Computers)
        {
        Get-QADcomputer $computer -Service $dc.dnshostname -ip lastlogontimestamp

    Leave a Reply

    Your email address will not be published. Required fields are marked *