Public/OS/Get-TimeInfo.ps1
<#
Copyright © 2024 Integris. For internal company use only. All rights reserved. #> FUNCTION Get-TimeInfo { <# .SYNOPSIS Retrieves and displays detailed time information for the system. .DESCRIPTION This function collects various time-related details, including local time, Windows time, GMT time, time zone information, and NTP server configuration. It also calculates the difference between the system time and the NTP time. .PARAMETER NoTimeZone If specified, skips the retrieval of time zone information. .EXAMPLE Get-TimeInfo This command retrieves and displays detailed time information for the system. .EXAMPLE Get-TimeInfo -NoTimeZone This command retrieves and displays detailed time information for the system, excluding time zone information. .NOTES This function uses various modules and web requests to gather time information and may require appropriate permissions to execute. #> [CmdletBinding()] Param ( [switch]$NoTimeZone = $False ) $NTPTimeInstalled = Test-IntegrisModuleDependency -Name NTPTime # Temp Vars $Results = @() $NTPTime = "" $TimezoneDiff = "" # Results Vars $Hostname = $env:COMPUTERNAME $ApproximateLocation = "" $LocalTime = "" $WindowsTime = "" $WindowsTimeGMT = "" $GMTTime = "" $SecondsDifference = "" $WindowsTimeZone = "" $WindowsUTCOffSet = "" $LocalTimeZone = "" $LocalUTCOffSet = "" $NTPServer = "" $TimeDifference = "" # Get NTP Server Info IF ($True) { TRY { $NTPConfig = & "w32tm" /query /configuration $ServerList = @() IF ($null -eq ($NTPConfig | Select-String "NTPServer:")) { $ServerList = "None" } ELSE { $ServerString = ($NTPConfig | Select-String "NTPServer:") $ServerList = $ServerString.ToString().Replace("NtpServer: ","").Replace(" (Local)","").Split(" ") } $NTPServer = $ServerList } CATCH { $NTPServer = "[Error.Command.w32tm.Unknown]" } } # Get Actual Time IF ($True) { IF ($NTPTimeInstalled -eq $False) { Write-Verbose "Required module NTPTime is missing and could not be installed. Please install module an try again: https://www.powershellgallery.com/packages/NTPTime" $LocalTime = "[Error.Module.NTPTime.NotInstalled]" $GMTTime = "[Error.Module.NTPTime.NotInstalled]" $SecondsDifference = "[Error.Module.NTPTime.NotInstalled]" } TRY { $NTPTime = (Get-NTPTime -MaxOffset 1999999999 -ErrorAction Continue).NTPTime } CATCH { Write-Verbose "NTP request to pool.ntp.org failed. If this error persists, check connectivity and/or security tools." $LocalTime = "[Error.Module.NTPTime.RequestFailed]" $GMTTime = "[Error.Module.NTPTime.RequestFailed]" $SecondsDifference = "[Error.Module.NTPTime.RequestFailed]" } } # Get Geo Location Data IF ($True) { TRY { $GeoData = Invoke-RestMethod -Method Get -Uri "http://ip-api.com/json/$PublicIPv4" } CATCH { TRY { $GeoData = Invoke-RestMethod -Method Get -Uri "http://ip-api.com/json/$PublicIPv4" } CATCH { Write-Verbose "WebRequest failed. Check firewall settings or other web security applications, such as ThreatLocker or OpenDNS. IP-API.com must be whitelisted on port 80." $ApproximateLocation = "[Error.WebRequest.IP-API.com:80.RequestFailed]" } } } # Get TimeZone Data IF ($NoTimeZone -eq $False) { TRY { $TimeZoneID = $GeoData.timezone $TimeZoneEncoded = [uri]::EscapeDataString($TimeZoneID) $TimeZoneData = Invoke-RestMethod -Method Get -Uri "https://timeapi.io/api/timezone/zone?timeZone=$TimeZoneEncoded" $TimeZoneUTCOffset = $TimeZoneData.currentUtcOffset.seconds / 3600 } CATCH { TRY { $TimeZoneID = $GeoData.timezone $TimeZoneEncoded = [uri]::EscapeDataString($TimeZoneID) $TimeZoneData = Invoke-RestMethod -Method Get -Uri "https://timeapi.io/api/timezone/zone?timeZone=$TimeZoneEncoded" $TimeZoneUTCOffset = $TimeZoneData.currentUtcOffset.seconds / 3600 } CATCH { Write-Verbose "WebRequest failed. Check firewall settings or other web security applications, such as ThreatLocker, OpenDNS, or timeapi.io must be whitelisted on port 80."; $LocalTimeZone = "[Error.WebRequest.API.timeapi.io:80.RequestFailed]" $LocalUTCOffSet = "[Error.WebRequest.API.timeapi.io:80.RequestFailed]" } } } # Get Current Windows Time $WindowsTime = Get-Date $TimeDifference = $NTPTime - $WindowsTime IF ($ApproximateLocation -notlike "*Error.*") { $ApproximateLocation = $GeoData.City+", "+$GeoData.RegionName+" "+$GeoData.Zip } IF ($GMTTime -notlike "*Error.*") { $GMTTime = [System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId($NTPTime, 'Greenwich Standard Time') } IF ($SecondsDifference -notlike "*Error.*") { $TimeDifference = $NTPTime - $WindowsTime; $SecondsDifference = [Math]::Round([Math]::Abs($TimeDifference.TotalSeconds),2) } TRY { $WindowsTimeZone = (Get-TimeZone).StandardName } CATCH { $WindowsTimeZone = "[Error.Command.Get-TimeZone.Unknown]" } TRY { [int]$WindowsUTCOffSet = (Get-TimeZone).BaseUtcOffset.ToString().Replace("0","").Replace(":","") $WindowsTimeGMT = [System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId($WindowsTime, 'Greenwich Standard Time') } CATCH { $WindowsUTCOffSet = "[Error.Command.Get-TimeZone.Unknown]" $WindowsTimeGMT = "[Error.Command.Get-TimeZone.Unknown]" } IF ($LocalTimeZone -notlike "*Error.*") { $LocalTimeZone = $TimeZoneID } IF ($LocalUTCOffSet -notlike "*Error.*") { $LocalUTCOffSet = [int]$TimeZoneUTCOffset } IF ($WindowsUTCOffSet -like "*Error.*") {"[Error.Command.Get-TimeZone.Unknown]" } ELSEIF ($LocalTimeZone -like "*Error.*" ) {"[Error.WebRequest.API.Geonames.org:80.RequestFailed]" } ELSE { $TimezoneDiff = $LocalUTCOffSet - $WindowsUTCOffSet } IF ($LocalTime -notlike "*Error.*") { $LocalTime = $NTPTime.AddHours($TimezoneDiff) } ### Get Local Timezone Offset ### This sections checks the timezone information to confirm if the current date should have a DST adjustment $DSTOffset = Get-CimInstance Win32_TimeZone $Date = (Get-Date) $AfterDST = $False $BeforeSST = $False IF (($Date.Month -gt $DSTOffset.DaylightMonth) -or ($Date.Month -eq $DSTOffset.DaylightMonth -and $Date.Day -ge $DSTOffset.DaylightDay)) { $AfterDST = $True } IF (($Date.Month -lt $DSTOffset.StandardMonth) -or ($Date.Month -eq $DSTOffset.StandardMonth -and $Date.Day -ge $StandardDay.DaylightDay)) { $BeforeSST = $True } IF ($AfterDST -and $BeforeSST) { $WindowsTime = $WindowsTime.AddMinutes(-$DSTOffset.DaylightBias) $WindowsUTCOffSet = $WindowsUTCOffSet - ($DSTOffset.DaylightBias / 60) } $Results += New-Object PSObject -WarningAction SilentlyContinue -Property @{ Hostname = $Hostname ApproximateLocation = $ApproximateLocation LocalTime = $LocalTime WindowsTime = $WindowsTime WindowsTimeGMT = $WindowsTimeGMT LocalTimeGMT = $GMTTime SecondsDifference = $SecondsDifference WindowsTimeZone = $WindowsTimeZone WindowsUTCOffSet = $WindowsUTCOffSet LocalTimeZone = $LocalTimeZone LocalUTCOffSet = $LocalUTCOffSet NTPServer = $NTPServer } RETURN $Results | Select-Object Hostname, ApproximateLocation, WindowsTime, LocalTime, WindowsTimeGMT, LocalTimeGMT, SecondsDifference, WindowsTimeZone, WindowsUTCOffSet, LocalTimeZone, LocalUTCOffSet, NTPServer } |