Constants:
HKEY_CLASSES_ROOT (2147483648 (0x80000000))
HKEY_CURRENT_USER (2147483649 (0x80000001))
HKEY_LOCAL_MACHINE (2147483650 (0x80000002))
HKEY_USERS (2147483651 (0x80000003))
HKEY_CURRENT_CONFIG (2147483653 (0x80000005))

# Get value of Reg Key
$comp = "<SERVER1>"
$hklm = 2147483650
$key = "SYSTEM\CurrentControlSet\Control\Session Manager\Power"
$value = "HiberbootEnabled"
$wmi = [wmiclass]"\\$comp\root\default:stdRegProv"
$result = ($wmi.GetDWORDValue($hklm,$key,$value)).uvalue

# to query multiple systems
$comps = "Server1","Server2"
$hklm = 2147483650
$key = "SYSTEM\CurrentControlSet\Control"
$value = "LastBootShutdown"
$comps| Foreach-Object {$wmi = [wmiclass]"\\$_\root\default:stdRegProv"
($wmi.GetDWORDValue($hklm,$key,$value)).uvalue }


Function Get-Uptime { 

<# 
.SYNOPSIS 
Get-Uptime retrieves boot up information from a Computer. 
.DESCRIPTION 
 Get-Uptime uses WMI to retrieve the Win32_OperatingSystem 
 LastBootuptime property. It displays the start up time 
 as well as the uptime. 
 For Windows 8 and newer Desktop Operating Systems, it also compares
 property value with most recent Event Log *low power* entry.
 
.PARAMETER ComputerName 
 The Computer name to query. Default: Localhost.

.NOTES
 Original script created By: Jason Wasser
 Modified: March 2019
 Version 1.0 
 
 Changelog: 
 * Modified for the purposes of PowerShell challenge 

.LINK
 Get-Uptime original PowerShell Script
 <a href="https://gallery.technet.microsoft.com/scriptcenter/Get-Uptime-PowerShell-eb98896f">https://gallery.technet.microsoft.com/scriptcenter/Get-Uptime-PowerShell-eb98896f</a>
 
.EXAMPLE 
Get-Uptime -ComputerName SERVER-R2 
Gets the uptime from SERVER-R2 
.EXAMPLE 
Get-Uptime -ComputerName (Get-Content C:\Temp\Computerlist.txt) 
Gets the uptime from a list of computers in c:\Temp\Computerlist.txt. 
.EXAMPLE 
Get-Uptime -ComputerName SERVER04 -Credential domain\serveradmin 
Gets the uptime from SERVER04 using alternate credentials. 
#> 

 [CmdletBinding()] 
 param ( 
 [Parameter(Mandatory=$false, 
 Position=0, 
 ValueFromPipeline=$true, 
 ValueFromPipelineByPropertyName=$true)] 
 [Alias("Name")] 
 [string[]]$ComputerName=$env:COMPUTERNAME, 
 $Credential = [System.Management.Automation.PSCredential]::Empty, 
 
 [Parameter(Mandatory=$false,Position=0)] 
 [Alias("Log")] 
 [string]$LogPath="c:\logs\logfile.txt"
 )
 
 begin{
 $out = "*** Get-Uptime processing started " + (Get-Date) + " ***"
 Write-Output $out | Out-File -FilePath $LogPath -Append
 } 
 
 
 process { 
 foreach ($Computer in $ComputerName) { 
 try { 
 
 #Need to verify that the hostname is valid in DNS 
 $hostdns = [System.Net.DNS]::GetHostEntry($Computer) 
 
 # get OS Details from WMI 
 $OS = Get-WmiObject win32_operatingsystem -ComputerName $Computer -ErrorAction Stop -Credential $Credential 
 
 # If right conditions are met, just get LastBootTime boolean
 $objHibEntry = $false

 # Check if Computer IS Desktop OS Windows 8 and above
 If ([int]$OS.ProductType -eq 1 -and [int]([System.Version]$OS.Version).Major+[int]([System.Version]$OS.Version).Minor -gt 7)
 #If ([int]$OS.ProductType -eq 1 -and [int]([System.Version]$OS.Version).Major+[int]([System.Version]$OS.Version).Minor -ge 8)
 # ^ this option works too^
 
 {
 # Check Windows Registry to see if HiberbootEnabled is Enabled
 $hklm = 2147483650
 $key = "SYSTEM\CurrentControlSet\Control\Session Manager\Power"
 $value = "HiberbootEnabled"
 $wmi = [wmiclass]"\\$Computer\root\default:stdRegProv"
 
 If (($wmi.GetDWORDValue($hklm,$key,$value)).uvalue -eq 1)
 { 
 # Get most recent *low power* event log entry
 
 $logentry = (Get-WMIobject win32_ntlogevent -ComputerName $ComputerName -filter "(logfile='system') AND (EventCode='1') AND (Message LIKE 'The system has returned from a low power state%')")[0]
 $logtime = $logentry.ConvertToDateTime($logentry.TimeGenerated)
 

 # compare Last Boot Time with most recent *low power* log entry
 if ($OS.ConvertToDateTime($OS.LastBootUpTime) -lt $logtime)
 {
 $BootTime = $logtime
 $Uptime = $OS.ConvertToDateTime($OS.LocalDateTime) - $boottime 
 $propHash = [ordered]@{ 
 ComputerName = $Computer 
 BootTime = $BootTime 
 Uptime = [math]::round($Uptime.TotalDays,3)
 OperatingSystem = $OS.Caption + " " + $OS.OSArchitecture
 } 
 $objComputerUptime = New-Object PSOBject -Property $propHash
 $objComputerUptime 
 $objHibEntry = $true # we've added the object
 } # end log entry if
 
 else { $objHibEntry = $false } # object needs to be created
 
 } # end HiberBootEnabled if
 
 } # end Windows Server or Windows 7 if

 
 # Fast Startup is OFF - Windows 8 and above or Windows Server or Windows 7, get Last Boot Time
 if ($objHibEntry -eq $false)
 {
 $BootTime = $OS.ConvertToDateTime($OS.LastBootUpTime) 
 $Uptime = $OS.ConvertToDateTime($OS.LocalDateTime) - $boottime 
 $propHash = [ordered]@{ 
 ComputerName = $Computer 
 BootTime = $BootTime 
 Uptime = [math]::round($Uptime.TotalDays,3)
 OperatingSystem = $OS.Caption + " " + $OS.OSArchitecture
 } 

 $objComputerUptime = New-Object PSOBject -Property $propHash
 $objComputerUptime
 } # end get Last Boot Time if

 
 } #end try
 
 catch [Exception] { 
 Write-Output "$computer $($_.Exception.Message)" | Out-File -FilePath $logpath -Append
 #return
 } 
 } #end foreach
 } #end process
 
 end
 {
 $out = "*** Get-Uptime processing completed " + (Get-Date) + " ***"
 Write-Output $out | Out-File -FilePath $logpath -Append
 } 

} #end function



.