PowerCLI script to report and change host NTP settings

The script I would like to share today is in a way supplementary to what I wrote about in my previous post.

For those who don’t know it yet – last week I gave an example of completely turning off VMware Tools guest time synchronization via script that is able to set any of virtual machine “advanced settings”.

Now I would like to look at subject of timekeeping from vSphere host perspective, I think we all agree that you should have your time synchronized and correct among all components of virtual infrastructure – regardless if you synchronize Guest OS time with host or not.
It’s not only about “feeling nice”, as being out of sync can be a reason for many at least annoying issues – like the one described in this KB. Other issues include but are not limited to problems with snapshots (so backups!), vmotions and so on and so forth…

Of course the best practice to implement NTP on vSphere hosts is to do it via host profiles and monitoring whether the time is not drifting away should be done with vCOPs or whatever monitoring tool you are using, but putting host in maintenance mode and applying the whole profile might be too much of work if you just need to point your hosts to new time sources.
Or maybe you are consulting for some smaller customer that does not have fully matured monitoring framework in place and you just need to have a quick report of timekeeping settings in such environment.

This is where the following script comes handy.

The script can be used in two “modes” – if you provide only mandatory parameters (vCenter Server and cluster name) it will query all hosts available in the selected cluster and provide a report on NTP settings.
The report will be saved in .csv file that could look like this.

Most fields in the report are self-explanatory I think, I decided to fix the number of reported NTP servers to 5, because I wanted to avoid difficulties of exporting variable length strings to .csv that I had to deal with some time ago. Most of the time I see only two NTP servers configured – which is perfectly fine, the highest number I ever saw was 4 (and that’s an overkill IMHO), so reporting 5 time sources should  be more than enough.

“NTPDPolicy” field might require some explanation, three values of “automatic”, “on” or “off” are possible for this field and they are corresponding to settings that you can see in GUI.


So “automatic” = “Start automatically if any ports are open and stop when all ports are closed”,
“on” = “Start and stop with host”
and “off” = “Start and stop manually”.

In my opinion best policy for ntp daemon is “on”, just because we always want our time synced properly. This policy also makes things easier since configuring it instructs our host to automatically update its security profile and open appropriate ports on ESXi firewall.
It is actually the other way round if we set service policy to “automatic” – service starts only when we open the ports manually, this policy might be useful for services that we use temporarily, like, say sshd, if we need to open ssh session to ESXi host we just open ports on firewall via vSphere Client and the service starts automatically (we don’t need to remember to start it), but honestly it does not make much sense with ntpd.
“Off” policy effectively disables ntpd.

You can see also “timedrift” reported for each host, this value is difference (in seconds) between current time on the host and the system you invoked the script from. I’d like to stress out that because of the way this comparison is implemented, you got to be sure time on your workstation or server where you run this script is correct – personally I was always invoking this script from vCenter Server for given infrastructure.

In line 98 of the script I defined a constant ($maxtimedrift) value of what is “acceptable” time skew for hosts. I configured it to 1 second (so maximum difference between any given pair of hosts should not be bigger than 2 seconds), but properly working ntpd is able to keep this difference within milliseconds, so feel free to adjust this value to your needs (the script will throw red lines with exclamation marks at you if it detects larger time drift during execution).

As you can see in the report one of the vsphere hosts I checked, namely esxhost01.seba.local, has some problems with being on time, ntpd is turned off there and measured time skew is more than 10 thousands seconds (or precisely 3 hours).
We definitely need to fix that and this is where 2nd “mode” of my script comes to the rescue. By simply providing the script optional -NTPDSources parameter you instruct it to change ntpd settings.

You can provide just one NTP server like this:

vmhosttimekeeping.ps1 vCenterServer vcenter.seba.local ClusterName ProductionCluster NTPSources time01.seba.local

But if you want to provide multiple time sources separate them with commas and enclose the whole list in quotation marks like that:

vmhosttimekeeping.ps1 vCenterServer vcenter.seba.local ClusterName ProductionCluster NTPSources “time01.seba.local,time02.seba.local,”

and make sure you don’t put any spaces in this string, cause test-connection cmdlet (that I use later on to “sanitize” input) will fail if you provide it with servername that starts with blank character (sic!).

The script will give you a warning and one last chance to abort (just in case you had it invoked by mistake) but if you confirm the execution, it will first try to ping each NTP server you provided (and remove not responding ones – this is my crude way of eliminating typos from input, so be sure your time sources pong for pings from the system you are running this script or disable this check 😉 ).
Once the list of NTP servers is confirmed the script will first stop ntpd service then clear the currently configured time sources for each host in selected cluster.

Please note this is not “modifying” or “adjusting” NTP configuration, it is “wipe out everything and start from scratch” approach.

Subsequently NTP servers are added, ntpd service policy is configured for “on” and script configures time on host to match time of the system it is invoked from.
I do that because in case of big time differences (like 3 hours in our example) ntpd will not adjust time of host without a reboot, please be careful with this, since (as I explained before) the script assumes as correct the current time of system it is running on.
Make sure this assumption is valid and run this script (in “setup mode” at least) from your vCenter Server if possible (you’ve got your time correct of vCenter, right?, if not at least you don’t end-up with time difference between vCenter and hosts).

As a final step ntpd service is started with start-vmhostservice cmdlet.

I like to be informed if a script is actually doing something (don’t like scripts that can’t communicate anything but blinking cursor and you need to wonder whether it hangs or what) so I made this script rather chatty.
It throws at least one line for each host that has been added to report or changed and what I like most, there is a progress bar displayed with write-progress cmdlet at the top of PowerCLI window.

I hope you will find this script useful, as always – feel free to share and provide your feedback

Sebastian Baryło

Successfully jumping to conclusions since 2001.

  • Garrett

    Nice script Sebastian. Another option that everyone can utilize is VMware’s Host profiles – which I use for my auto-deployed ESXi hosts.

  • sbarylo

    Thanks for positive feedback Garret, that’s exactly use case for this script – when you need to correct NTP settings, but can not afford rolling maintenance mode through your cluster(s)

  • Pingback: Newsletter: August 10, 2014 | Notes from MWhite()

  • Pingback: VMware Power CLI | virtualforce()

  • FR

    Nice Script!!!

    It would be nice if it had the option of addressing all hosts globally instead of just inside one cluster.. and if it output some error when checking for legitimate time sources.