{"id":49893,"date":"2010-05-09T00:01:00","date_gmt":"2010-05-09T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2010\/05\/09\/hey-scripting-guy-weekend-scripter-configuring-w32time-service-logging\/"},"modified":"2010-05-09T00:01:00","modified_gmt":"2010-05-09T00:01:00","slug":"hey-scripting-guy-weekend-scripter-configuring-w32time-service-logging","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-weekend-scripter-configuring-w32time-service-logging\/","title":{"rendered":"Hey, Scripting Guy! Weekend Scripter: Configuring W32Time Service Logging"},"content":{"rendered":"<p><a class=\"addthis_button\" href=\"http:\/\/www.addthis.com\/bookmark.php?v=250&amp;pub=scriptingguys\"><img decoding=\"async\" alt=\"Bookmark and Share\" src=\"http:\/\/s7.addthis.com\/static\/btn\/v2\/lg-share-en.gif\" width=\"125\" height=\"16\"><\/a><\/p>\n<p>&nbsp;<\/p>\n<p class=\"MsoNormal\">Microsoft Scripting Guy Ed Wilson here, <a href=\"http:\/\/blogs.technet.com\/heyscriptingguy\/archive\/2010\/05\/08\/hey-scripting-guy-weekend-scripter-configuring-a-timeserver-in-windows-server.aspx\">yesterday<\/a> I wrote a script that configured my domain controller with an external time source. After doing that, I thought it would be a good idea to have the ability to enable and disable diagnostic logging for the <b>W32Time<\/b> service. I ran across a pretty good knowledge base article, <a href=\"http:\/\/support.microsoft.com\/kb\/816043\"><font face=\"Segoe\">KB 816043<\/font><\/a>, that explained the different registry keys that needed to be modified, and I decided to get to work on the script. (I later found the <a href=\"http:\/\/blogs.msdn.com\/w32time\/archive\/2008\/02\/28\/configuring-the-time-service-enabling-the-debug-log.aspx\"><font face=\"Segoe\">Time Service team blog on MSDN<\/font><\/a> that talks about a different way to do this). The result is the ConfigureW32TimeLogging.ps1 script seen here. <\/p>\n<p class=\"CodeBlockScreenedHead\"><strong>ConfigureW32TimeLogging.ps1<\/strong><\/p>\n<p class=\"CodeBlockScreened\"><font><font face=\"Lucida Sans Typewriter\">Param(<br \/><span>&nbsp; <\/span>$computer = &#8220;Hyperv&#8221;, <br \/><span>&nbsp; <\/span>$user = &#8220;nwtraders\\administrator&#8221;,<br \/><span>&nbsp; <\/span>[switch]$enable,<br \/><span>&nbsp; <\/span>[switch]$disable<br \/>)<\/p>\n<p>Function Start-W32TimeLogging($PSSession)<br \/>{<br \/><span>&nbsp;<\/span>Invoke-Command -Session $PSSession -ScriptBlock { <br \/><span>&nbsp;<\/span>$timeRoot = &#8220;HKLM:\\SYSTEM\\CurrentControlSet\\services\\W32Time\\Config&#8221;<br \/><span>&nbsp;<\/span>$invalidChars = [io.path]::GetInvalidFileNamechars() <br \/><span>&nbsp;<\/span>$date = Get-Date -format s<br \/><span>&nbsp;<\/span>$file = &#8220;w32time-&#8221; + ($date.ToString() -replace &#8220;[$invalidChars]&#8221;,&#8221;-&#8220;) + &#8220;.log&#8221;<br \/><span>&nbsp;<\/span>$logPath = Join-Path -Path c:\\fso -ChildPath $file<br \/><span>&nbsp;<\/span>Set-ItemProperty -path &#8220;$timeroot&#8221; -name FileLogSize -Value 10000000<br \/><span>&nbsp;<\/span>Set-ItemProperty -path &#8220;$timeroot&#8221; -name FileLogName -Value $logPath<br \/><span>&nbsp;<\/span>Set-ItemProperty -path &#8220;$timeroot&#8221; -name FileLogEntries -Value 0-116<br \/><span>&nbsp; <\/span><br \/><span>&nbsp;<\/span>Register-WmiEvent -Query `<br \/><span>&nbsp; <\/span>&#8220;select * from __InstanceModificationEvent within 5 where targetinstance isa &#8216;win32_service'&#8221; `<br \/><span>&nbsp; <\/span>-SourceIdentifier stopped<\/p>\n<p><span>&nbsp;<\/span>Stop-Service -Name w32Time<br \/><span>&nbsp;<\/span>Wait-Event -SourceIdentifier stopped<br \/><span>&nbsp;<\/span>Start-Service -Name w32Time<br \/><span>&nbsp;<\/span><br \/><span>&nbsp;<\/span>Unregister-Event -SourceIdentifier stopped<br \/><span>&nbsp;<\/span>Remove-Event -SourceIdentifier stopped<br \/><span>&nbsp;<\/span>} # end invoke-command<br \/><span>&nbsp;<\/span>Remove-PSSession -Session $psSession<br \/>} #end Start-W32TimeLogging<\/p>\n<p>Function Stop-W32TimeLogging($pssession)<br \/>{<br \/><span>&nbsp;<\/span>Invoke-Command -Session $PSSession -ScriptBlock { <br \/><span>&nbsp;<\/span>$timeRoot = &#8220;HKLM:\\SYSTEM\\CurrentControlSet\\services\\W32Time\\Config&#8221;<br \/><span>&nbsp;<\/span>Remove-ItemProperty -path &#8220;$timeroot&#8221; -name FileLogSize <br \/><span>&nbsp;<\/span>Remove-ItemProperty -path &#8220;$timeroot&#8221; -name FileLogName <br \/><span>&nbsp;<\/span>Remove-ItemProperty -path &#8220;$timeroot&#8221; -name FileLogEntries <br \/><span>&nbsp; <\/span><br \/><span>&nbsp;<\/span>Register-WmiEvent -Query `<br \/><span>&nbsp; <\/span>&#8220;select * from __InstanceModificationEvent within 5 where targetinstance isa &#8216;win32_service'&#8221; `<br \/><span>&nbsp; <\/span>-SourceIdentifier stopped<\/p>\n<p><span>&nbsp;<\/span>Stop-Service -Name w32Time<br \/><span>&nbsp;<\/span>Wait-Event -SourceIdentifier stopped<br \/><span>&nbsp;<\/span>Start-Service -Name w32Time<br \/><span>&nbsp;<\/span><br \/><span>&nbsp;<\/span>Unregister-Event -SourceIdentifier stopped<br \/><span>&nbsp;<\/span>Remove-Event -SourceIdentifier stopped<br \/><span>&nbsp;<\/span>} # end invoke-command<br \/><span>&nbsp;<\/span>Remove-PSSession -Session $psSession<br \/>} #end Stop-W32TimeLogging<\/p>\n<p># *** Entry Point to script ***<\/p>\n<p>$psSession = New-PSSession -ComputerName $computer -Credential $user <\/p>\n<p>if($enable) { start-w32TimeLogging -pssession $pssession ; exit }<br \/>if($disable) { stop-w32TimeLogging -pssession $pssession ; exit }<\/font><\/font><\/p>\n<p class=\"MsoNormal\">To enable diagnostic logging for the <b>W32Time<\/b> service, the three registry keys that are shown in the following image are added to the <b>w32Time<\/b> configuration hive. To disable diagnostic logging, the same three registry keys are removed. Of course, both of these operations require the <b>w32Time<\/b> service to reload the configuration information from the registry. To do this, I stop and start the <b>w32Time<\/b> service.<span>&nbsp; <\/span><\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" title=\"Image of the three registry keys\" alt=\"Image of the three registry keys\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/WES-5-9-10-01.jpg\" width=\"600\" height=\"326\"><a href=\"http:\/\/blogs.technet.com\/photos\/heyscriptingguy\/images\/3329612\/original.aspx\"><font face=\"Segoe\"><\/font><\/a><\/p>\n<p class=\"MsoNormal\">The script is extremely similar to the one I wrote yesterday. They both use Windows PowerShell remoting, they both use the <b>Set-Itemproperty<\/b> cmdlet to create registry keys, and they both use WMI eventing to indicate when the <b>w32Time<\/b> service has stopped. <\/p>\n<p class=\"MsoNormal\">Despite the similarities, there are some differences between the two scripts. One of the things I do is create a custom name for the w32Time.log file. I do this because I might want to run it at different times of the day on the same day, and I did not want to fool with renaming or deleting pre-existing log files. This will also automatically allow me to keep as many logs as I wish. Here is the code:<\/p>\n<p class=\"CodeBlockScreened\"><font><font face=\"Lucida Sans Typewriter\">$invalidChars = [io.path]::GetInvalidFileNamechars() <br \/>$date = Get-Date -format s<br \/>$file = &#8220;w32time-&#8221; + ($date.ToString() -replace &#8220;[$invalidChars]&#8221;,&#8221;-&#8220;) + &#8220;.log&#8221;<br \/>$logPath = Join-Path -Path c:\\fso -ChildPath $file<\/font><\/font><\/p>\n<p class=\"MsoNormal\">Because I am using the timestamp that gets converted to a string as part of the file name, I need to do a little bit of work. This is because all of the characters that are used in a timestamp are not allowed to be used in a filename. Using the <b>GetInvalidFileNameChars<\/b> static method from the <b>system.io.path<\/b> .NET Framework class, I can easily find out which characters are disallowed. I use this character set, and feed it to the <b>replace<\/b> operator to change all invalid characters to a dash. Finally the <b>Join-Path<\/b> cmdlet is used to build the path to the new log file. <\/p>\n<p class=\"MsoNormal\">The log itself is Unicode, so when you attempt to read it, you will need to specify the encoding parameter. Using the <b>Select-String<\/b> cmdlet, I can read the file and look for a particular string at the same time. The command I used is seen here (I shortened the path to fit it on a single line for clarity):<\/p>\n<p class=\"CodeBlockScreened\"><font><font face=\"Lucida Sans Typewriter\">Select-String -Path c:\\time.log -Pattern &#8220;ntpclient&#8221; -Encoding unicode \u2013AllMatches<\/font><\/font><\/p>\n<p class=\"MsoNormal\">When I run the command, I am greeted with the output seen in the following image.<\/p>\n<p class=\"Fig-Graphic\"><a href=\"http:\/\/blogs.technet.com\/photos\/heyscriptingguy\/images\/3329613\/original.aspx\"><font face=\"Segoe\"><\/font><\/a><img decoding=\"async\" title=\"Image of output from the command\" alt=\"Image of output from the command\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/WES-5-9-10-02.jpg\" width=\"600\" height=\"327\"><\/p>\n<p class=\"MsoNormal\">&nbsp;<\/p>\n<p class=\"MsoNormal\">If you want to know exactly what we will be looking at tomorrow, follow us on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> or <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\">Facebook<\/a>. If you have any questions, send e-mail to us at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\"><font face=\"Segoe\">scripter@microsoft.com<\/font><\/a> or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\"><font face=\"Segoe\">Official Scripting Guys Forum<\/font><\/a>. See you tomorrow. Until then, peace.<\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p><b><span>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/span><\/b><\/p>\n<p><b><span><\/span><\/b><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; Microsoft Scripting Guy Ed Wilson here, yesterday I wrote a script that configured my domain controller with an external time source. After doing that, I thought it would be a good idea to have the ability to enable and disable diagnostic logging for the W32Time service. I ran across a pretty good knowledge base [&hellip;]<\/p>\n","protected":false},"author":595,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[86,51,31,26,57,3,130,61,45],"class_list":["post-49893","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-basic-information","tag-getting-started","tag-operating-system","tag-registry","tag-remoting","tag-scripting-guy","tag-servers","tag-weekend-scripter","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>&nbsp; Microsoft Scripting Guy Ed Wilson here, yesterday I wrote a script that configured my domain controller with an external time source. After doing that, I thought it would be a good idea to have the ability to enable and disable diagnostic logging for the W32Time service. I ran across a pretty good knowledge base [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/49893","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/595"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=49893"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/49893\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=49893"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=49893"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=49893"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}