Server Time Check/Compare Script.

This topic contains 3 replies, has 2 voices, and was last updated by  Dave Wyatt 3 years, 8 months ago.

  • Author
    Posts
  • #11826

    John K
    Participant

    Hi,

    I'm working on a short script to check the time on servers and compare it with "master" server. The script will run as part of a daily check/report so I need to have a "friendly" output from the script. Before reading the script below I should make you aware I'm a noob.

    Here's what I was playing with...

    # Create a variable for the server that the time will be checked against (Master).
    $srv_master = invoke-command -computer MASTER_TIME -command {get-date}

    # Create a variable for the servers that will check their time against the Master.
    $srv_check = invoke-command -computer (Get-Content -path c:\servers.txt) -command {get-date}

    # Compare the outputs from the variables above and out put to text file.
    Compare-Object -ReferenceObject $srv_master -DifferenceObject $srv_check | Select-Object -Property InputObject | out-file -filepath C:\time_check.txt

    I would like to include the server names in the output text file, does anyone have suggestions on how to achieve this? I'd also appreciate any suggestions on improving the script, but please bare in mind I'm not an advance user and would like to keep the script understandable for me.

    I'm pretty sure I need to some how pass the computer name across before the compare-object runs. I'm working on this but thought I would ask for suggestion while I work.

    Thanks in advance for and assistance or suggestions.

  • #11828

    Dave Wyatt
    Moderator

    There are a few things to keep in mind here:

    • Get-Date returns a value in the time zone that's configured on the server where the command runs. If you want to compare values against the output of Get-Date from other machines, you should convert them all to Universal time, using one of these two techniques in your Invoke-Command script blocks: (Get-Date).ToUniversalTime() or [DateTime]::UtcNow
    • These Get-Date commands are not all going to execute at exactly the same time, so even if the clocks on these servers are in sync, there's going to be some small differences in your report.
    • Your $srv_master variable is going to contain a single DateTime object, but $srv_check is probably an array (assuming servers.txt contains more than one computer name). Passing them straight to compare-object like that probably doesn't have the desired results. In fact, since you're working with simple DateTime values, I wouldn't recommend using Compare-Object at all; you can just do math on the DateTime values.
    • Invoke-Command automatically adds a PSComputerName property to every object it produces, which makes it easy for you to generate your report.

    Here's an example of how you might revise your code, combining all of these ideas:

    $srv_master = Invoke-Command -ComputerName MASTER_TIME -Command { (Get-Date).ToUniversalTime() }
    
    # Create a variable for the servers that will check their time against the Master.
    $srv_check = invoke-command -ComputerName (Get-Content -Path c:\servers.txt) -Command { (Get-Date).ToUniversalTime() }
     
    # We'll use Select-Object with a couple of constructed properties to display each computer name in srv_check,
    # along with the number of seconds that their time is off from srv_master (rounded to 2 decimal places).
    # You could do this same thing with ForEach-Object and New-Object; it's personal preference which approach you take,
    # as they both can get you objects with identical properties in the end.
    
    $properties = @(
        @{Name = 'ComputerName'; Expression = { $_.PSComputerName } }
        @{Name = 'TimeDifference'; Expression = { '{0:N2} s' -f ($_ - $srv_master).TotalSeconds } }
    )
    
    $srv_check |
    Select-Object -Property $properties |
    Out-File -FilePath C:\time_check.txt
    
    
  • #11831

    John K
    Participant

    That's great Dave thanks.

    I've added "@{name = ' ServerTime ' ; Expression = { $_.TimeOfDay }}" into the $properties variable , but I would like to only show HH:MM:SS (no points of seconds). I believe I will have do something similar to what you've done with the 'Timediffence' expression, but I'm not familiar with the technique used there. Could you tell me the name of the technique or where I might find out more please?

  • #11832

    Dave Wyatt
    Moderator

    The TimeOfDay property is a TimeSpan object, but in this case, there's an easier way. You can use the ToString method on the DateTime object itself, and pass in a format string (see http://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx and http://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx for details on what format strings you can use.) For example:

    $_.ToString('t') # Uses the standard "short time" formatting.  How this looks depends on the regional settings of your local machine.
    $_.ToString('HH:mm:ss') # Displays hours:minutes:seconds in 24-hour format, regardless of regional settings.
    

You must be logged in to reply to this topic.