{"id":52083,"date":"2009-11-05T00:01:00","date_gmt":"2009-11-05T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2009\/11\/05\/hey-scripting-guy-can-i-start-an-event-based-on-when-a-registry-value-is-changed\/"},"modified":"2009-11-05T00:01:00","modified_gmt":"2009-11-05T00:01:00","slug":"hey-scripting-guy-can-i-start-an-event-based-on-when-a-registry-value-is-changed","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-can-i-start-an-event-based-on-when-a-registry-value-is-changed\/","title":{"rendered":"Hey, Scripting Guy! Can I Start an Event Based on When a Registry Value Is Changed?"},"content":{"rendered":"<p><!-- AddThis Button BEGIN --><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><!-- AddThis Button END --><\/p>\n<p class=\"MsoNormal\">&nbsp;<\/p>\n<p><img decoding=\"async\" title=\"Hey, Scripting Guy! Question\" border=\"0\" alt=\"Hey, Scripting Guy! Question\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" height=\"34\"><\/p>\n<p class=\"MsoNormal\">Hey, Scripting Guy! I need to be notified when a particular registry key value gets changed. The registry value is in the HKEY_LOCAL_MACHINE hive. What I am trying to accomplish is this: I am using a script to install software. After the first piece of software is successfully installed, I want to install a subsequent piece of software. And after this is done, I will reboot the computer. I have tested this technique in our lab, and I am able to postpone the reboot. I have tried pausing the execution of the install script by using the <b>Start-Sleep<\/b> cmdlet, and this works okay. The problem is that on fast computers the pause is too long, and on slow computers the pause is not long enough. It seems that I cannot figure out a really good way to do this. <\/p>\n<p class=\"MsoNormal\">I am thinking that if I cannot figure this out, I will need to just record the computers on which the install fails, and manually visit each machine; however, several of the computers are at remote locations and this is not a really practical solution. The idea for the registry key is that each software package creates its own registry key, and if I can detect when this occurs, I can then start the next install. Can you help me?<\/p>\n<p class=\"MsoNormal\">&#8212; LK<\/p>\n<p class=\"MsoNormal\"><img decoding=\"async\" title=\"Hey, Scripting Guy! Answer\" border=\"0\" alt=\"Hey, Scripting Guy! Answer\" align=\"left\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" height=\"34\">Hello LK, <\/p>\n<p class=\"MsoNormal\">Microsoft Scripting Guy Ed Wilson here. I am listening to the <a href=\"http:\/\/bit.ly\/Ur3aF\"><font face=\"Segoe\">The Kingston Trio<\/font><\/a> on my Zune as I check the <a href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\"><font face=\"Segoe\">scripter@microsoft.com<\/font><\/a> e-mail inbox. I am sipping a cup of <a href=\"http:\/\/en.wikipedia.org\/wiki\/Constant_Comment\"><font face=\"Segoe\">Constant Comment tea<\/font><\/a> and munching on an <a href=\"http:\/\/bit.ly\/oe0WL\"><font face=\"Segoe\">ANZAC biscuit<\/font><\/a>. The weather outside is frightful, but inside my office it is delightful. And since I&rsquo;ve no place to go, let it snow!<\/p>\n<p class=\"MsoNormal\">By the way, Craig and I have been having several discussions about the 2010 Scripting Games. One thing we can tell you, they will not be held in the summer. They will be earlier! I have been busy working on events. If you have any ideas for the 2010 Scripting Games, e-mail us at <a href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\"><font face=\"Segoe\">scripter@microsoft.com<\/font><\/a>. What should you say? Just about anything. We are interested in ideas for events, ideas to make the Games go better, ideas to increase participation&mdash;just about anything. <\/p>\n<p class=\"MsoNormal\">LK, I wrote the MonitorRegistryKeyValueChangeEvent.ps1 for you. The MonitorRegistryKeyValueChangeEvent.ps1 script watches a registry key value, and when that value changes, it fires an event. To use the script, you must have Windows PowerShell 2.0 installed. You will need to modify the <b>$keyPath<\/b> variable and the <b>$valueName<\/b> variable to use it. The complete MonitorRegistryKeyValueChangeEvent.ps1 script is seen here. <\/p>\n<p class=\"CodeBlockScreenedHead\"><strong>MonitorRegistryKeyValueChangeEvent.ps1<\/strong><\/p>\n<p class=\"CodeBlockScreened\"><span><font face=\"Lucida Sans Typewriter\">#Requires &ndash;version 2.0<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"CodeBlockScreened\"><span><font face=\"Lucida Sans Typewriter\">$hive = &#8220;HKEY_LOCAL_MACHINE&#8221;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"CodeBlockScreened\"><span><font face=\"Lucida Sans Typewriter\">$keyPath = &#8220;Software\\Microsoft\\WBEM\\Scripting&#8221;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"CodeBlockScreened\"><span><font face=\"Lucida Sans Typewriter\">$valueName = &#8220;Default NameSpace&#8221;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"CodeBlockScreened\"><span><font face=\"Lucida Sans Typewriter\">$gciPath = $keyPath -replace &#8220;\\&#8221;,&#8221;&#8221;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"CodeBlockScreened\"><span><font face=\"Lucida Sans Typewriter\">$query = &#8220;Select * from RegistryValueChangeEvent where Hive=&#8217;$hive&#8217; AND &#8221; +<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"CodeBlockScreened\"><span><font face=\"Lucida Sans Typewriter\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8220;KeyPath=&#8217;$keyPath&#8217; AND ValueName=&#8217;$ValueName'&#8221;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"CodeBlockScreened\"><span><font face=\"Lucida Sans Typewriter\">Register-WmiEvent -Query $query -SourceIdentifier KeyChanged<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"CodeBlockScreened\"><span><font face=\"Lucida Sans Typewriter\">Wait-Event -SourceIdentifier KeyChanged<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"CodeBlockScreened\"><span><font face=\"Lucida Sans Typewriter\">&#8220;New value for $valueName is &#8221; + (Get-ItemProperty -Path HKLM:$gciPath).$valueName<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">The MonitorRegistryKeyValueChangeEvent.ps1 actually begins with a comment that states the script requires version 2.0. This is not really a comment; it is a directive to Windows PowerShell that will prevent script execution on a Windows PowerShell 1.0 computer. Of course the script will not execute on Windows PowerShell 1.0, but this directive will save you time and generate a more readable error message. The #Requires statement is seen here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">#Requires -version 2.0<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">The <b>$hive<\/b> variable holds the registry hive that will be monitored. In this script, you monitor the HKEY_LOCAL_MACHINE hive. This is the only hive the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa393042(VS.85).aspx\"><font face=\"Segoe\">RegistryKeyChangeEvent WMI class<\/font><\/a> supports. Any of the WMI classes that are derived from the <b>RegistryEvent<\/b> abstract class only work on the HKEY_LOCAL_MACHINE hive. The WMI registry event classes are seen in Table 1. <\/p>\n<p class=\"TableNum-Title\"><strong>Table 1<span>&nbsp; <\/span>WMI Registry Event Classes<\/strong><\/p>\n<table class=\"MsoNormalTable\" border=\"1\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"206\">\n<p class=\"TableHead\"><strong>Event class <\/p>\n<p><\/strong><\/p>\n<\/td>\n<td valign=\"top\" width=\"166\">\n<p class=\"TableHead\"><b>Hive location<\/p>\n<p><\/b><\/p>\n<\/td>\n<td valign=\"top\" width=\"252\">\n<p class=\"TableHead\"><b>Description <\/p>\n<p><\/b><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"206\">\n<p class=\"TableText\">RegistryEvent <\/p>\n<\/td>\n<td valign=\"top\" width=\"166\">\n<p class=\"TableText\">N\/A Abstract<\/p>\n<\/td>\n<td valign=\"top\" width=\"252\">\n<p class=\"TableText\">Base class for changes in the registry. <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"206\">\n<p class=\"TableText\">RegistryTreeChangeEvent<\/p>\n<\/td>\n<td valign=\"top\" width=\"166\">\n<p class=\"TableText\">RootPath<\/p>\n<\/td>\n<td valign=\"top\" width=\"252\">\n<p class=\"TableText\">Monitors changes to a hierarchy of keys. <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"206\">\n<p class=\"TableText\">RegistryKeyChangeEvent<\/p>\n<\/td>\n<td valign=\"top\" width=\"166\">\n<p class=\"TableText\">KeyPath<\/p>\n<\/td>\n<td valign=\"top\" width=\"252\">\n<p class=\"TableText\">Monitors changes to a single key. <\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"206\">\n<p class=\"TableText\">RegistryValueChangeEvent<\/p>\n<\/td>\n<td valign=\"top\" width=\"166\">\n<p class=\"TableText\">ValueName<\/p>\n<\/td>\n<td valign=\"top\" width=\"252\">\n<p class=\"TableText\">Monitors changes to a single value.<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p class=\"MsoNormal\">\n<p>&nbsp;<\/p>\n<p class=\"MsoNormal\">The value of the registry hive, HKEY_LOCAL_MACHINE, is normally listed as all capital letters, and in some instances, this is actually a requirement. However, with the RegsitryKeyChangeEvent WMI class as used in Windows PowerShell, this is not case-sensitive. You could easily use all lowercase letters for your hive name and it would work fine. Keep in mind that though it is not case sensitive, you must spell it correctly for the script to work:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">$hive = &#8220;HKEY_LOCAL_MACHINE&#8221;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">The key path points to the registry key you wish to monitor. There are two things that you need to remember. The first is that you do not have a backward slash at the beginning of the string. The second thing to remember is that all of the backward slashes are escaped&mdash;you have double backward slashes between portions of the registry key name. The value assignment to the <b>$keyPath<\/b> variable is seen here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">$keyPath = &#8220;Software\\Microsoft\\WBEM\\Scripting&#8221;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">The last portion of the path to the registry value you want to monitor is the value name itself. The variable <b>$valueName<\/b> stores the name of the value to monitor. This is shown here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">$valueName = &#8220;Default NameSpace&#8221;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">The path to the registry value that is being monitored is seen here:<\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" title=\"Image of the path to the registry value being monitored\" alt=\"Image of the path to the registry value being monitored\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2009\/november\/hey1105\/hsg-11-5-09-01.jpg\" width=\"600\" height=\"418\"><\/p>\n<p class=\"MsoNormal\"><br>After the path to the registry key value has been assigned via the three different variables, the <b>replace<\/b> operator is used to replace the double backward slashes with a single backward slash. This is only necessary for the value stored in the <b>$keyPath<\/b> variable because the hive and the value strings do not have any backward slashes in them. The resulting path is stored in the <b>$gipPath<\/b> variable. This path will be used with the <b>Get-ItemProperty<\/b> cmdlet to retrieve the new value that is assigned to the registry value&mdash;and the <b>Get-ItemProperty<\/b> cmdlet does not need to have the backward slashes escaped the way WMI does:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">$gipPath = $keyPath -replace &#8220;\\&#8221;,&#8221;&#8221;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">The WMI query is the same as the WMI query that is used in VBScript. An example of monitoring the registry from VBScript can be seen in the Hey, Scripting Guy! article, <span lang=\"EN\"><a href=\"http:\/\/blogs.technet.com\/heyscriptingguy\/archive\/2005\/07\/11\/how-can-i-monitor-changes-to-a-registry-key.aspx\"><font face=\"Segoe\">How Can I Monitor Changes to a Registry Key?<\/font><\/a><\/p>\n<p><\/span><\/p>\n<p class=\"Readeraidonly\"><span lang=\"EN\">When writing your VBScripts, if you keep your query separated from the WMI moniker, it makes it easier to reuse your WMI queries in a Windows PowerShell script.<\/span><\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">$query = &#8220;Select * from RegistryValueChangeEvent where Hive=&#8217;$hive&#8217; AND &#8221; +<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8220;KeyPath=&#8217;$keyPath&#8217; AND ValueName=&#8217;$ValueName'&#8221;<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">Two cmdlets are used to provide access to the WMI event system. The first cmdlet is the <b>Registry-WmiEvent<\/b> cmdlet. The WMI query that is stored in the <b>$query<\/b> variable is used, and the <b>SourceIdentifier<\/b> <b>KeyChanged<\/b> is assigned to the event. Only one event query can be assigned the <b>SourceIdentifier<\/b> of <b>KeyChanged<\/b> because <b>SourceIdentifiers<\/b> must be unique. If you inadvertently run the script a second time, this error appears:<\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" title=\"Image of error that appears when inadvertently running script a second time\" alt=\"Image of error that appears when inadvertently running script a second time\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2009\/november\/hey1105\/hsg-11-5-09-02.jpg\" width=\"600\" height=\"425\"><br><\/p>\n<p class=\"MsoNormal\">The <b>Wait-Event<\/b> cmdlet is used to pause the script execution until the event identified by the <b>SourceIdentifier<\/b> occurs. These two lines of code are seen here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">Register-WmiEvent -Query $query -SourceIdentifier KeyChanged<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">Wait-Event -SourceIdentifier KeyChanged<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">When the event triggers, the script continues to the next line. The <b>Get-ItemProperty<\/b> cmdlet is used to retrieve the new value that caused the event to trigger. This is seen here:<\/p>\n<p class=\"CodeBlock\"><span><font face=\"Lucida Sans Typewriter\">&#8220;New value for $valueName is &#8221; + (Get-ItemProperty -Path HKLM:$gipPath).$valueName<\/p>\n<p><\/font><\/span><\/p>\n<p class=\"MsoNormal\">After you run the script, the information seen in the following image appears in the Windows PowerShell ISE:<\/p>\n<p class=\"Fig-Graphic\"><img decoding=\"async\" title=\"Information appearing in Windows PowerShel ISE after running script\" alt=\"Information appearing in Windows PowerShel ISE after running script\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2009\/november\/hey1105\/hsg-11-5-09-03.jpg\" width=\"600\" height=\"397\"><a href=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/2009\/november\/hey1105\/hsg-11-5-09-03.jpg\"><font face=\"Segoe\"><\/font><\/a><\/p>\n<p class=\"MsoNormal\">Well, LK, that is all there is to monitoring the registry for a key value change event. Join us tomorrow as we dive into the virtual mail bag and retrieve questions that require shorter answers. Yes, it is time for Quick-Hits Friday.<\/p>\n<p class=\"MsoNormal\">If you want to know exactly what we will be looking at tomorrow, follow us on <a href=\"http:\/\/www.twitter.com\/scriptingguys\/\" target=\"_blank\"><font face=\"Segoe\">Twitter<\/font><\/a> or <a href=\"http:\/\/www.facebook.com\/group.php?gid=5901799452\" target=\"_blank\">Facebook<\/a>. If you have any questions, send e-mail to us at <a href=\"http:\/\/blogs.technet.commailto:scripter@microsoft.com\" target=\"_blank\"><font face=\"Segoe\">scripter@microsoft.com<\/font><\/a> or post them on the <a href=\"http:\/\/social.technet.microsoft.com\/Forums\/en\/ITCG\/threads\/\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<br>&nbsp;<\/p>\n<p><b><span>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/p>\n<p><\/span><\/b><\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>&nbsp; Hey, Scripting Guy! I need to be notified when a particular registry key value gets changed. The registry value is in the HKEY_LOCAL_MACHINE hive. What I am trying to accomplish is this: I am using a script to install software. After the first piece of software is successfully installed, I want to install a [&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":[42,3,4,45],"class_list":["post-52083","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-events-and-monitoring","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>&nbsp; Hey, Scripting Guy! I need to be notified when a particular registry key value gets changed. The registry value is in the HKEY_LOCAL_MACHINE hive. What I am trying to accomplish is this: I am using a script to install software. After the first piece of software is successfully installed, I want to install a [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/52083","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=52083"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/52083\/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=52083"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=52083"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=52083"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}