{"id":12991,"date":"2011-08-16T00:01:00","date_gmt":"2011-08-16T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2011\/08\/16\/monitor-and-respond-to-windows-power-events-with-powershell\/"},"modified":"2011-08-16T00:01:00","modified_gmt":"2011-08-16T00:01:00","slug":"monitor-and-respond-to-windows-power-events-with-powershell","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/monitor-and-respond-to-windows-power-events-with-powershell\/","title":{"rendered":"Monitor and Respond to Windows Power Events with PowerShell"},"content":{"rendered":"<p><strong>Summary<\/strong>: Guest Blogger Trevor Sullivan shows how to monitor and to respond to Windows Power events using Windows PowerShell.<\/p>\n<p>&nbsp;<\/p>\n<p>Microsoft Scripting Guy Ed Wilson here. Today&rsquo;s guest blogger is Trevor Sullivan, and he has a fascinating article about responding to power management events. First, a little bit about Trevor.&nbsp;<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1460.HSG-8-16-11-1.jpg\"><img decoding=\"async\" style=\"border: 0px\" title=\"Photo of Trevor Sullivan\" alt=\"Photo of Trevor Sullivan\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1460.HSG-8-16-11-1.jpg\" width=\"362\" height=\"474\" \/><\/a><\/p>\n<p>Trevor Sullivan is a passionate, experienced, and Microsoft-certified IT pro with more than seven years in the industry. Although he is interested in nearly all Microsoft technologies, his primary specialties include:<\/p>\n<ul>\n<li>Design, implementation, and troubleshooting of Microsoft System Center Configuration Manager 2007.<\/li>\n<li>Automation using Windows PowerShell, Windows Management Instrumentation (WMI), Active Directory Services Interface (ADSI), and the Microsoft .NET Framework.<\/li>\n<\/ul>\n<p>Trevor is a Microsoft-recognized Community Contributor (MCC) and is active in several online communities:<\/p>\n<ul>\n<li>Microsoft TechNet and MSDN discussion forums (he is a moderator on the TechNet Scripting Guys forum).<\/li>\n<li><a href=\"http:\/\/myitforum.com\/\">myITforum<\/a> mailing lists.<\/li>\n<li>Blogging on WordPress (<a href=\"http:\/\/trevorsullivan.net\/\">http:\/\/trevorsullivan.net<\/a>).<\/li>\n<li>Twitter (<a href=\"https:\/\/twitter.com\/pcgeek86\">@pcgeek86<\/a>).<\/li>\n<\/ul>\n<p>One of his major achievements is the development and public release of an open-source Windows PowerShell module called <a title=\"PowerEvents  \" href=\"http:\/\/powerevents.codeplex.com\">PowerEvents<\/a>. During his personal time, he enjoys studying theology, spending time with his girlfriend, being outdoors, shooting photos, playing video games, testing software, and learning about all sorts of new things.<\/p>\n<p>Take it away, Trevor!<\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"font-size: small\"><b>Introduction<\/b><\/span><\/p>\n<p>Oftentimes, people want to be able to respond to events automatically on their computers: &ldquo;When &lt;X&gt; happens, I want &lt;Y&gt; to happen in response.&rdquo; An example of this might be: &ldquo;If SomeProcess.exe exceeds 50 percent processor utilization for 60 seconds, kill it<i>.<\/i>&rdquo; Usually this would require some custom systems monitoring software, but what if I told you that your computer had this functionality built into it already? That&rsquo;s right, little known to most people is the WMI background service, which provides a robust eventing and event response model.<\/p>\n<p>Although power management hasn&rsquo;t always been a highlight of the Microsoft Windows operating system (OS), it&rsquo;s certainly come a long way in Windows 7 and is now quite robust. Sleeping and hibernating in Windows 7 are both quite fast, and resuming from both states is likewise very quick. But what if you want to do something when your computer wakes up? Though this may not be a terribly common scenario, sometimes people have the need to subscribe to this event and perform an action in response to it.<\/p>\n<p>In the remainder of this article, we will take a look at how to subscribe for system-level power management events, and how to respond to them. We will be working with the following technologies:<\/p>\n<ul>\n<li><a href=\"http:\/\/www.scriptingguys.com\/learnpowershell\">Windows PowerShell<\/a><\/li>\n<li><a href=\"http:\/\/powerevents.codeplex.com\/\">PowerEvents<\/a> for Windows PowerShell<\/li>\n<li><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa394582(v=vs.85).aspx\">Windows Management Instrumentation<\/a> (WMI)<\/li>\n<\/ul>\n<p><span style=\"font-size: small\"><b><br \/>WMI Power Management events<\/b><\/span><\/p>\n<p>Microsoft has built a robust power management provider into <a href=\"http:\/\/www.google.com\/url?sa=t&amp;source=web&amp;cd=1&amp;ved=0CHYQFjAA&amp;url=http%3A%2F%2Fwindows.microsoft.com%2Fen-US%2Fwindows7%2Fproducts%2Fhome&amp;ei=sooYTqakM6OtsAL1mpjCBw&amp;usg=AFQjCNHe-GPYcoB9fJE-wztciRkk9VHnEQ\">Windows 7<\/a>, and thankfully for us, they have exposed its functionality via the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa394582(v=vs.85).aspx\">WMI<\/a> service. WMI provides a standards-based interface in the operating system and applications that extend it. Although WMI has suffered from reliability and performance problems in the past&mdash;primarily on Windows XP&mdash;modern-day hardware combined with the newest Windows 7 operating system is quite reliable. Microsoft has resolved a lot of WMI bugs such that it is a very dependable service.<\/p>\n<p><span style=\"font-size: small\"><b><br \/>Power Management WMI Provider<\/b><\/span><\/p>\n<p>All WMI providers (extensions to WMI) are registered in a particular WMI namespace under the <b>__Win32Provider<\/b> class. We can ensure that the Windows Power Management provider is registered by running this WMI query from Windows PowerShell:<\/p>\n<p style=\"padding-left: 30px\">@(<b>Get-WmiObject<\/b> <i>-Namespace<\/i> root\\cimv2 <i>-Query<\/i> &#8220;select * from __Win32Provider where Name = &#8216;MS_Power_Management_Event_Provider'&#8221;).Count<\/p>\n<p>If this query returns a result of &ldquo;1,&rdquo; we know that the provider is registered.<\/p>\n<p><span style=\"font-size: small\"><b><br \/>Win32_PowerManagementEvent class<\/b><\/span><\/p>\n<p>The power management provider exposes a single WMI class called <b><a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa394362(v=vs.85).aspx\">Win32_PowerManagementEvent<\/a><\/b>, which is an extrinsic event class. Extrinsic event classes differ from intrinsic event classes in that the events they provide come from an external provider (the Power Management WMI provider), rather than them representing a change to a WMI object.<\/p>\n<p>The <b>Win32_PowerManagementEvent<\/b> class only has one property that we really care about, which is the <b>EventType<\/b> property. The possible values for this property are:<\/p>\n<table style=\"width: 209px\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"51\">\n<p><b><span style=\"text-decoration: underline\">Value<\/span><\/b><\/p>\n<\/td>\n<td valign=\"top\" width=\"156\">\n<p><b><span style=\"text-decoration: underline\">Meaning<\/span><\/b><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"51\">\n<p>4<\/p>\n<\/td>\n<td valign=\"top\" width=\"156\">\n<p>Entering suspend<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"51\">\n<p>7<\/p>\n<\/td>\n<td valign=\"top\" width=\"156\">\n<p>Resume from suspend<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"51\">\n<p>10<\/p>\n<\/td>\n<td valign=\"top\" width=\"156\">\n<p>Power status change<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"51\">\n<p>11<\/p>\n<\/td>\n<td valign=\"top\" width=\"156\">\n<p>OEM event<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"51\">\n<p>18<\/p>\n<\/td>\n<td valign=\"top\" width=\"156\">\n<p>Resume automatic<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>As you might gather, we are interested in events that have a value of &#8220;7,&#8221; which represents a system resume.<\/p>\n<p><span style=\"font-size: small\"><b><br \/>Example Scenario<\/b><\/span><\/p>\n<p>In this example scenario, we are going to take a look at how to restart a Windows service when the system resumes. Specifically, I recently noticed that the <a href=\"http:\/\/code.google.com\/p\/ps3mediaserver\/\">PS3 Media Server<\/a> software has an <a href=\"http:\/\/code.google.com\/p\/ps3mediaserver\/issues\/detail?id=163&amp;colspec=ID%20Type%20Status%20Priority%20Milestone%20Owner%20Summary%20Stars\">issue with power management<\/a> in that it does not listen for connections upon system resume from Standby\/Hibernate. This has <a href=\"http:\/\/code.google.com\/p\/ps3mediaserver\/issues\/detail?id=163#c18\">reportedly been a problem<\/a> with Windows 7 Ultimate Edition 64-bit.<\/p>\n<p>To work around this issue, we&rsquo;ll look at how to restart the PS3 Media Server service each time the computer resumes from a low power state.<\/p>\n<p><span style=\"font-size: small\"><b><br \/>Using PowerEvents<\/b><\/span><\/p>\n<p>The use of the PowerEvents model follows a three-step process:<\/p>\n<ol>\n<li>Create WMI event filter using WQL.<\/li>\n<li>Create an event consumer (response to the event occurrence).<\/li>\n<li>Create a WMI binding between the event filter and the event consumer.<\/li>\n<\/ol>\n<p>We will cover these three steps individually below.<\/p>\n<p><span style=\"font-size: small\"><b><br \/>WQL event filter<\/b><\/span><\/p>\n<p>First, we need to build an WMI event filter using the WMI Query Language (WQL). WQL is similar to Structured Query Language (SQL), but is much more limited in scope. WQL does not support <b>INSERT<\/b>, <b>UPDATE<\/b>, or <b>DELETE<\/b> statements; it only supports <b>SELECT<\/b> queries. We&rsquo;re going to follow the event query template:<\/p>\n<p style=\"padding-left: 30px\">select * from &lt;<i>WmiClass<\/i>&gt; WITHIN &lt;<i>PollInterval<\/i>&gt; where &lt;<i>Criteria<\/i>&gt;<\/p>\n<p>In this case, we&rsquo;re going to use the following values for our event query:<\/p>\n<ul>\n<li><i>WmiClass<\/i> = Win32_PowerManagementEvent<\/li>\n<li><i>PollInterval<\/i> = 5<\/li>\n<li><i>Criteria<\/i> = &#8220;EventType = 7&#8221;<\/li>\n<\/ul>\n<p>Our resulting query will look like this:<\/p>\n<p style=\"padding-left: 30px\">select * from Win32_PowerManagementEvent WITHIN 5 where EventType = 7<\/p>\n<p>The command we&rsquo;ll use to create our WMI event filter using the PowerEvents module for Windows PowerShell looks like this:<\/p>\n<p style=\"padding-left: 30px\">$Filter = New-WmiEventFilter <i>-Name<\/i> SystemResumed <i>-Query<\/i> &#8220;select * from Win32_PowerManagementEvent where EventType = 7&#8221;<\/p>\n<p>We store the filter object in a Windows PowerShell variable for later use in the event binding.<\/p>\n<p>More information about WMI event queries can be found in the PowerEvents documentation. The PDF is located in the Documentation folder of the <a href=\"http:\/\/powerevents.codeplex.com\/\">PowerEvents<\/a> download. This document includes information about how to test your WMI event query using the wbemtest.exe utility, before creating the permanent event registration to reduce troubleshooting hassle.<\/p>\n<p><span style=\"font-size: small\"><b><br \/>Event consumer<\/b><\/span><\/p>\n<p>Now that we have created (and tested, right?) the event filter, we need to create an event consumer. In this example, we&rsquo;ll use a Windows PowerShell script to stop and start the PS3 Media Server service (short name: <b>PS3 Media Server<\/b>). The script itself contains this code:<\/p>\n<p style=\"padding-left: 30px\">$ServiceName = $args[0]<\/p>\n<p style=\"padding-left: 30px\"><b>Add-Content<\/b> <i>-Path<\/i> &#8216;c:\\Restart Service.log&#8217; <i>-Value<\/i> &#8220;Service name is: $ServiceName&#8221;<\/p>\n<p style=\"padding-left: 30px\">$Service = @(<b>Get-WmiObject<\/b> <i>-Namespace<\/i> root\\cimv2 <i>-Class<\/i> Win32_Service <i>-Filter<\/i> &#8220;Name = &#8216;$ServiceName'&#8221;)<\/p>\n<p style=\"padding-left: 30px\"><b>Add-Content<\/b> <i>-Path<\/i> &#8216;C:\\Restart Service.log&#8217; <i>-Value<\/i> &#8220;Found $($Service.Count) instances of &#8216;$ServiceName&#8217; service&#8221;<\/p>\n<p style=\"padding-left: 30px\">$Result = $Service[0].StopService()<\/p>\n<p style=\"padding-left: 30px\"><b>Add-Content<\/b> <i>-Path<\/i> &#8216;c:\\Restart Service.log&#8217; <i>-Value<\/i> &#8220;Stopped service with result: $($Result.ReturnValue)&#8221;<\/p>\n<p style=\"padding-left: 30px\"><b>Start-Sleep<\/b> 4<\/p>\n<p style=\"padding-left: 30px\">$Result = $Service[0].StartService()<\/p>\n<p style=\"padding-left: 30px\"><b>Add-Content<\/b> <i>-Path<\/i> &#8216;c:\\Restart Service.log&#8217; <i>-Value<\/i> &#8220;Started service with result: $($Result.ReturnValue)&#8221;<\/p>\n<p style=\"padding-left: 30px\"><b>Add-Content<\/b> <i>-Path<\/i> &#8216;c:\\Restart Service.log&#8217; <i>-Value<\/i> &#8220;Exiting restart service script&#8221;<\/p>\n<p>Save this code in a file called c:\\windows\\temp\\Restart Windows Service.ps1.<\/p>\n<p>To create the event consumer object in WMI, we&rsquo;ll use the following command:<\/p>\n<p style=\"padding-left: 30px\">$Consumer = New-WmiEventConsumer <i>-Verbose<\/i> <i>-Name<\/i> SystemResumedRestartService <i>-ConsumerType<\/i> CommandLine <i>-CommandLineTemplate<\/i> &#8220;powershell.exe -command `&#8221;. &#8216;$($env:WinDir)\\temp\\Restart Windows Service.ps1&#8217; &#8216;PS3 Media Server&#8217;`&#8221;&#8221;<\/p>\n<p>This command creates a command-line consumer &mdash; that is to say, we want to call a command-line utility in response to the event that occurs. We give it a friendly name so that we know what it runs in response to, and what it does in response to the event: <b>SystemResumedRestartService.<\/b> Then we use the <i>CommandLineTemplate<\/i> parameter to specify the command line we want to execute in response to the event. In this case, we&rsquo;re calling Windows PowerShell and passing it our script file via the <i>-command<\/i> switch along with an argument to the script file. We use script arguments to make our script dynamic. All we have to do to change the service that gets restarted is change the parameter that we&rsquo;re passing to it. We don&rsquo;t have to touch the script itself at all.<\/p>\n<p style=\"padding-left: 30px\"><b>Important<\/b>&nbsp; &nbsp;Make sure you have configured your Windows PowerShell execution policy to allow execution of script files; otherwise, the event consumer will fail. Run Windows PowerShell with your administrative token and use this command: <b>Set-ExecutionPolicy Unrestricted<\/b>.<\/p>\n<p><span style=\"font-size: small\"><b><br \/>WMI event binding<\/b><\/span><\/p>\n<p>Finally, now that we have created our event filter and event consumer, all we have to do to initiate the flow of events is bind them together. We&rsquo;ve got the filter and consumer stored in variables called <b>$Filter<\/b> and <b>$Consumer<\/b>, so all we have to do is call this command:<\/p>\n<p style=\"padding-left: 30px\">New-WmiFilterToConsumerBinding <i>-Filter<\/i> $Filter <i>-Consumer<\/i> $Consumer<\/p>\n<p><span style=\"font-size: small\"><b><br \/>Testing<\/b><\/span><\/p>\n<p>And that&rsquo;s it! We&rsquo;re done. Now that all the WMI objects have been created, all we have to do is suspend and resume our workstation to test the process. After the system is restarted, we should see a c:\\Restart Service.log file created. Check this log to ensure that the service you specified in the event consumer command-line was properly stopped and started.<\/p>\n<p><span style=\"font-size: small\"><b><br \/>Conclusion<\/b><\/span><\/p>\n<p>This article has demonstrated the use of the <a href=\"http:\/\/powerevents.codeplex.com\/\">PowerEvents<\/a> module for Windows PowerShell to create an event listener (filter)\/responder (consumer) for wake-from-low-power-state events. Although this particular example restarts a Windows service in response to such an event, you can use your creativity to come up with other tasks you might need to fire off at the same occurrence.<\/p>\n<p style=\"padding-left: 30px\"><b>Note<\/b>&nbsp; &nbsp;For more information about working with permanent and temporary WMI events, see <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/tags\/windows+powershell\/wmi\/events+and+monitoring\/\">&nbsp;this collection of Hey, Scripting Guy! Blog posts<\/a>. This collection includes a post about using <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2010\/12\/06\/learn-how-to-use-vbscript-to-create-permanent-wmi-events.aspx\">VBScript to create permanent WMI events<\/a>. This post is important because it discusses the basics of permanent WMI events. Next, I talk about using Windows PowerShell <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2010\/12\/07\/use-powershell-to-monitor-and-respond-to-events-on-your-server.aspx\">to monitor and to respond to events on the server<\/a>. This post continues the discussion about permanent WMI events. This is followed by the first of two articles from Trevor that talk about his <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2010\/12\/08\/use-a-powershell-module-to-work-with-wmi-permanent-events.aspx\">Windows PowerShell module to work with WMI permanent events<\/a>. The second Trevor article in the series talks about <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2010\/12\/09\/use-the-powershell-wmi-event-module-to-quickly-monitor-events.aspx\">using the Windows PowerShell WMI event module to quickly monitor events<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<p>Thanks Trevor for an interesting article, and for writing your Windows PowerShell module for working with WMI Permanent Events.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><b>Ed Wilson, Microsoft Scripting Guy<\/b><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Guest Blogger Trevor Sullivan shows how to monitor and to respond to Windows Power events using Windows PowerShell. &nbsp; Microsoft Scripting Guy Ed Wilson here. Today&rsquo;s guest blogger is Trevor Sullivan, and he has a fascinating article about responding to power management events. First, a little bit about Trevor.&nbsp; Trevor Sullivan is a passionate, [&hellip;]<\/p>\n","protected":false},"author":598,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[42,56,3,4,211,45,6],"class_list":["post-12991","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-events-and-monitoring","tag-guest-blogger","tag-scripting-guy","tag-scripting-techniques","tag-trevor-sullivan","tag-windows-powershell","tag-wmi"],"acf":[],"blog_post_summary":"<p>Summary: Guest Blogger Trevor Sullivan shows how to monitor and to respond to Windows Power events using Windows PowerShell. &nbsp; Microsoft Scripting Guy Ed Wilson here. Today&rsquo;s guest blogger is Trevor Sullivan, and he has a fascinating article about responding to power management events. First, a little bit about Trevor.&nbsp; Trevor Sullivan is a passionate, [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/12991","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\/598"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=12991"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/12991\/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=12991"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=12991"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=12991"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}