usr/etc/Get-Uptime.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function Get-Uptime {
  [CmdletBinding()]param()

  begin {
    New-Delegate ntdll {
      int NtQuerySystemInformation([int, buf, int, buf])
    }

    New-Structure SYSTEM_TIMEOFDAY_INFORMATION {
      Int64  BootTime
      Int64  CurrentTime
      Int64  TimeZoneBias
      UInt32 TimeZondeId
      UInt32 Reserved
      UInt64 BootTimeBias
      UInt64 SleepTimeBias
    }
  }
  process {}
  end {
    $buf = [Byte[]]::new([SYSTEM_TIMEOFDAY_INFORMATION]::GetSize())
    if (($nts = $ntdll.NtQuerySystemInformation.Invoke(3, $buf, $buf.Length, $null)) -ne 0) {
      throw (ConvertTo-ErrMessage -NtStatus $nts)
    }

    $sti = ConvertTo-PointerOrStructure $buf ([SYSTEM_TIMEOFDAY_INFORMATION])
    [TimeSpan]::FromMilliseconds(($sti.CurrentTime - $sti.BootTime) / 10000)
  }
}