Perl Toolkit: Check ESX(i) host time

I had an issue recently where a single ESXi host’s clock was incorrect. The administrator had never set the clock initially, so NTP never kept it in sync cause it was too far off to begin.

Since I’ve got a large number of hosts and the idea of clicking to each one through VI Client and checking the configuration tab, I immediately turned to PowerCLI. Naturally, one of Luc‘s scripts was the top search result.

That solved my immediate need to check the hosts, but I also wanted to setup some general monitoring. Since my monitoring infrastructure is compromised, primarily, of a linux Nagios host, that means PowerCLI couldn’t help. So, I did the next best thing and ported Luc’s script to perl.

Below is the result of that porting. It can also be run from vMA for reporting via email or another mechanism.

5 thoughts on “Perl Toolkit: Check ESX(i) host time”

  1. nice script. A little patch though (probably caused by twordpress messing with your code). In the for loop of the esx hosts when parsing the hosttime variable to pieces the regex misses the ‘\’ before the ‘d{x}’ matches, so it must be ‘\d{x}’ instead.

    • Oxtan,

      Thank you for catching that! You were absolutely correct, WordPress did not like the backslash. Should be all fixed up now.

      Thanks again.

      Andrew

  2. I found another edge case. If the esx host clock is off on the early side (so the esx host clock is 17:00 whereas the actual clock is 17:03, for instance) then ( $hostepoch – $localtime) will always be lower than $allowedDrift because ( $hostepoch – $localtime) is a negative integer.

    In that case you need to add an extra elsif block like this:

    elsif ( ( $localtime – $hostepoch ) > $allowedDrift ) {
    print $host->get_property(‘summary.config.name’) . ” is ” . ($hostepoch – $localtime) . ” seconds off! n”;
    }

    For my nagios check I added two extra variables:
    # save here info for esx hosts whose clocks are not synchronized
    my %drift_ok;
    my %drift_warn;

    and in the check for drift if loop and end of script is like this:

    # check for drift, output something
    if ( ( $hostepoch – $localtime ) > $allowedDrift ) {
    $drift_warn{$hostname} = $drifted_time;
    }
    elsif ( ( $localtime – $hostepoch ) > $allowedDrift ) {
    $drift_warn{$hostname} = $drifted_time;
    }
    else {
    $drift_ok{$hostname} = $drifted_time;
    }

    }

    # this will be > 0 if more than 0 hosts have a bigger drift than allowed
    my $warning = scalar ( keys %drift_warn );

    if ( $warning > 0 ) {
    while ( my ( $hostname, $drift ) = each %drift_warn ) {
    print
    “$hostname has drifted by $drift seconds relative to the ntp server\n”;

    }
    exit 1;
    }
    else {
    print “OK: all connected esx servers are properly in sync with our ntp server\n”;
    exit 0;
    }

    Thanks for your work, it saved me some leg work 🙂

  3. and right after posting all this I remember about the abs builtin Perl funtion 🙂

    So much simpler:

    if ( abs ( $hostepoch – $localtime ) > $allowedDrift ) {
    $drift_warn{$hostname} = $drifted_time;
    }

    no elsif block, the rest remains the same. I should post my script to github …

    • Thank you again for catching my errors! I’ve modified to use the absolute value of the subtraction operation in the comparison.

      Andrew

Leave a Reply