Uptime workstations in the domain

Good afternoon ladies and gentlemen! I see that your community is really cool in povershelle! Maybe someone will tell what to do ?! I need a script to uptime workstations in the domain. Unfortunately, yet I do not really know povershell. I did the vbs, however, I REAL like to see a working example on povershell

On Error Resume Next
Set objConnection = CreateObject(“ADODB.Connection”)
Set objCommand = CreateObject(“ADODB.Command”)
objConnection.Provider = “ADsDSOObject”
objConnection.Open “Active Directory Provider”
Set objCOmmand.ActiveConnection = objConnection
objCommand.CommandText = “;” & “(” & CONST_AD_BASE_FILTER & “);” & CONST_AD_ATTRs & CONST_AD_SCOPE
objCommand.Properties(“Page Size”) = 1000
objCommand.Properties(“Searchscope”) = 2
Const CONST_AD_BASE=“OU=PC,OU=Orlan,DC=dom,DC=de”
Const CONST_AD_BASE_FILTER="&(objectClass=computer)"
Const CONST_AD_ATTRs=“Name,ADsPath,whenCreated,lastLogon,operatingSystem,description;”
Const CONST_AD_SCOPE=“subtree”
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst
'----
Do Until objRecordSet.EOF
strComputer = objRecordSet.Fields(“Name”).Value
Wscript.Echo "Computer Name: " & objRecordSet.Fields(“Name”).Value

Set objWMIService = GetObject(“winmgmts:” _
& “{impersonationLevel=impersonate}!\” & strComputer & “\root\cimv2”)
Set colOperatingSystems = objWMIService.ExecQuery _
(“Select * from Win32_OperatingSystem”)

For Each objOS in colOperatingSystems
dtmBootup = objOS.LastBootUpTime
dtmLastBootupTime = WMIDateStringToDate(dtmBootup)
dtmSystemUptime = DateDiff(“s”, dtmLastBootUpTime, Now)
WScript.Echo (dtmSystemUptime \ (3600*24)) & “:” & (dtmSystemUptime \ 3600) Mod 24 & “:” & (dtmSystemUptime \ 60) Mod 60 & “:” & dtmSystemUptime Mod 60
Next

objRecordSet.MoveNext

Loop

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

Then I write the batch file and use third-party software to sort the desired value of systeminfo. It works, but for a long time gathering information. I understand that powershell all will be easier and faster. I do not know how to implement. Nobody will tell? uptime of local workstation get easy, but the stations in the domain of a specific OU - a heavy question. Please help me!!!

To my knowledge, it’s not possible to get the uptime from Active Directory.
This because you have to rely on the AD attribute ‘lastLogontimeStamp’, which is not a good indicator for uptime calculation.
To be able to trust on this attribute, you have to gather information from the security event log on each domain controller.

That said, here’s a much more trustable way to do it.
I’ve created a quick and dirty function for you, which you can use to retrieve the uptime per computer.

https://gist.github.com/rdiphoorn/d87c0905380991e0d01c

If you do a search for “Powershell Server Uptime”, there are many example of how get the information you are asking about. Take a look at Use PowerShell to Create an HTML Uptime Report , it has a function Get-UpTime that accepts a string of computers as a parameter. If you wanted to get the computers in an OU, you could use Get-ADComputer (requires RSAT tools with AD Powershell module enabled) and use the -SearchBase to restrict it to a certain OU.

$servers = Get-ADComputer -Filter * -SearchBase "OU=Virtual,OU=Workstations,OU=iAccess,DC=int,DC=iap,DC=dom"  | Select -ExpandProperty Name
Get-UpTime -Servers $servers

To my knowledge, it’s not possible to get the uptime from Active Directory.
This because you have to rely on the AD attribute ‘lastLogontimeStamp’, which is not a good indicator for uptime calculation.
To be able to trust on this attribute, you have to gather information from the security event log on each domain controller.

That said, here’s a much more trustable way to do it.
I’ve created a quick and dirty function for you, which you can use to retrieve the uptime per computer.

#requires -Version 2 -Modules CimCmdlets
function Get-Uptime 
{
    

    [CmdletBinding()]
    Param(
        [Parameter(ValueFromPipeline = $True)][string[]]$ComputerName
    )
    
    #region Initialization Code
    try 
    {
        $computerObjects = Get-CimInstance -ComputerName $ComputerName -ClassName Win32_OperatingSystem -ErrorAction SilentlyContinue
    }
    catch 
    {
        Write-Warning -Message $_.Exception.Message
    }
    #endregion Initialization Code
    
    #region Process Code    
    try 
    {
        foreach ($computerObject in $computerObjects) 
        {
            $upTimeDays = (New-TimeSpan -Start (Get-Date -Date $computerObject.LastBootUpTime.Ticks) -End (Get-Date)).TotalDays
            $upTimeHours = (New-TimeSpan -Start (Get-Date -Date $computerObject.LastBootUpTime.Ticks) -End (Get-Date)).TotalHours
    
            #region Constructing Output Object
            New-Object -TypeName PSCustomObject -Property ([ordered] @{
                    'Computername' = $computerObject.CSName
                    'LastBootTime' = $computerObject.LastBootUpTime
                    'UptimeDays' = [math]::Round($upTimeDays,0)
                    'UptimeHours' = [math]::Round($upTimeHours,1)
            })#endregion Contructing Output Object
        }
    }
    catch 
    {
        Write-Warning -Message $_.Exception.Message
    }
    #endregion Process Code
}

Yes! It real work. Even faster than the vbs!
Thank you very much! Indeed povershell rules!