none
Dsquery computer -inactive, can you trust the result?

    Question

  • i just ran "Dsquery computer -inactive 4 >c:\list.txt", and got a result of 74 inactive computer accounts... But what i really expected to get, were over 200 inactive computer accounts.
    But I have recently disablet about 150 computer accounts, so are they marked as "active" since i did that?
    Server 2003.
    Wednesday, February 17, 2010 10:22 AM

Answers

  • Hey
    I think it’s better to create new OU named old computers accounts and use the below script I tested it before and its working fine with AD 2003

    Note: the script will move the old accounts that didn’t authenticated with DC more than 30 days the default time for password synchronization between computer account and AD , the below script is editable you can change the 30 days as you want and can change  the name of the OU , after you run this script please review all machine in old computers OU before deleting them as you may find some accounts related to Cluster services , copy the content below and paste it into notepad file then change the extension to VBS  

    http://gallery.technet.microsoft.com/ScriptCenter/en-us/1abb142e-97d5-40ff-b6b8-430d3ca06ace


    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    'This script is designed to find inactive computer accounts in specified domain.
    'Once it found inactive computer accounts, script will move it into a specified OU.
    'Also,if script find an active account in specified OU, it will be moved back to Computers comtainer.
    'The "Inactive" condition is based on "PwdLastChange" properity of computer object.
    'Member computer(s)  will change it's password ( for computer account, not user.) every 30 days by default,
    'except administrator(s) disable this function.
    'If you did, don't use this script to clear inactive computer accounts in your AD domain.

     


    Option Explicit
    On Error Resume Next
    Const ADS_SCOPE_SUBTREE = 2
    Dim objConnection,objCommand,objRecordSet,objNewOU,objComputer,objOriComputer
    Dim strDomain
    Dim strDestOU
    Dim intConfirm
    Dim intDuration
    strDomain="DC=mantrac,DC=win2k,DC=dom"  'Provide your domain name here
    strDestOU="OU=Old Computer Acounts"  'Provide destination OU here. This OU must exist when your run this script.
    intDuration = 30    'Default password reset interval is 30 days. 45 days is author's suggestion.  

    Set objConnection = CreateObject("ADODB.Connection")
    Set objCommand =   CreateObject("ADODB.Command")
    objConnection.Provider = "ADsDSOObject"
    objConnection.Open "Active Directory Provider"

    Set objCOmmand.ActiveConnection = objConnection
    objCommand.CommandText = "Select Name,DistinguishedName from 'LDAP://" & strDomain & _
            "' where objectClass='computer'"
    objCommand.Properties("Page Size") = 1500
    objCommand.Properties("Timeout") = 30
    objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
    objCommand.Properties("Cache Results") = False

    Set objRecordSet = objCommand.Execute
    'Error occurs here means domain connection failed.
    If Err.Number <> 0 Then Wscript.Quit


    Set objNewOU = GetObject("LDAP://" & strDestOU & "," & strDomain)
    'Error occurs here means destination OU not exist.
    If Err.Number <> 0 Then Wscript.Quit

    Set objOriComputer = GetObject("LDAP://CN=Computers," & strDomain)


    objRecordSet.MoveFirst
    Dim dtmValue,intDateDiff,intSuccessCount,intErrorCount,intNotMoveCount,intMoveBack,objMoveComputer
    intSuccessCount = 0
    intErrorCount = 0
    intNotMoveCount = 0
    intMoveBack = 0

    Do While not objRecordSet.EOF
     Set objComputer = GetObject("LDAP://" & objRecordSet.Fields("DistinguishedName").Value)
     dtmValue = CDate(objComputer.PasswordLastChanged)
     
     
     
     intDateDiff=CInt(Now - dtmValue)

     If CInt(intDateDiff) > intDuration  Then
      If InStr(UCase(objRecordSet.Fields("DistinguishedName").Value),UCase(strDestOU) & ",") = 0 Then
       Set objMoveComputer = objNewOU.MoveHere _
            ("LDAP://" & objRecordSet.Fields("DistinguishedName").Value,"CN=" &_
             objRecordSet.Fields("Name").Value)
       If Err.Number = 0 Then
        intSuccessCount = intSuccessCount + 1
       Else
            
            intErrorCount = intErrorCount + 1
           End If
          Else
           'The computer has be moved to destination OU before.
           intNotMoveCount = intNotMoveCount + 1
          End If
     Else
      'Move the computer back to original Computers container if it is a active account.
      If InStr(UCase(objRecordSet.Fields("DistinguishedName").Value),UCase(strDestOU) & ",") <> 0 Then
           Set objMoveComputer = objOriComputer.MoveHere _
            ("LDAP://" & objRecordSet.Fields("DistinguishedName").Value,"CN=" &_
             objRecordSet.Fields("Name").Value)
           
           If Err.Number = 0 Then
            
            intMoveBack = intMoveBack +1
           Else
            
            intErrorCount = intErrorCount + 1
            
           End If
          End If
          
     End If
       
        objRecordSet.MoveNext
        Err.Clear
       
    Loop

    Wscript.Echo "Executive results:" & Chr(13) &_
      intSuccessCount & " computer(s) moved to specified OU, " & intErrorCount & " computer(s) Failed. " & Chr(13) & _
      intNotMoveCount & " computer(s) already in destination OU, "& intMoveBack & " computer(s) moved back to Computers container."

    Wednesday, February 17, 2010 12:08 PM

All replies

  • Thanks, this article http://gallery.technet.microsoft.com/ScriptCenter/en-us/6b8163d1-5fae-43b5-a664-a2d1f6e1e2da was great, but i'm not running windows server 2008 yet...  so no powershell..

    I just want to list all inactive computer accounts
    Wednesday, February 17, 2010 11:30 AM
  • Howdie!

    lansti schrieb:
    > Thanks, this article
    > http://gallery.technet.microsoft.com/ScriptCenter/en-us/6b8163d1-5fae-43b5-a664-a2d1f6e1e2da was
    > great, but i'm not running windows server 2008 yet... so no powershell..
    >
    > I just want to list all inactive computer accounts

    You need to understand that there's a difference between a disabled and
    an inactive account in Active Directory. Disabled accounts are just...
    disabled. You can't use them to log on. We call an account "inactive",
    if the account wasn't used for a certain amount of time.

    Keep in mind that purging inactive machines might also delete valid
    machine accounts -- like mobile machines (laptops, netbooks, ..).
    Deleting them results in problems when folks try to log on once they're
    back in your corporate network.

    If you're just trying to purge "legacy" accounts, I recommend you look
    into oldCMP, a tool by joe (http://www.joeware.net). It is free and has
    two modes: report and purge. It generates an HTML output of the computer
    accounts and, if you want it, deletes them off the directory.

    Cheers,
    Florian

    Microsoft MVP - Group Policy (http://www.frickelsoft.net/blog)
    Wednesday, February 17, 2010 11:47 AM
  • Hey
    I think it’s better to create new OU named old computers accounts and use the below script I tested it before and its working fine with AD 2003

    Note: the script will move the old accounts that didn’t authenticated with DC more than 30 days the default time for password synchronization between computer account and AD , the below script is editable you can change the 30 days as you want and can change  the name of the OU , after you run this script please review all machine in old computers OU before deleting them as you may find some accounts related to Cluster services , copy the content below and paste it into notepad file then change the extension to VBS  

    http://gallery.technet.microsoft.com/ScriptCenter/en-us/1abb142e-97d5-40ff-b6b8-430d3ca06ace


    -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    'This script is designed to find inactive computer accounts in specified domain.
    'Once it found inactive computer accounts, script will move it into a specified OU.
    'Also,if script find an active account in specified OU, it will be moved back to Computers comtainer.
    'The "Inactive" condition is based on "PwdLastChange" properity of computer object.
    'Member computer(s)  will change it's password ( for computer account, not user.) every 30 days by default,
    'except administrator(s) disable this function.
    'If you did, don't use this script to clear inactive computer accounts in your AD domain.

     


    Option Explicit
    On Error Resume Next
    Const ADS_SCOPE_SUBTREE = 2
    Dim objConnection,objCommand,objRecordSet,objNewOU,objComputer,objOriComputer
    Dim strDomain
    Dim strDestOU
    Dim intConfirm
    Dim intDuration
    strDomain="DC=mantrac,DC=win2k,DC=dom"  'Provide your domain name here
    strDestOU="OU=Old Computer Acounts"  'Provide destination OU here. This OU must exist when your run this script.
    intDuration = 30    'Default password reset interval is 30 days. 45 days is author's suggestion.  

    Set objConnection = CreateObject("ADODB.Connection")
    Set objCommand =   CreateObject("ADODB.Command")
    objConnection.Provider = "ADsDSOObject"
    objConnection.Open "Active Directory Provider"

    Set objCOmmand.ActiveConnection = objConnection
    objCommand.CommandText = "Select Name,DistinguishedName from 'LDAP://" & strDomain & _
            "' where objectClass='computer'"
    objCommand.Properties("Page Size") = 1500
    objCommand.Properties("Timeout") = 30
    objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
    objCommand.Properties("Cache Results") = False

    Set objRecordSet = objCommand.Execute
    'Error occurs here means domain connection failed.
    If Err.Number <> 0 Then Wscript.Quit


    Set objNewOU = GetObject("LDAP://" & strDestOU & "," & strDomain)
    'Error occurs here means destination OU not exist.
    If Err.Number <> 0 Then Wscript.Quit

    Set objOriComputer = GetObject("LDAP://CN=Computers," & strDomain)


    objRecordSet.MoveFirst
    Dim dtmValue,intDateDiff,intSuccessCount,intErrorCount,intNotMoveCount,intMoveBack,objMoveComputer
    intSuccessCount = 0
    intErrorCount = 0
    intNotMoveCount = 0
    intMoveBack = 0

    Do While not objRecordSet.EOF
     Set objComputer = GetObject("LDAP://" & objRecordSet.Fields("DistinguishedName").Value)
     dtmValue = CDate(objComputer.PasswordLastChanged)
     
     
     
     intDateDiff=CInt(Now - dtmValue)

     If CInt(intDateDiff) > intDuration  Then
      If InStr(UCase(objRecordSet.Fields("DistinguishedName").Value),UCase(strDestOU) & ",") = 0 Then
       Set objMoveComputer = objNewOU.MoveHere _
            ("LDAP://" & objRecordSet.Fields("DistinguishedName").Value,"CN=" &_
             objRecordSet.Fields("Name").Value)
       If Err.Number = 0 Then
        intSuccessCount = intSuccessCount + 1
       Else
            
            intErrorCount = intErrorCount + 1
           End If
          Else
           'The computer has be moved to destination OU before.
           intNotMoveCount = intNotMoveCount + 1
          End If
     Else
      'Move the computer back to original Computers container if it is a active account.
      If InStr(UCase(objRecordSet.Fields("DistinguishedName").Value),UCase(strDestOU) & ",") <> 0 Then
           Set objMoveComputer = objOriComputer.MoveHere _
            ("LDAP://" & objRecordSet.Fields("DistinguishedName").Value,"CN=" &_
             objRecordSet.Fields("Name").Value)
           
           If Err.Number = 0 Then
            
            intMoveBack = intMoveBack +1
           Else
            
            intErrorCount = intErrorCount + 1
            
           End If
          End If
          
     End If
       
        objRecordSet.MoveNext
        Err.Clear
       
    Loop

    Wscript.Echo "Executive results:" & Chr(13) &_
      intSuccessCount & " computer(s) moved to specified OU, " & intErrorCount & " computer(s) Failed. " & Chr(13) & _
      intNotMoveCount & " computer(s) already in destination OU, "& intMoveBack & " computer(s) moved back to Computers container."

    Wednesday, February 17, 2010 12:08 PM
  • Howdie!

    sameh.khairy schrieb:
    > intDuration = 30 'Default password reset interval is 30 days. 45 days
    > is author's suggestion.

    45 is still a pretty aggressive number. There are a lot of places where
    employees are off network for more than 45 days. I, personally, wouldn't
    go below 90 days -- like that you _really_ get the orphaned machine
    accounts. Everything below it is just asking for helpdesk calls IMHO.

    Cheers,
    florian

    Microsoft MVP - Group Policy (http://www.frickelsoft.net/blog)
    Wednesday, February 17, 2010 1:15 PM
  • Hi Florian,


    That’s right 30-45 is a short period I usually use it for 90 days instead of 30 and that’s  why I told him that he can change number of days as he want

    Wednesday, February 17, 2010 1:18 PM
  • Has anyone tried this?
    Tuesday, March 02, 2010 4:28 PM
  • yes i tried this many times and it working fine with me
    Tuesday, March 02, 2010 8:30 PM
  • Does it work on server 2008, has any one checked it 
    Monday, December 19, 2011 2:41 PM
  • Hi

    Is this script works for WIndows 2008 R2 Domain controller ?

    Instead of looking in to complete domain can we make source as a OU because it is if you run this script it is showing built in Users and Computer accounts as inactive for so days ?

    Like destination OU can we  search objects in specific source OU ?

    mANGESH

    Thursday, July 05, 2012 2:32 PM