{"id":54813,"date":"2008-11-26T11:28:00","date_gmt":"2008-11-26T11:28:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2008\/11\/26\/hey-scripting-guy-how-can-i-collect-processor-information\/"},"modified":"2008-11-26T11:28:00","modified_gmt":"2008-11-26T11:28:00","slug":"hey-scripting-guy-how-can-i-collect-processor-information","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/hey-scripting-guy-how-can-i-collect-processor-information\/","title":{"rendered":"Hey, Scripting Guy! How Can I Collect Processor Information?"},"content":{"rendered":"<h2><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Question\" height=\"34\" alt=\"Hey, Scripting Guy! Question\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\" \/> <\/h2>\n<p>Hey, Scripting Guy! I am interested in using Windows PowerShell to collect processor information, but I do not need to see the raw data. I would rather see calculated results such as the maximum, minimum, and average processor utilization. I know I can do this, but that seems like writing a lot of math formulas, and I just am not in the mood for all that work. Will you do it for me?<\/p>\n<p>&#8211; LA<\/p>\n<p><img decoding=\"async\" height=\"5\" alt=\"Spacer\" src=\"https:\/\/devblogs.microsoft.com\/scripting\/wp-content\/uploads\/sites\/29\/2019\/05\/spacer.gif\" width=\"5\" border=\"0\" \/><img decoding=\"async\" class=\"nearGraphic\" title=\"Hey, Scripting Guy! Answer\" height=\"34\" alt=\"Hey, Scripting Guy! Answer\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" width=\"34\" align=\"left\" border=\"0\" \/> <\/p>\n<p>Hi LA,<\/p>\n<p>Guess what? It is late at night on a Friday night (as I am writing this), I am sipping a nice cup of green tea with lemon and a cinnamon stick in it, munching on some raw almonds, savoring a nice hunk of <a href=\"http:\/\/en.wikipedia.org\/wiki\/Artisan_cheese\" target=\"_blank\">artisan cheese<\/a>, and I am listening to <a href=\"http:\/\/en.wikipedia.org\/wiki\/Harry_James\" target=\"_blank\">Harry James<\/a> on my Zune. I am not in the mood for a bunch of math formulas either. Luckily for both of us, Windows PowerShell has the <b>Measure-Object<\/b> cmdlet that will do the calculations for us. Because it is nearly the weekend, I will throw in a progress indicator for free. Without much ado (or <a href=\"http:\/\/en.wikipedia.org\/wiki\/Scrappy-Doo\" target=\"_blank\">Scrappy-Doo<\/a>) here is the <b>CalculateAverageUtilization.ps1<\/b>&nbsp;script:<\/p>\n<pre class=\"codeSample\">Function CreateEmptyArray($ubound)\n{\n [int[]]$script:aryProp = [array]::CreateInstance(\"int\",$ubound)\n} #end CreateEmptyArray\nFunction GetWmiPerformanceData()\n{\n For($i = 0 ; $i -le $reps -1 ; $i++)\n  {\n   $aryProp[$i] +=([wmi]\"\\\\$computer\\root\\cimv2:$class.$key='$instance'\").$Property\n   Write-Progress -Activity \"Obtaining Processor info\" -Status \"% complete: \" `\n   -PercentComplete $i\n   Start-Sleep -Seconds $delay\n  } #end for\n}#end GetWmiPerformanceData\nFunction EvaluateObject()\n{\n $aryProp | \n Measure-Object -Average -Maximum -Minimum |\n Format-Table -Property `\n  @{ Label = \"Data Points\" ; Expression = {$_.count} }, \n  average, Maximum, Minimum -autosize\n} #End EvaluateObject\n# *** Entry Point ***\n$computer = \".\"\n$delay = 1\n$reps = 10\n$class = \"Win32_PerfFormattedData_PerfOS_Processor\"\n$key = \"name\"\n$instance = \"_Total\"\n$property = \"PercentProcessorTime\"\nCreateEmptyArray($reps)\nGetWmiPerformanceData\nEvaluateObject\n<\/pre>\n<p>The main body of the script consists of three separate functions. The first function that is called creates an empty array of integers and assigns it to a script level variable named <b>$aryProp<\/b>. The second function called gathers the WMI performance information and writes it to the <b>$aryProp<\/b> variable. The last function evaluates the information in the <b>$aryProp<\/b> variable and generates the output. It is a best practice to order the functions in a script in the order in which they will be called. While this is not always possible, it is still a worthy goal because it will make the script easier to read.<\/p>\n<p>The <b>CreateEmptyArray<\/b> function creates an empty array that will be used to store the processor utilization information. When it is called, the value that is stored in the <b>$reps<\/b> variable is passed to it. This value becomes the upper boundary of the array. To create the array we use the static <b>CreateInstance<\/b> method from the <b>system.array<\/b> .NET Framework class. When we use the <b>CreateInstance<\/b> method, we need to give it the type of data it will hold and the upper boundary of the array. We store the empty array in a script-level variable named <b>$aryProp<\/b>. A script-level variable will be available for use outside of the function. We use the <b>[int[]]<\/b> type constraint to make sure the variable will only hold an array of integers. The <b>CreateEmptyArray<\/b> function is seen here:<\/p>\n<pre class=\"codeSample\">Function CreateEmptyArray($ubound)\n{\n [int[]]$script:aryProp = [array]::CreateInstance(\"int\",$ubound)\n} #end CreateEmptyArray\n<\/pre>\n<p>The <b>GetWmiPerformanceData<\/b> function is the main function in the script. It begins with a <b>for<\/b> loop that starts counting at 0 until it is one minus the number stored in the <b>$reps<\/b> variable. The <b>for<\/b> loop increments the enumerator by one. The <b>$i<\/b> variable is used to not only control the number of repetitions through the code block, but also the element the data point gets stored in. The <b>$i++<\/b> syntax increments the <b>$i<\/b> enumerator by one\u2014this is the same as <b>$i = $i +1<\/b>. This section of the code is shown here:<\/p>\n<pre class=\"codeSample\">For($i = 0 ; $i -le $reps -1 ; $i++)<\/pre>\n<p>Inside the code block, the <b>[WMI]<\/b> type accelerator is used to make a connection to the computer specified in the <b>$computer<\/b> variable to the class that is stored in the <b>$class<\/b> variable. The <b>$key<\/b> and <b>$instance<\/b> variables are used to connect to the key property of a specific instance of the WMI performance class. The property stored in the <b>$property<\/b> variable is the data point we are interested in obtaining. When the data is retrieved, it is stored in the element number <b>$i<\/b> in the array <b>$aryProp<\/b>. This line of code is seen here:<\/p>\n<pre class=\"codeSample\">$aryProp[$i] +=([wmi]\"\\\\$computer\\root\\cimv2:$class.$key='$instance'\").$Property<\/pre>\n<p>Because it is conceivable that the script could run for an extended period of time, the <b>Write-Progress<\/b> cmdlet is used to display a progress indicator bar:<\/p>\n<p><img decoding=\"async\" height=\"321\" alt=\"Image of the progress indicator bar\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/hey1126\/hsg_perf3_01.jpg\" width=\"450\" border=\"0\" \/> <\/p>\n<p>&nbsp;<\/p>\n<p>The top line displays the value that is specified in the <b>\u2013Activity<\/b> parameter. In this script, it states &#8220;Obtaining processor info.&#8221; The next line that is displayed is the data you supply for the <b>e-Status<\/b> parameter. Here it says &#8220;% complete:&#8221; followed by a progress bar that indicates the percent complete of the value <b>$i<\/b>. This section of code is shownhere:<\/p>\n<pre class=\"codeSample\">   Write-Progress -Activity \"Obtaining Processor info\" -Status \"% complete: \" `\n   -PercentComplete $i\n<\/pre>\n<p>The last thing we do is pause the execution of the script for a short period of time that is specified by the <b>$delay<\/b> value. To do this, we use the <b>Start-Sleep<\/b> cmdlet, which is similar to the VBScript command <b>Wscript.Sleep<\/b> except that it will take both seconds and milliseconds for the pause interval. The default parameter is seconds, and therefore the <b>\u2013seconds<\/b> parameter does not need to be specified. However, as a best practice I recommend including the full parameter name because it will improve the readability of the script. This is doubly important because the interval used for <b>Wscript.Sleep<\/b> was milliseconds, and confusion could easily arise with the missing parameter. This section of code is shown here:<\/p>\n<pre class=\"codeSample\">Start-Sleep -Seconds $delay<\/pre>\n<p>The complete <b>GetWmiPerformanceData<\/b> function is seen&nbsp;here:<\/p>\n<pre class=\"codeSample\">Function GetWmiPerformanceData()\n{\n For($i = 0 ; $i -le $reps -1 ; $i++)\n  {\n   $aryProp[$i] +=([wmi]\"\\\\$computer\\root\\cimv2:$class.$key='$instance'\").$Property\n   Write-Progress -Activity \"Obtaining Processor info\" -Status \"% complete: \" `\n   -PercentComplete $i\n   Start-Sleep -Seconds $delay\n  } #end for\n}#end GetWmiPerformanceData\n<\/pre>\n<p>The last function to look at is the <b>EvaluateObject<\/b> function. The <b>EvaluateObject<\/b> function begins by pipelining the data stored in the <b>$aryProp<\/b> variable to the <b>Measure-Object<\/b> cmdlet where we specify that we are interested in the <b>\u2013Average<\/b>, <b>\u2013Maximum<\/b>, and the <b>\u2013Minimum<\/b> values contained in the <b>$aryProp<\/b> variable. We then pipeline the results of that calculation to the <b>Format-Table<\/b> to display a table of the results. Because the <b>count<\/b> property that is reported by the <b>Measure-Object<\/b> cmdlet is a bit obtuse, we decide to create a custom label named &#8220;Data Points.&#8221; To do this, we need to use a special hash table format. <\/p>\n<p>The first element in the hash table is called <b>Label<\/b>, and the value of the label element is &#8220;Data Points.&#8221; The second element in the hash table is named <b>Expression<\/b> and the value of the expression element is <b>$_.count<\/b>. The <b>$_<\/b> variable is an automatic variable that represents the current item on the pipeline\u2014in this case, the object coming across from the <b>Measure-Object<\/b> cmdlet. We are interested in the <b>count<\/b> property. We then choose the remaining properties from the <b>Measure-Object<\/b> cmdlet that we are interested in displaying: <b>average<\/b>, <b>maximum<\/b>, and <b>minimum<\/b>. We use the <b>\u2013autosize<\/b> parameter from <b>Format-Table<\/b> cmdlet to shrink the display to a more space-conscious output of the data: <\/p>\n<p><img decoding=\"async\" height=\"321\" alt=\"Image of a space-conscious output of the data\" src=\"http:\/\/img.microsoft.com\/library\/media\/1033\/technet\/images\/scriptcenter\/qanda\/hsg\/hey1126\/hsg_perf3_02.jpg\" width=\"450\" border=\"0\" \/> <\/p>\n<p>&nbsp;<\/p>\n<p>here:<\/p>\n<pre class=\"codeSample\">Function EvaluateObject()\n{\n $aryProp | \n Measure-Object -Average -Maximum -Minimum |\n Format-Table -Property `\n  @{ Label = \"Data Points\" ; Expression = {$_.count} }, \n  average, Maximum, Minimum -autosize\n} #End EvaluateObject\n<\/pre>\n<p>The only thing left in the script is to declare the values for the variables and call the functions. This is seen&nbsp;here:<\/p>\n<pre class=\"codeSample\">$computer = \".\"\n$delay = 1\n$reps = 10\n$class = \"Win32_PerfFormattedData_PerfOS_Processor\"\n$key = \"name\"\n$instance = \"_Total\"\n$property = \"PercentProcessorTime\"\n\nCreateEmptyArray($reps)\nGetWmiPerformanceData\nEvaluateObject\n<\/pre>\n<p>See, LA, neither of us needed to do any math calculations thanks to the <b>Measure-Object<\/b> cmdlet. Now that we are done, it\u2019s time for more tea.<\/p>\n<p><font class=\"Apple-style-span\" face=\"Verdana\" size=\"3\"><span class=\"Apple-style-span\"><b><b>Ed Wilson and Craig Liebendorfer, Scripting Guys<\/b><\/b><\/span><\/font><\/p>\n<p><font class=\"Apple-style-span\" face=\"Verdana\" size=\"3\"><b><\/b><\/font><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, Scripting Guy! I am interested in using Windows PowerShell to collect processor information, but I do not need to see the raw data. I would rather see calculated results such as the maximum, minimum, and average processor utilization. I know I can do this, but that seems like writing a lot of math formulas, [&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":[34,41,31,60,3,45],"class_list":["post-54813","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-hardware","tag-monitoring","tag-operating-system","tag-performance","tag-scripting-guy","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Hey, Scripting Guy! I am interested in using Windows PowerShell to collect processor information, but I do not need to see the raw data. I would rather see calculated results such as the maximum, minimum, and average processor utilization. I know I can do this, but that seems like writing a lot of math formulas, [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/54813","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=54813"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/54813\/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=54813"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=54813"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=54813"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}