{"id":1948,"date":"2019-05-16T23:59:22","date_gmt":"2019-05-16T15:59:22","guid":{"rendered":"http:\/\/www.jhouseconsulting.com\/?p=1948"},"modified":"2025-07-30T21:59:33","modified_gmt":"2025-07-30T13:59:33","slug":"best-practice-for-the-windows-time-w32time-service-for-rdsh-and-vdi-workloads","status":"publish","type":"post","link":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/2019\/05\/16\/best-practice-for-the-windows-time-w32time-service-for-rdsh-and-vdi-workloads-1948","title":{"rendered":"Best Practice for the Windows Time (W32TIME) Service for RDSH and VDI workloads"},"content":{"rendered":"\n<p>When using image deployment mechanisms for RDSH and VDI workloads, such as Citrix PVS, Citrix MCS and VMware View Composer, it&#8217;s extremely important to reconfigure the Windows Time (w32time) Service to ensure that the LastBootUpTime is accurate. If it&#8217;s not accurate, it effects monitoring, the correlation of log data, event triggers, etc.<\/p>\n\n\n\n<p>The default Manual trigger of the Windows Time service is based on domain membership, which seems to cause issues as the image boots and changes name to the correct target name. Without having a deep enough understanding on the inner workings of these technologies, I can only assume that the default trigger of the Windows Time service is not compatible with the way the imaging mechanisms work on boot up to change the computer name and join to an Active Directory computer object. There may be a point during startup where Windows detects that it&#8217;s not domain joined and therefore stops the Windows Time service, which seems to throw&nbsp;the time out.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>Here&#8217;s a screen shot from an image I built in Perth, Australia. Notice how the LastBootUpTime is several hours into the future as Perth is GMT +8.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/www.jhouseconsulting.com\/2019\/05\/16\/best-practice-for-the-windows-time-w32time-service-for-rdsh-and-vdi-workloads-1948\/incorrectwindowstimeatboot-australia\" rel=\"attachment wp-att-1950\"><img fetchpriority=\"high\" decoding=\"async\" width=\"719\" height=\"188\" src=\"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-content\/uploads\/2019\/05\/IncorrectWindowsTimeAtBoot-Australia-e1558023781167.png\" alt=\"Incorrect Windows Time At Boot - Australia\" class=\"wp-image-1950\" srcset=\"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-content\/uploads\/2019\/05\/IncorrectWindowsTimeAtBoot-Australia-e1558023781167.png 719w, https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-content\/uploads\/2019\/05\/IncorrectWindowsTimeAtBoot-Australia-e1558023781167-300x78.png 300w\" sizes=\"(max-width: 719px) 100vw, 719px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p>Here&#8217;s a screen shot from an image I built in Saskatoon, Canada. Notice how the LastBootUpTime is several hours into the past as Saskatoon is GMT -6.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/www.jhouseconsulting.com\/2019\/05\/16\/best-practice-for-the-windows-time-w32time-service-for-rdsh-and-vdi-workloads-1948\/incorrectwindowstimeatboot-canada\" rel=\"attachment wp-att-1951\"><img decoding=\"async\" width=\"722\" height=\"184\" src=\"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-content\/uploads\/2019\/05\/IncorrectWindowsTimeAtBoot-Canada-e1558023817157.png\" alt=\"Incorrect Windows Time At Boot - Canada\" class=\"wp-image-1951\" srcset=\"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-content\/uploads\/2019\/05\/IncorrectWindowsTimeAtBoot-Canada-e1558023817157.png 722w, https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-content\/uploads\/2019\/05\/IncorrectWindowsTimeAtBoot-Canada-e1558023817157-300x76.png 300w\" sizes=\"(max-width: 722px) 100vw, 722px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p>So to fix this we simply run a script in the master\/gold image to&#8230;<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Remove the trigger from the Windows Time (w32time) Service<\/li>\n<\/ul>\n\n\n\n<p>sc triggerinfo w32time delete<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Set the Windows Time (w32time) Service to start automatically<\/li>\n<\/ul>\n\n\n\n<p>sc config w32time start= auto<\/p>\n\n\n\n<p>Then the LastBootUpTime is&nbsp;accurate as seen in the following screen shot.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/www.jhouseconsulting.com\/2019\/05\/16\/best-practice-for-the-windows-time-w32time-service-for-rdsh-and-vdi-workloads-1948\/correctwindowstimeatboot\" rel=\"attachment wp-att-1952\"><img decoding=\"async\" width=\"720\" height=\"186\" src=\"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-content\/uploads\/2019\/05\/CorrectWindowsTimeAtBoot-e1558023844364.png\" alt=\"Correct Windows Time At Boot\" class=\"wp-image-1952\" srcset=\"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-content\/uploads\/2019\/05\/CorrectWindowsTimeAtBoot-e1558023844364.png 720w, https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-content\/uploads\/2019\/05\/CorrectWindowsTimeAtBoot-e1558023844364-300x78.png 300w\" sizes=\"(max-width: 720px) 100vw, 720px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p>Microsoft provides some different options <a href=\"https:\/\/support.microsoft.com\/en-au\/help\/2385818\/windows-time-service-doesn-t-start-automatically-on-a-workgroup-comput\" target=\"_blank\" rel=\"noopener\">here<\/a>.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Method 1 is preferred and provides accuracy, which is what I&#8217;ve discussed here.\n<ul class=\"wp-block-list\">\n<li>remove the trigger from the Windows Time (w32time) Service\n<ul class=\"wp-block-list\">\n<li>sc triggerinfo w32time delete<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>set the Windows Time (w32time) Service to start automatically\n<ul class=\"wp-block-list\">\n<li>sc config w32time start= auto<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Method 2 is better than default, but is not as accurate as method 1\n<ul class=\"wp-block-list\">\n<li>Change it to start when the network is ready (has an IP address)\n<ul class=\"wp-block-list\">\n<li>sc triggerinfo w32time start\/networkon stop\/networkoff<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Set the Windows Time (w32time) Service to start manually\n<ul class=\"wp-block-list\">\n<li>sc config w32time start= manual<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li>Method 3 is not a workable solution<\/li>\n<\/ul>\n\n\n\n<p>I&#8217;ve documented this to provide discussion and guidance on how the Windows Time service should be configured for these use cases. From my findings tools such as the <a href=\"https:\/\/support.citrix.com\/article\/CTX224676\" target=\"_blank\" rel=\"noopener\">Citrix Optimizer<\/a> and <a href=\"https:\/\/labs.vmware.com\/flings\/vmware-os-optimization-tool\" target=\"_blank\" rel=\"noopener\">VMware OS Optimization Tool<\/a> do not contain changes to this service.<\/p>\n\n\n\n<p>Here is the <a  data-e-Disable-Page-Transition=\"true\" class=\"download-link\" title=\"\" href=\"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/download\/3425\/?tmstv=1776914800\" rel=\"nofollow\" id=\"download-link-3425\" data-redirect=\"false\" >\n\tConfigureWindowsTimeService.ps1\t(1369 downloads\t)\n<\/a>\n script<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: powershell; auto-links: false; title: ; quick-code: false; notranslate\" title=\"\">\n&lt;#\n  This script will configure the Windows Time (w32time) Service\n\n  We need to reconfigure the Windows Time (w32time) Service to ensure that the\n  LastBootUpTime is accurate, as the default Manual trigger based on domain\n  membership seems to cause issues when using image deployment mechanisms for\n  RDSH and VDI workloads, such as Citrix PVS, Citrix MCS, View Composer, etc.\n  The default trigger stops (or does not start) the Windows Time service when\n  it's not domain joined. Without having a deep enough understanding on the\n  inner workings of these technologies, I assume that the default trigger on\n  the Windows Time service is not compatible with the way the imaging software\n  works on bootup to change the computer name and join to an Active Directory\n  computer object, as there may be a point during startup when it's not domain\n  joined.\n\n  Microsoft documents the issue and different options here:\n  - https:\/\/support.microsoft.com\/en-au\/help\/2385818\/windows-time-service-doesn-t-start-automatically-on-a-workgroup-comput\n  - https:\/\/learn.microsoft.com\/en-au\/troubleshoot\/windows-client\/active-directory\/w32time-not-start-on-workgroup\n\n  As per the Microsoft documentation:\n  - Method 1 is preferred and provides accuracy, which is what this script provides.\n    - remove the trigger from the Windows Time (w32time) Service\n      sc triggerinfo w32time delete\n    - set the Windows Time (w32time) Service to start automatically\n       sc config w32time start= auto\n  - Method 2 is better than default, but is not as accurate as method 1\n    - Change it to start when the network is ready (has an IP address)\n      sc triggerinfo w32time start\/networkon stop\/networkoff\n    - Set the Windows Time (w32time) Service to start manually\n      sc config w32time start= manual\n  - Method 3 is not a workable solution\n\n  To query the existing triggers...\n  - sc qtriggerinfo W32Time\n\n  To add the Domain Join trigger back in and set startup to manual...\n  - sc triggerinfo w32time start\/domainjoin\n  - sc config w32time start= manual\n\n  Script name: ConfigureWindowsTimeService.ps1\n  Release 1.0\n  Written by Jeremy Saunders (jeremy@jhouseconsulting.com) 14th April 2019\n\n#&gt;\n\n#-------------------------------------------------------------\n# Set Powershell Compatibility Mode\nSet-StrictMode -Version 2.0\n\n# Enable verbose, warning and error mode\n$VerbosePreference = 'Continue'\n$WarningPreference = 'Continue'\n$ErrorPreference = 'Continue'\n\n#-------------------------------------------------------------\n\n$Service = &quot;w32time&quot;\n\n# We can use the sc.exe command line utility\n# Possible results using the sc.exe command line tool:\n# &#x5B;SC] ChangeServiceConfig SUCCESS\n# &#x5B;SC] OpenSCManager FAILED 5:  Access is denied.\n# &#x5B;SC] OpenSCManager FAILED 1722:  The RPC server is unavailable.&quot; --&gt; Computer shutdown\n# &#x5B;SC] OpenService FAILED 1060:  The specified service does not exist as an installed service.&quot; --&gt; Service not installed\n\nwrite-verbose &quot;Removing the trigger for the `&quot;$Service`&quot; service...&quot; -verbose\nInvoke-Command {cmd \/c sc.exe triggerinfo $Service delete} | out-null\n\nwrite-verbose &quot;Setting the `&quot;$Service`&quot; service to Automatic...&quot; -verbose\nInvoke-Command {cmd \/c sc.exe config $Service start= auto} | out-null\n\n# Unfortunately we need to force the $ExitCode variable to 0 when using Set-StrictMode\n# in PowerShell scripts used in MDT\/SCCM Task Sequences. It's a known bug.\n$ExitCode = 0\nWrite-Verbose &quot;Completed with an exit code of $ExitCode&quot;\nExit $ExitCode\n<\/pre><\/div>\n\n\n<p>I hope this helps.<\/p>\n\n\n","protected":false},"excerpt":{"rendered":"<p>When using image deployment mechanisms for RDSH and VDI workloads, such as Citrix PVS, Citrix MCS and VMware View Composer, it&#8217;s extremely important to reconfigure the Windows Time (w32time) Service to ensure that the LastBootUpTime is accurate. If it&#8217;s not accurate, it effects monitoring, the correlation of log data, event triggers, etc. The default Manual &#8230; <a title=\"Best Practice for the Windows Time (W32TIME) Service for RDSH and VDI workloads\" class=\"read-more\" href=\"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/2019\/05\/16\/best-practice-for-the-windows-time-w32time-service-for-rdsh-and-vdi-workloads-1948\" aria-label=\"Read more about Best Practice for the Windows Time (W32TIME) Service for RDSH and VDI workloads\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ngg_post_thumbnail":0,"footnotes":""},"categories":[554,14,626,35,5,91,40,38,242],"tags":[551,546,553,552,549,556,555,422,550,301,547,548,417,433],"class_list":["post-1948","post","type-post","status-publish","format-standard","hentry","category-best-practice","category-citrix","category-cvad","category-os-tuning","category-scripting","category-vdi","category-vmware","category-xenapp","category-xendesktop","tag-horizon","tag-lastbootuptime","tag-mcs","tag-pvs","tag-rdsh","tag-sc-config-w32time-start-auto","tag-sc-triggerinfo-w32time-delete","tag-vdi","tag-view","tag-w32time","tag-windows-time","tag-windows-time-service","tag-xenapp","tag-xendesktop"],"aioseo_notices":[],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/posts\/1948","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/comments?post=1948"}],"version-history":[{"count":5,"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/posts\/1948\/revisions"}],"predecessor-version":[{"id":3429,"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/posts\/1948\/revisions\/3429"}],"wp:attachment":[{"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/media?parent=1948"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/categories?post=1948"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jhouseconsulting.com\/jhouseconsulting\/wp-json\/wp\/v2\/tags?post=1948"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}