Have you ever been left wondering which computers on your domain have been neglected by their user and not restarted in forever? This is a question that come up in my office every once and a while. One of the easiest ways to solve this problem is to ask WMI for when the computer was last restarted and subtract it from the current time. Also, while asking WMI questions you might as well ask which user is currently logged on the PC that way you know who to blame. This is exactly what the following script does for your domain. It grabs the list of workstations from the domain then queries WMI for the last time the computer is restarted and does some conversion and math and makes you an nice CSV that you can play with.
Script Configuration
Before running this script there is some minor configuration that must be done so it can communicate with your Active Directory setup.
- Find objConnection.Open “Active Directory Server” change Active Directory Server to the name of your Domain Controller
- Find objCommand.CommandText = _
“Select Name, Location from ‘LDAP://OU=Workstations,DC=west,DC=domain,DC=edu’ ” _
& “Where objectClass=’computer'” change subdomain, domain, and suffix to the name of your domain i.e. west domain edu (respectively) - Find GetUptime objRecordSet.Fields(“Name”).Value, “C:\uptime.csv” and change C:\uptime.csv to the location where you want the file saved. Be sure to save it with the extension CSV
Const ADS_SCOPE_SUBTREE = 2 Set objConnection = CreateObject("ADODB.Connection") Set objCommand = CreateObject("ADODB.Command") objConnection.Provider = "ADsDSOObject" objConnection.Open "Active Directory Server" Set objCOmmand.ActiveConnection = objConnection objCommand.CommandText = _ "Select Name, Location from 'OU=Workstations,DC=west,DC=domain,DC=edu' " _ & "Where objectClass='computer'" objCommand.Properties("Page Size") = 1000 objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE Set objRecordSet = objCommand.Execute objRecordSet.MoveFirst Do Until objRecordSet.EOF GetUptime objRecordSet.Fields("Name").Value, "C:\uptime.csv" objRecordSet.MoveNext Loop Sub GetUptime(strComputer, strFilename) On Error Resume Next Set StdOut = WScript.StdOut Set objFSO = CreateObject("scripting.filesystemobject") Set logStream = objFSO.opentextfile(strFilename, 8, True) Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv") If Err.Number Then logStream.writeline(strComputer & ",Offline") Err.Clear Else Set objWMIService = GetObject _ ("winmgmts:\\" & strComputer & "\root\cimv2") Set colOperatingSystems = objWMIService.ExecQuery _ ("Select * from Win32_OperatingSystem") For Each objOS in colOperatingSystems dtmBootup = objOS.LastBootUpTime dtmLastBootupTime = WMIDateStringToDate(dtmBootup) dtmSystemUptime = DateDiff("h", dtmLastBootUpTime, Now()) Next Set objWMIService = GetObject _ ("winmgmts:\\" & strComputer & "\root\cimv2") Set colComputerSys = objWMIService.ExecQuery _ ("Select UserName from Win32_ComputerSystem") For Each objCS in colComputerSys username = objCS.UserName logStream.writeline(strComputer & ",Online," & dtmSystemUptime & "," & dtmLastBootupTime & "," & username) Next End If logStream.Close End Sub Function WMIDateStringToDate(dtmBootup) WMIDateStringToDate = CDate(Mid(dtmBootup, 5, 2) & "/" & _ Mid(dtmBootup, 7, 2) & "/" & Left(dtmBootup, 4) _ & " " & Mid (dtmBootup, 9, 2) & ":" & _ Mid(dtmBootup, 11, 2) & ":" & Mid(dtmBootup, _ 13, 2)) End Function