Get the Time in No Time - Snapshot System Time Config

Windows networks by their nature and design rely on accurate time keeping. Without it, Kerberos authentication would fail, event log entries would be practically meaningless, file backups would be off, and zombies would walk the earth. Ok, maybe not the last one; but maintaining accurate clocks is imperative.

 

There are a number of time related elements to consider. For example, what is the current time zone? Is there an NTP (Network Time Protocol) server specified? Is the Windows Time service running? Some of this information can be found in the registry. Some of it can be retrieved using command line tools and the rest can be identified using WMI (Windows Management Instrumentation).

 

I decided it might be helpful to be able to take a snapshot of a system’s time configuration. This information could be valuable when trouble shooting a potential time-related problem, or pro-actively scanning a collection of computers for possible misconfigurations. As you probably guessed, Windows PowerShell is the perfect tool.

 

I wrote a function called Get-TimeInfo. Here’s what the code looks like:

 


Function Get-TimeInfo {

[cmdletbinding()]

Param(
[Parameter(Position=0,ValueFromPipeline=$True)]
[ValidateNotNullorEmpty()]
[string[]]$Computername=$env:computername)

Process {
Foreach ($computer in $Computername) {
Write-Verbose "Connecting to $computer"
$sb={
$hash=@{
w32tmreg=get-itemproperty HKLM:System\CurrentControlSet\services\W32Time\Parameters
tz=get-wmiobject win32_timezone
cs=get-wmiobject win32_computersystem
os=get-wmiobject win32_operatingsystem
svc=get-wmiobject win32_service -filter "name='w32time'"
}
write $hash
} #sb

if ($computer -eq $env:Computername) {
$data=Invoke-Command -ScriptBlock $sb
}
else {
$data=Invoke-Command -ScriptBlock $sb -ComputerName $computer
}

if ($data) {
New-object -TypeName PSObject -Property @{
Computername=$data.tz.__SERVER
DST=$data.cs.DaylightInEffect
Timezone=$data.tz.caption
Offset=$data.tz.bias
LocalDateTime=([wmi]"").ConvertToDateTime($data.os.LocalDateTime)
NTPServer=$data.w32tmreg.ntpserver
NTPType=$data.w32tmreg.Type
W32Time="{0} ({1})" -f $data.svc.State,$data.svc.Startmode
}
} #if $data
} #foreach

} #process

} #end function

 

The function queries the registry to identity any NTP servers. Because you can only access the Registry Provider locally, the function uses PowerShell remoting to connect to remote computers. This means any computer you want to query must be running at least PowerShell 2.0 with remoting enabled.

 

The function also uses WMI to query a number of classes that have pertinent time related properties. All of the information is wrapped up in a custom object which is written to the pipeline. The object looks like this:

 


Computername : CHI-WIN7-22
Offset : -300
W32Time : Running (Auto)
LocalDateTime : 11/20/2011 2:58:13 PM
DST : False
Timezone : (UTC-05:00) Eastern Time (US & Canada)
NTPType : NTP
NTPServer : chi-dc01.globomantics.local

 

The function works in the pipeline and can be used to gather information from a number of computers in one line command.

 

PS C:\> get-content C:\work\computers.txt | get-timeinfo | Select Computername,NTPServer,W32Time

 

Figure 1 shows the result.

 

 

I can tell at glance if I have any problems or misconfigurations.

 

If you want to learn more about the values, where they come from and why they matter, be sure to take a look at the accompanying article, "Managing Time Settings for Domain Members".

 

How do you handle time-related configurations? Have you ever had a serious time related problem? How did you know and what did you do to resolve it?

About the Author