{"id":54823,"date":"2008-11-25T11:26:00","date_gmt":"2008-11-25T11:26:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2008\/11\/25\/hey-scripting-guy-how-can-i-determine-the-average-process-utilization-for-my-computer\/"},"modified":"2008-11-25T11:26:00","modified_gmt":"2008-11-25T11:26:00","slug":"hey-scripting-guy-how-can-i-determine-the-average-process-utilization-for-my-computer","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-determine-the-average-process-utilization-for-my-computer\/","title":{"rendered":"Hey, Scripting Guy! How Can I Determine the Average Process Utilization for My Computer?"},"content":{"rendered":"<h2><img decoding=\"async\" height=\"34\" width=\"34\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" align=\"left\" alt=\"Hey, Scripting Guy! Question\" border=\"0\" title=\"Hey, Scripting Guy! Question\" class=\"nearGraphic\" \/> <\/h2>\n<p>I would like to determine the average processor utilization for my computer over a certain period of time. If I could run this remotely, it would be even better. Can this be done?<\/p>\n<p>&#8211; MP<\/p>\n<p><img decoding=\"async\" height=\"5\" width=\"5\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" alt=\"Spacer\" border=\"0\" \/><img decoding=\"async\" height=\"34\" width=\"34\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" align=\"left\" alt=\"Hey, Scripting Guy! Answer\" border=\"0\" title=\"Hey, Scripting Guy! Answer\" class=\"nearGraphic\" \/><\/p>\n<p>Hi MP,<\/p>\n<p>We can certainly do this. In fact, it can be done both locally and remotely. But you do need to be careful of the <a target=\"_blank\" href=\"http:\/\/en.wikipedia.org\/wiki\/Uncertainty_principle\">Heisenberg uncertainty principle<\/a>.<\/p>\n<p>There are a couple of ways we can query for performance information. We can use the <b>Get-WmiObject<\/b> cmdlet, which is very easy to use and understand. We can also use the <b>System.Management.Management<\/b> .NET Framework class directly. This is perhaps a bit easier to do than it might seem because of the existence of the <b>[WMI]<\/b> type accelerator. Before choosing our approach, let&#8217;s examine each potential solution to see which code is the best to use.<\/p>\n<p>For our test, let&#8217;s obtain the total processor utilization time for the first CPU in our machine. Let&#8217;s print this value out ten times. This command is one logical command and uses the line continuation character at the end of the first line to allow for multiline entry. This command uses the <b>[WMI]<\/b> type accelerator. The command begins by using a <b>for<\/b> statement that begins counting at 1, continues until the value of <b>$i<\/b> is less than or equal to 10, and increments the value of <b>$i<\/b> by one. The code block, which is demarked by the curly brackets, uses the <b>[WMI]<\/b> type accelerator to return a specific instance of the <b>Win32_PerfFormattedData_PerfOS_Processor<\/b> WMI class. These instances are seen in the <a target=\"_blank\" href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/resources\/guiguy\/wbemtest.mspx\">WbemTest tool<\/a> when you choose the <b>instances<\/b> button from the <b>class<\/b> page:<\/p>\n<p><img decoding=\"async\" height=\"285\" width=\"450\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/hey1125\/hsg_perf2_01.jpg\" alt=\"Image of instances of the Win32_PerfFormattedData_PerfOS_Processor WMI class\" border=\"0\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>You will notice that each instance is referenced by the name of the class, the <b>name<\/b> property, and then a value for the <b>name<\/b> property. The <b>name<\/b> property is the <b>key<\/b> property for the <b>Win32_PerfFormattedData_PerfOS_Processor<\/b> WMI class. When you are using the <b>[WMI]<\/b> type accelerator, you always need to give it a value for the <b>key<\/b> property of the class. This process of using the <b>[WMI]<\/b> type accelerator to connect to a specific instance of a class is similar to the VBScript <b>Get<\/b> method. The <b>Get<\/b> method of the <b>sWbemServices<\/b> object is talked about <a target=\"_blank\" href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/guide\/sas_wmi_srzu.mspx?mfr=true\">on this page<\/a>. After we have the specific instance of the <b>Win32_PerfFormattedData_PerfOS_Processor<\/b> WMI class, we can return the <b>percentProcessorTime<\/b> property&nbsp;value:<\/p>\n<pre class=\"codeSample\">for($i = 1 ; $i -le 10 ; $i++) `\n{ \n ([wmi]\"Win32_PerfFormattedData_PerfOS_Processor.name='0'\").percentProcessorTime\n}\n<\/pre>\n<p>When it is run, it prints out the current processor utilization 10 different times.<\/p>\n<p>If you were to use <b>Get-WmiObject<\/b> , the code would be very similar in concept. The <b>Get-WmiObject<\/b> cmdlet takes the <b>&ndash;class<\/b> parameter, which allows it to query a specific WMI class. This is similar to using the <b>ExecQuery<\/b> method from the <b>sWbemServices<\/b> object. The <b>ExecQuery<\/b> method is <a target=\"_blank\" href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/guide\/sas_wmi_srzu.mspx?mfr=true\">documented here<\/a>. To keep the cmdlet from returning information from all the processors, the <b>&ndash;filter<\/b> parameter is used to limit the amount of information that is returned. This is similar to using a <b>where<\/b> clause in a <a target=\"_blank\" href=\"http:\/\/www.microsoft.com\/technet\/scriptcenter\/guide\/sas_wmi_jehv.mspx?mfr=true\">VBScript WMI query<\/a>. Because only one instance of the class is returned, we can also use the dotted notation to retrieve a specific property from the object. This code is shown here:<\/p>\n<pre class=\"codeSample\">for($i = 1 ; $i -le 10 ; $i++) `\n{ \n (Get-WmiObject -class Win32_PerfFormattedData_PerfOS_Processor &ndash;filter \"name='0'\").percentProcessorTime \n}\n<\/pre>\n<p>If we use the <b>measure-command<\/b> cmdlet to see if one approach is faster than the other, we would see that both commands take approximately five seconds to execute. There is no appreciable difference in the performance of the two commands. So the choice is the syntax with which you are the most familiar. <\/p>\n<p>So here it is, the <b>GetWmiPerformanceData.ps1<\/b> script.<\/p>\n<pre class=\"codeSample\">Function GetWmiPerformanceData()\n{\n For($i = 1 ; $i -le $reps ; $i++)\n  {\n   ([wmi]\"\\\\$computer\\root\\cimv2:$class.$key='$instance'\").$Property\n   Start-Sleep -Seconds $delay\n  } #end for\n}#end GetWmiPerformanceData\n\n$computer = \"vista\"\n$delay = 1\n$reps = 2\n$class = \"Win32_PerfFormattedData_PerfOS_Processor\"\n$key = \"name\"\n$instance = \"_Total\"\n$property = \"PercentProcessorTime\"\n\nGetWmiPerformanceData\n<\/pre>\n<p>The <b>GetWmiPerformanceData.ps1<\/b> script begins by declaring a function that is named <b>GetWmiPerformanceData<\/b>. This function is used to query the WMI class a certain number of times, and to return a specific property from a specific instance on a specific computer. The cool thing about the function is that everything is abstracted. This follows the <a target=\"_blank\" href=\"http:\/\/en.wikipedia.org\/wiki\/Prime_Directive\">prime directive<\/a> for scripting which means do not mess with the worker section of the script. The four parts of a script are detailed in the <a target=\"_blank\" href=\"http:\/\/www.microsoft.com\/mspress\/books\/authors\/auth9543.aspx\">Microsoft VBScript Step by Step<\/a> book. The <b>for<\/b> statement begins with the value of <b>$i<\/b> equal to 1, and continues until it is less than or equal the value set in the variable <b>$reps<\/b>. It is incremented by one on each loop. This is seen here:<\/p>\n<pre class=\"codeSample\">For($i = 1 ; $i -le $reps ; $i++)<\/pre>\n<p>Inside the code block, the <b>[WMI]<\/b> type accelerator is used to connect to the <b>root\\cimv2<\/b> WMI namespace on the computer that is specified in the <b>$computer<\/b> variable. The WMI class that will be queried is stored in the <b>$class<\/b> variable and the <b>key<\/b> property name is in the <b>$key<\/b> variable. The particular instance to return is defined in the <b>$instance<\/b> variable, and the property we are interested in is stored in the <b>$property<\/b> variable. Although this particular syntax is a bit complicated, the fact that it is stored in a function with everything abstracted into a variable means it can be used over again without requiring any changes. This line of code is shown here:<\/p>\n<pre class=\"codeSample\">([wmi]\"\\\\$computer\\root\\cimv2:$class.$key='$instance'\").$Property<\/pre>\n<p>Because you might want to pause the script between polling cycles, the <b>start-sleep<\/b> cmdlet is used to halt script execution. The specified time is supplied in seconds, although milliseconds could have been used. This line of code is shown here:<\/p>\n<pre class=\"codeSample\">Start-Sleep -Seconds $delay<\/pre>\n<p>The bulk of the script is supplying values for the variables. The <b>computer<\/b> variable holds the name of the computer to query. This could be a local or a remote computer. The <b>$delay<\/b> variable controls the time between polling, and the <b>$reps<\/b> variable controls how many times the script will poll. The <b>$class<\/b> variable holds a WMI <b>performance counter<\/b> class, and the <b>$key<\/b> variable holds the <b>key<\/b> property for the class. Note that this script will not work on a WMI class that contains a composite key (more than one key property). The <b>$instance<\/b> variable is used to supply the name of the particular instance to query. This is seen&nbsp;is seen here:<\/p>\n<pre class=\"codeSample\">$computer = \"vista\"\n$delay = 1\n$reps = 2\n$class = \"Win32_PerfFormattedData_PerfOS_Processor\"\n$key = \"name\"\n$instance = \"_Total\"\n$property = \"PercentProcessorTime\"\n<\/pre>\n<p>Once all the variables have been supplied values, the last thing to do is to actually call the function. This is easily done by simply placing the function name on a line by itself as seen here:<\/p>\n<pre class=\"codeSample\">GetWmiPerformanceData<\/pre>\n<p>When we run the script, the results are not all that impressive. It is just a list of numbers displayed on the console.<\/p>\n<p>MP, this should move you closer to using the WMI <b>performance counter<\/b> classes. Tomorrow, we will see what we can do about processing the numbers that are written to the screen. See ya!<\/p>\n<p><span class=\"Apple-style-span\" style=\"font-family: Verdana;font-size: small\"><span class=\"Apple-style-span\"><b><b>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/b><\/b><\/span><\/span><\/p>\n<p><span class=\"Apple-style-span\" style=\"font-family: Verdana;font-size: small\"><b><\/b><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I would like to determine the average processor utilization for my computer over a certain period of time. If I could run this remotely, it would be even better. Can this be done? &#8211; MP Hi MP, We can certainly do this. In fact, it can be done both locally and remotely. But you do [&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":[31,60,3,45],"class_list":["post-54823","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-operating-system","tag-performance","tag-scripting-guy","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>I would like to determine the average processor utilization for my computer over a certain period of time. If I could run this remotely, it would be even better. Can this be done? &#8211; MP Hi MP, We can certainly do this. In fact, it can be done both locally and remotely. But you do [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/54823","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=54823"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/54823\/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=54823"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=54823"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=54823"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}