{"id":13321,"date":"2011-07-14T00:01:00","date_gmt":"2011-07-14T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2011\/07\/14\/automatically-enable-and-disable-trace-logs-using-powershell\/"},"modified":"2011-07-14T00:01:00","modified_gmt":"2011-07-14T00:01:00","slug":"automatically-enable-and-disable-trace-logs-using-powershell","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/automatically-enable-and-disable-trace-logs-using-powershell\/","title":{"rendered":"Automatically Enable and Disable Trace Logs Using PowerShell"},"content":{"rendered":"<p><b>Summary<\/b>: Use Windows PowerShell to automatically enable and disable trace logs.<\/p>\n<p>&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\" \/>Hey, Scripting Guy! Your articles have been right on target&mdash;they hit me where I live. I am wondering if I could actually automate some of this? Suppose I am trying to install software using WMI, and I would like to see the log entries you talked about the other day. Could I do all of this in the same script?<\/p>\n<p>&mdash;AS<br \/>&nbsp;<\/p>\n<p><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 AS,<\/p>\n<p>Microsoft Scripting Guy Ed Wilson here. One does not have to be a night owl to work in IT, but it seems to help. Last night, I was working on some problems with third-hop WMI delegation, and I happened to look up and it was 4:00 in the morning. I said to myself, &ldquo;Cool, my friends in Australia are awake.&rdquo; So I exchanged a number of email messages with my Australian friends. In fact, <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2010\/12\/26\/weekend-scripter-create-a-holiday-greeting-using-powershell-and-wpf.aspx\">Chris Bellee<\/a> and <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2008\/10\/06\/self-contained-underwater-breathing-apparatus.aspx\">Pete<\/a> both had some great suggestions to help me with troubleshooting my problem. I also exchanged email with my <a href=\"http:\/\/blogs.technet.com\/search\/searchresults.aspx?q=jit&amp;sections=7618\">good friend Jit<\/a>; unfortunately, neither he nor <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2010\/04\/14\/hey-scripting-guy-april-14-2010.aspx\">Brent<\/a> (one of my <a href=\"http:\/\/en.wikipedia.org\/wiki\/Tim_Tam\">Tim Tam<\/a> connections) is going to be at the TechReady conference I will be speaking at in Seattle in a few weeks. As a matter of a fact, I am speaking at a large number of events in the next few weeks: the <a href=\"https:\/\/www323.livemeeting.com\/lrs\/8000181573\/Registration.aspx?PageName=j5mdg2340ds2nr6z\">Virtual PowerShell User group<\/a>, the <a href=\"http:\/\/powershellgroup.org\/content\/july-central-ohio-powershell-users-group\">Central Ohio PowerShell Users Group<\/a>, and <a href=\"http:\/\/www.sqlsaturday.com\/80\/schedule.aspx\">SQL Saturday #80<\/a> in Wheeling West Virginia, in addition to TechReady. There are a lot of events. I use <a href=\"http:\/\/technet.microsoft.com\/en-us\/scriptcenter\/hh182567\">the Community page on the Script Center<\/a> to keep track of where I will be and when. Lisa is doing a great job keeping this page up to date, and we are putting my commitments on the page as soon as I know them.&nbsp;<\/p>\n<p style=\"padding-left: 30px\">In <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2011\/07\/09\/use-powershell-to-troubleshoot-windows.aspx\">Saturday&rsquo;s Weekend Scripter post<\/a>, I talked about working with Event Tracing for Windows (ETW) logs. I discussed how to enable and disable the logs, and how to use the <b>Get-WinEvent<\/b> cmdlet to find and to read the trace. On <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2011\/07\/11\/use-dates-types-to-filter-event-trace-logs-in-powershell.aspx\">Monday, I continued the ETW discussion<\/a> by examining the <b>datetime<\/b> stamp that is generated for each event. On <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2011\/07\/12\/parse-windows-trace-logs-by-using-powershell.aspx\">Tuesday, I explored parsing the <b>message<\/b> property<\/a> of the WMI Activity Trace log. <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2011\/07\/13\/use-powershell-to-troubleshoot-software-installation.aspx\">Yesterday<\/a>, I talked about using Windows PowerShell to troubleshoot software installation.&nbsp;<\/p>\n<p>AS, I know I have been writing quite a bit recently about <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2011\/06\/26\/don-t-write-scripts-write-powershell-functions.aspx\">the importance of writing functions<\/a> and <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2011\/06\/25\/don-t-write-powershell-scripts.aspx\">not writing scripts<\/a>, and today&rsquo;s script is no exception. What I am going to do today is write a script. This means that what I am producing is pretty much limited to a specific scenario. This is really the way that advanced functions and modules are produced&mdash;they start out as a quick line of code that gets collected into a script and migrates to functions, advanced functions, and modules. In fact, nearly every function that is in my <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2011\/07\/03\/use-a-module-to-simplify-scripting-local-users-and-groups.aspx\">Local User Management module<\/a> began as a quick script. The complete EnableLogDisableLogInstallSoftware.ps1 script is shown here.<\/p>\n<p style=\"padding-left: 30px\"><b>EnableLogDisableLogInstallSoftware.ps1<\/b><\/p>\n<p style=\"padding-left: 30px\">$WmiLog = (Get-WinEvent -ListLog *wmi*trace* -force).logname<\/p>\n<p style=\"padding-left: 30px\">echo y | Wevtutil.exe sl $wmiLog \/e:true<\/p>\n<p style=\"padding-left: 30px\">Invoke-WmiMethod -class win32_product -Name install `<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; &nbsp;-ArgumentList @($true, $null, &#8220;\\\\hyperv1\\data\\HelloWorld.msi&#8221;)<\/p>\n<p style=\"padding-left: 30px\">echo y | Wevtutil.exe sl $wmiLog \/e:false<\/p>\n<p style=\"padding-left: 30px\">Get-WinEvent -LogName $wmiLog -Oldest&nbsp;<\/p>\n<p>AS, the first thing I do is find the exact name for the trace log with which I want to work. I use a wildcard character (*) to simplify typing and because I might not know the exact name of the log in the first place. Keep in mind, this wildcard character pattern resolves to the WMI Activity\/Trace log on my Windows 7 Ultimate system. It is entirely possible that other software could create its own ETW trace log, and my wildcard character pattern might pick up those log files. You should therefore <i>test<\/i> the pattern to ensure that your pattern resolves to the log you wish to use. Identifying ETW logs and working with them is discussed in <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2011\/07\/09\/use-powershell-to-troubleshoot-windows.aspx\">Saturday&rsquo;s post<\/a>.<\/p>\n<p style=\"padding-left: 30px\">$WmiLog = (Get-WinEvent -ListLog *wmi*trace* -force).logname&nbsp;<\/p>\n<p>The next line of code in the script combines several cool tricks, one really powerful technique, and an idea for future exploration. With all this going for it, let&rsquo;s dive right in and show the code before discussing it:<\/p>\n<p style=\"padding-left: 30px\">echo y | Wevtutil.exe sl $wmiLog \/e:true<\/p>\n<p>I will admit the line of code does not look like much, but it is really powerful stuff. The first part, <b>echo y<\/b>, allows me to pass a <b>y<\/b> (for yes) to the prompt from the command. This technique will be discussed in two days in the July 16, 2011, blog post by Sean Kearney (a.k.a. Energized Tech).<\/p>\n<p>The best way to understand the <b>echo y<\/b> thing is to see what happens without it. When running the <b>wevtutil.exe<\/b><i> <\/i>command to enable a trace log, a prompt displays a warning that the command will clear the previous contents of the log. These types of prompts, common for lots of command-line utilities, play havoc with scripts. The command and associated prompt are shown here:<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Windows\\system32&gt; Wevtutil.exe sl $wmiLog \/e:true<\/p>\n<p style=\"padding-left: 30px\">**** Warning: Enabling this type of log clears it.&nbsp; Do you want to enable and<\/p>\n<p style=\"padding-left: 30px\">clear this log? [y\/n]:&nbsp;<\/p>\n<p>By using the <b>echo<\/b> command (<b>echo<\/b> is an alias for the <b>Write-Output<\/b> cmdlet) and piping the results to the <b>wevtutil<\/b><i> <\/i>command, I am able to respond to the prompt and to allow script execution to continue. This powerful technique permits the use of literally hundreds of legacy commands (these types of techniques and the importance of being able to use currently available legacy commands are the reason I invited Sean to write his <a href=\"http:\/\/blogs.technet.com\/search\/searchresults.aspx?q=Legacy&amp;sections=7618\">Interact with the Legacy series of articles<\/a>. The command <b><a href=\"http:\/\/technet.microsoft.com\/en-us\/magazine\/dd310329.aspx?pr=blog\">wevtutil<\/a><\/b><i> <\/i>is extremely powerful and it is used to perform many more tasks than simply enabling or disabling event trace logs. The <b>sl<\/b><i> <\/i>command is the <b>set log<\/b> command from <b>wevtutil<\/b>, and it does not have anything to do with an alias for the <b>Set-Location<\/b> cmdlet. It is important to note that in this context, Windows PowerShell is smart enough to distinguish the two, and is not expecting an alias to appear here. This fact greatly simplifies the syntax because if Windows PowerShell were not so smart, I would be required to encase the command inside quotation marks and have to invoke the expression. Or I might be required to escape the <b>sl<\/b><i>. <\/i>The next thing that is pretty cool is the command is smart enough to interpret the value stored in the <b>$wmiLog<\/b> variable. This makes it easy to work with the command, and to automate it via Windows PowerShell.<\/p>\n<p>On the next line in the script, I use the <b>Invoke-WmiMethod<\/b> cmdlet to call the <b>install<\/b><i> <\/i>method from the <b>Win32_Product<\/b> WMI class. In general, I like to use the WMI class accelerator (<b>[wmiclass]<\/b>), but using the <b>Invoke-WmiMethod<\/b> cmdlet makes configuring advanced WMI options (such as using packet privacy, Kerberos authentication, and impersonation levels) much easier. The big problem with using the <b>Invoke-WmiMethod<\/b> cmdlet is the lack of useful examples. Even using the <i>online <\/i>switch from help (<b>help Invoke-WmiMethod &ndash;online<\/b>), does not unearth much additional detail. Most Windows PowerShell books simply repeat the same example from the online content.<\/p>\n<p>There are several things to realize about using the <b>Invoke-WmiMethod<\/b> cmdlet. First, help states that the <i>class<\/i> parameter is used when calling a static method. This does not mean the method is discovered using the <i>static <\/i>switch from the <b>Get-Member<\/b> cmdlet, but rather that the method is not an instance method from WMI. An instance method from WMI is a method that is available from an instance of the class. For example, if I want to terminate a process, I have to use WMI to connect to a specific instance of a process. I cannot terminate a process without connecting to it first. By a similar token, if I want to uninstall software, I need to connect to an instance of the <b>Win32_Product<\/b> class. However, to install the software package, I do not connect to an instance (because <b>Win32_Product<\/b> represents installed software); instead, I use a static method from the class itself. Instance methods and static methods are detailed on MSDN. (By the way, if I want to use the Invoke-WmiMethod cmdlet to work with an instance method, I must provide the path to a specific instance of the class, which would generally involve using the key to the class. It does get complicated).<\/p>\n<p>The name of the method is simple. It is the name of the method. I used a backtick (<b>`<\/b>) character for line continuation in the output. The command gets really long, and can be difficult to read. (When troubleshooting a command, the first thing I do is remove all backtick characters and place the command on a single line.)<\/p>\n<p>The arguments are the next hurdle and are the most difficult portion of working with the command. The <i>argumentlist<\/i> parameter requires an array of arguments. I added the <b>@()<\/b> to force evaluation as an array, but it probably is not required. I think it does make the command a bit easier to understand. The thing that is really weird is that the <a href=\"http:\/\/technet.microsoft.com\/en-us\/library\/dd315300.aspx\"><i>ArgumentList <\/i>parameter<\/a> is <i>supposed to<\/i> accept arguments in the order required by the method. The order for <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/aa390890(v=VS.85).aspx\">Win32_Product <b>install<\/b><i> <\/i>method<\/a> is package location, options, and all users. This is even confirmed by using the <b>Get-Member<\/b> cmdlet as seen here.<\/p>\n<p style=\"padding-left: 30px\">PS C:\\Windows\\system32&gt; [wmiclass]&#8221;Win32_product&#8221; | gm install<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; TypeName: System.Management.ManagementClass#ROOT\\cimv2\\Win32_Product<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Name&nbsp;&nbsp;&nbsp; MemberType Definition&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&#8212;-&nbsp;&nbsp;&nbsp; &#8212;&#8212;&#8212;- &#8212;&#8212;&#8212;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Install Method&nbsp;&nbsp;&nbsp;&nbsp; System.Management.ManagementBaseObject Install(System.String PackageLocation, System.String Options, System.Boolean AllUsers)&nbsp;<\/p>\n<p>Unfortunately, when using the <b>Invoke-WmiMethod<\/b> cmdlet, I had to supply the arguments as <b>AllUsers<\/b>, <b>Options<\/b>, and finally <b>PackageLocation<\/b>.<\/p>\n<p style=\"padding-left: 30px\">Invoke-WmiMethod -class win32_product -Name install `<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp; &nbsp;-ArgumentList @($true, $null, &#8220;\\\\hyperv1\\data\\HelloWorld.msi&#8221;)&nbsp;<\/p>\n<p>After the software package installs, I use the <b>wevtutil<\/b><i> <\/i>utility to disable the trace logging. As a last step, I use the <b>Get-WinEvent<\/b> cmdlet to display information from the newly created event log. The command to disable logging is essentially the same command to enable logging. The only change is to set the value of <b>\/e<\/b> (for enable log) to <b>false<\/b>.<\/p>\n<p style=\"padding-left: 30px\">echo y | Wevtutil.exe sl $wmiLog \/e:false<\/p>\n<p style=\"padding-left: 30px\">Get-WinEvent -LogName $wmiLog -Oldest<\/p>\n<p>When I run the script, the return code from the <b>install<\/b> method is shown, followed by the newly created trace log entries. The script and associated output are shown in the following figure.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6011.hsg-7-14-11-1.png\"><img decoding=\"async\" style=\"border: 0px\" title=\"Image of script and associated output\" alt=\"Image of script and associated output\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6011.hsg-7-14-11-1.png\" \/><\/a><\/p>\n<p>AS, that is all there is to using automating logging. Troubleshooting Windows Week will continue tomorrow.<\/p>\n<p>&nbsp;<\/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><strong>Ed Wilson, Microsoft Scripting Guy<\/strong>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Use Windows PowerShell to automatically enable and disable trace logs. &nbsp; Hey, Scripting Guy! Your articles have been right on target&mdash;they hit me where I live. I am wondering if I could actually automate some of this? Suppose I am trying to install software using WMI, and I would like to see the log [&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":[97,98,3,4,134,45,6],"class_list":["post-13321","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-event-logs","tag-logs-and-monitoring","tag-scripting-guy","tag-scripting-techniques","tag-troubleshooting","tag-windows-powershell","tag-wmi"],"acf":[],"blog_post_summary":"<p>Summary: Use Windows PowerShell to automatically enable and disable trace logs. &nbsp; Hey, Scripting Guy! Your articles have been right on target&mdash;they hit me where I live. I am wondering if I could actually automate some of this? Suppose I am trying to install software using WMI, and I would like to see the log [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/13321","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=13321"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/13321\/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=13321"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=13321"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=13321"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}