{"id":669,"date":"2014-09-17T00:01:00","date_gmt":"2014-09-17T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2014\/09\/17\/use-powershell-to-monitor-for-process-startup\/"},"modified":"2014-09-17T00:01:00","modified_gmt":"2014-09-17T00:01:00","slug":"use-powershell-to-monitor-for-process-startup","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/use-powershell-to-monitor-for-process-startup\/","title":{"rendered":"Use PowerShell to Monitor for Process Startup"},"content":{"rendered":"<p><b>Summary<\/b>: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to monitor for process startup.<\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. This morning, I spent a decent amount of time answering an email from a former colleague. I will actually share his email and my reply this coming weekend. In the meantime, I was playing around <b>Register-CimIndicationEvent<\/b>. This is not really a new Windows PowerShell cmdlet&mdash;I mean, it has been around for a while (since Windows PowerShell&nbsp;3.0), but not much has been written about it. There is little useful documentation for the cmdlet either.<\/p>\n<p>In today&rsquo;s post, I will talk about the following Windows PowerShell cmdlets:<\/p>\n<ul>\n<li>Register-CimIndicationEvent<\/li>\n<li>Get-Event<\/li>\n<li>Get-EventSubscriber<\/li>\n<li>Unregister-Event<\/li>\n<li>Select-Object<\/li>\n<li>Remove-Event<\/li>\n<\/ul>\n<p>To monitor for any process startup, I can use the WMI class Win32_ProcessStartTrace. When the event fires, the class provides information about the process ID, the parent process ID, the process name, the session ID, and even the SID for the user context that generates the event. This information becomes available after I retrieve the generated event. For more information, see MSDN: <a href=\"http:\/\/msdn.microsoft.com\/library\/windows\/desktop\/aa394374(v=vs.85).aspx\" target=\"_blank\">Win32_ProcessStartTrace class<\/a>.<\/p>\n<h2>Register for the event<\/h2>\n<p style=\"margin-left:30px\"><b>Note&nbsp;<\/b> This procedure requires admin rights. To start an elevated Windows PowerShell console, right-click the Windows PowerShell console icon and select <b>Run as Administrator<\/b> from the action menu.<\/p>\n<p>The first thing I need to do is to register to receive events. To do this, I use the <b>Register-CimIndicationEvent<\/b> cmdlet. When I do, I want to specify the WMI class to monitor and a name that I can use to track the generated event subscription. Here is the command I use:<\/p>\n<p style=\"margin-left:30px\">Register-CimIndicationEvent -ClassName Win32_ProcessStartTrace -SourceIdentifier &quot;ProcessStarted&quot;<\/p>\n<p>When I run the command, nothing returns. But I can use the <b>Get-EventSubscriber<\/b> cmdlet to verify that something actually happened (such as creating a new event subscription). Here is the command and its associated output:<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; Get-EventSubscriber<\/p>\n<p style=\"margin-left:30px\">SubscriptionId&nbsp;&nbsp; : 7<\/p>\n<p style=\"margin-left:30px\">SourceObject&nbsp;&nbsp;&nbsp;&nbsp; : Microsoft.Management.Infrastructure.CimCmdlets.CimIndicationWatcher<\/p>\n<p style=\"margin-left:30px\">EventName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : CimIndicationArrived<\/p>\n<p style=\"margin-left:30px\">SourceIdentifier : ProcessStarted<\/p>\n<p style=\"margin-left:30px\">Action&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"margin-left:30px\">HandlerDelegate&nbsp; :<\/p>\n<p style=\"margin-left:30px\">SupportEvent&nbsp;&nbsp;&nbsp;&nbsp; : False<\/p>\n<p style=\"margin-left:30px\">ForwardEvent&nbsp;&nbsp;&nbsp;&nbsp; : False<\/p>\n<h2>Hey, is anything happening?<\/h2>\n<p>I have not deliberately started any processes yet (like Calculator or Notepad), but when I use the <b>Get-Event <\/b>cmdlet, I see that the operating system generated a bunch of processes anyway. So there are already new processes starting up. The command with no parameters is shown here:<\/p>\n<p style=\"margin-left:30px\">Get-Event<\/p>\n<p>Here is what the output looks like at this point:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-9-17-14-01.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-9-17-14-01.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>There is one property that I can basically understand and that is the <b>TimeGenerated<\/b> property. Everything else is wrapped up in other objects. One thing I can do is take advantage of the ability of Windows PowerShell to do what I call &ldquo;the automatic foreach.&rdquo; That is, I can select a specific property from a collection of objects, and Windows PowerShell will display that object. Here, I choose the <b>SourceEventArgs<\/b> property:<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; (Get-Event).sourceeventargs<\/p>\n<p style=\"margin-left:30px\">NewEvent&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MachineId&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Bookmark&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Context<\/p>\n<p style=\"margin-left:30px\">&#8212;&#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8212;-<\/p>\n<p style=\"margin-left:30px\">Win32_ProcessStartT&#8230;<\/p>\n<p style=\"margin-left:30px\">Win32_ProcessStartT&#8230;<\/p>\n<p style=\"margin-left:30px\">Win32_ProcessStartT&#8230;<\/p>\n<p style=\"margin-left:30px\">Win32_ProcessStartT&#8230;<\/p>\n<p style=\"margin-left:30px\">Win32_ProcessStartT&#8230;<\/p>\n<p style=\"margin-left:30px\">&lt;output truncated&gt;<\/p>\n<p>Notice that each <b>NewEvent<\/b> says that it is an instance of Win32_ProcessStartTrace. Remember the MSDN document I mentioned earlier? This is where that comes into play. I can now cherry pick which of the properties of Win32_ProcessStartTrace I want to see. First, I look at the <b>NewEvent<\/b> property that contains instances of Win32_ProcessStartTrace. Here is the result:<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; (Get-Event).sourceeventargs.newevent<\/p>\n<p style=\"margin-left:30px\">SECURITY_DESCRIPTOR :<\/p>\n<p style=\"margin-left:30px\">TIME_CREATED&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 130552887343479772<\/p>\n<p style=\"margin-left:30px\">ParentProcessID&nbsp;&nbsp;&nbsp;&nbsp; : 4512<\/p>\n<p style=\"margin-left:30px\">ProcessID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 9304<\/p>\n<p style=\"margin-left:30px\">ProcessName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : SearchProtocolHost.exe<\/p>\n<p style=\"margin-left:30px\">SessionID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 1<\/p>\n<p style=\"margin-left:30px\">Sid&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : {1, 1, 0, 0&#8230;}<\/p>\n<p style=\"margin-left:30px\">PSComputerName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"margin-left:30px\">SECURITY_DESCRIPTOR :<\/p>\n<p style=\"margin-left:30px\">TIME_CREATED&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 130552887343479773<\/p>\n<p style=\"margin-left:30px\">ParentProcessID&nbsp;&nbsp;&nbsp;&nbsp; : 4512<\/p>\n<p style=\"margin-left:30px\">ProcessID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 3540<\/p>\n<p style=\"margin-left:30px\">ProcessName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : SearchFilterHost.exe<\/p>\n<p style=\"margin-left:30px\">SessionID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : 0<\/p>\n<p style=\"margin-left:30px\">Sid&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : {1, 1, 0, 0&#8230;}<\/p>\n<p style=\"margin-left:30px\">PSComputerName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :<\/p>\n<p style=\"margin-left:30px\">&lt;output truncated&gt;<\/p>\n<p>Yep. That is what I thought would be there. So now let me get a list for only the <b>ProcessName<\/b> property to see what is actually starting up:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-9-17-14-02.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-9-17-14-02.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>Cool. But when are these events happening? If I look at the <b>Time_Created<\/b> property, all I get is a bunch of numbers. When I look at MSDN, it simply says it is a string that represents time created&mdash;not exactly the most helpful Help in the world. Here is the output:<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; (Get-Event).sourceeventargs.newevent.Time_Created<\/p>\n<p style=\"margin-left:30px\">130552887343479772<\/p>\n<p style=\"margin-left:30px\">130552887343479773<\/p>\n<p style=\"margin-left:30px\">130552887430300826<\/p>\n<p style=\"margin-left:30px\">130552889482027640<\/p>\n<p style=\"margin-left:30px\">130552889482027641<\/p>\n<p style=\"margin-left:30px\">&lt;output truncated&gt;<\/p>\n<p>So, I decide to try one of my favorite tricks to translate this. I use the [System.Management.ManagementDateTimeConverter] class. But no matter what I try, I get error messages. Here are some efforts that didn&rsquo;t work:<\/p>\n<p style=\"margin-left:30px\">[System.Management.ManagementDateTimeConverter]::ToDmtfdatetime(130552788310990332)<\/p>\n<p style=\"margin-left:30px\">[System.Management.ManagementDateTimeConverter]::Totimespan(130552788310990332)<\/p>\n<p style=\"margin-left:30px\">[System.Management.ManagementDateTimeConverter]::Todatetime(130552788310990332)<\/p>\n<h2>So basically, I give up?<\/h2>\n<p>No, I don&rsquo;t give up&mdash;not with Windows PowerShell. There is always a way to do what I need to do when using Windows PowerShell. I decide to pull out another one of my favorite tricks: the custom property with <b>Select-Object<\/b>. Remember that earlier when I was looking at the output from <b>Get-Event<\/b>, I saw the <b>TimeGenerated<\/b> property.<\/p>\n<p>This property comes from <b>Get-Event<\/b> and is logged when the event generates. It does not come from WMI, so it is a proper <b>DateTime<\/b> object. I need to pick the property from this value and then get the process name from the object held in the <b>NewEvent<\/b> property. Here is the command I decided to use (this is a one-line command that I broke into two lines for readability online):<\/p>\n<p style=\"margin-left:30px\">Get-Event |<\/p>\n<p style=\"margin-left:30px\">select timegenerated, @{L=&#039;e&#039;; E = {$_.sourceeventargs.newevent.processname}}<\/p>\n<p>The output from this command is shown here:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-9-17-14-03.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-9-17-14-03.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<h2>Cleanup work<\/h2>\n<p>Now I need to do a little bit of cleanup. First, I remove all of the events. To do this, I use <b>Get-Event<\/b> and pipe the output to <b>Remove-Event<\/b>. I next confirm that this worked by using <b>Get-Event<\/b>:<\/p>\n<p style=\"margin-left:30px\">get-event | Remove-Event<\/p>\n<p style=\"margin-left:30px\">get-event<\/p>\n<p>Second, I need to unregister the event subscribers. To do this, I use <b>Get-EventSubscriber<\/b> and pipe the output to <b>Unregister-Event<\/b>. Once again, I call the prior command to confirm. Here are the two lines of script:<\/p>\n<p style=\"margin-left:30px\">Get-EventSubscriber | Unregister-Event<\/p>\n<p style=\"margin-left:30px\">Get-EventSubscriber<\/p>\n<p>That is all there is to using <b>Register-CimIndicationEvent<\/b> to monitor for process startup. I will continue talking about processes tomorrow when I will talk about more groovy things.<\/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\" target=\"_blank\">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>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to monitor for process startup. Microsoft Scripting Guy, Ed Wilson, is here. This morning, I spent a decent amount of time answering an email from a former colleague. I will actually share his email and my reply this coming weekend. In the meantime, I [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[42,31,87,3,4,45,6],"class_list":["post-669","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-events-and-monitoring","tag-operating-system","tag-processes","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell","tag-wmi"],"acf":[],"blog_post_summary":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about using Windows PowerShell to monitor for process startup. Microsoft Scripting Guy, Ed Wilson, is here. This morning, I spent a decent amount of time answering an email from a former colleague. I will actually share his email and my reply this coming weekend. In the meantime, I [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/669","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\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=669"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/669\/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=669"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=669"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=669"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}