{"id":2434,"date":"2012-07-05T14:01:48","date_gmt":"2012-07-05T18:01:48","guid":{"rendered":"http:\/\/jdhitsolutions.com\/blog\/?p=2434"},"modified":"2013-08-09T08:44:32","modified_gmt":"2013-08-09T12:44:32","slug":"powershell-pivot-tables","status":"publish","type":"post","link":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2434\/powershell-pivot-tables\/","title":{"rendered":"PowerShell Pivot Tables"},"content":{"rendered":"<p><a href=\"http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/07\/keyboardanalyze.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/07\/keyboardanalyze-150x150.png\" alt=\"\" title=\"keyboardanalyze\" width=\"150\" height=\"150\" class=\"alignleft size-thumbnail wp-image-2436\" \/><\/a>I was working on a question in the <a href=\"http:\/\/bit.ly\/AskJeffHicks\" title=\"Ask Don and Jeff a PowerShell Question\" target=\"_blank\">Ask Don and Jeff<\/a> forum about multidimensional arrays. The ultimate goal of sorts was to create an HTML report that contained in essence a pivot table. This device allows you to slice and dice data so that you can identify trends or patterns. In PowerShell, there aren't too many tools that allow you to \"re-organize\" an object. For example, say you have a variable that contains the results of querying a few computers for some critical services. But you want a table that shows you the computername as the Y-Axis and each service name as the header on the X axis. For each computer, the intersection should be the status of said property. In other words, a result like this:<\/p>\n<pre class=\"lang:batch decode:true \" >\r\nComputername Lanmanserver Wuauserv    Bits Spooler Audiosrv\r\n------------ ------------ --------    ---- ------- --------\r\nserenity          Running  Running Running Running  Running\r\nquark                      Stopped Running Running  Running\r\njdhit-dc01        Running  Running Running Stopped         \r\n<\/pre>\n<p>At a glance I can see where there might be problems. Blanks indicate the service doesn't exist on that computer. In this case, you might be able to get similar results with some grouping and Format-Table tricks. But more than likely you wouldn't have something you could export to XML or convert to HTML.<br \/>\nOr say you have a directory listing for a handful of file extensions and you want to see a count of each extension for each folder, perhaps something like this:<\/p>\n<pre class=\"lang:batch decode:true \" >\r\nDirectory                                        .ZIP .BAT .PS1 .TXT\r\n---------                                        ---- ---- ---- ----\r\nC:\\scripts\\AD-Old\\New                               0    0    1    1\r\nC:\\scripts\\AD-Old                                   1    0   82    1\r\nC:\\scripts\\ADTFM-Scripts\\LocalUsersGroups           0    0    8    0\r\nC:\\scripts\\ADTFM-Scripts                            0    0   55    3\r\nC:\\scripts\\en-US                                    0    0    1    0\r\nC:\\scripts\\GPAE                                     0    0    8    3\r\nC:\\scripts\\modhelp                                  1    0    0    0\r\nC:\\scripts\\PowerShellBingo                          0    0    4    0\r\nC:\\scripts\\PS-TFM                                   1    0   69    2\r\nC:\\scripts\\PSVirtualBox                             0    0    0    1\r\nC:\\scripts\\quark                                    0    0    0    1\r\nC:\\scripts\\TechEd2012                               1    0   11    3\r\nC:\\scripts\\Toolmaking\\old                           0    0   10    0\r\nC:\\scripts\\Toolmaking                               0    0   48    0\r\nC:\\scripts                                         55   13 1133  305\r\n<\/pre>\n<p>That last row is not a sum, but rather the count of each of those file types in the root of C:\\Scripts.  I did all of this with a function I call New-PSPivotTable.<\/p>\n<pre class=\"lang:ps decode:true \" >\r\nFunction New-PSPivotTable {\r\n\r\n# comment based help omitted here \r\n\r\n[cmdletbinding(DefaultParameterSetName=\"Property\")]\r\n\r\nParam(\r\n[Parameter(Position=0,Mandatory=$True)]\r\n[object]$Inputobject,\r\n[Parameter()]\r\n[String]$yLabel,\r\n[Parameter(Mandatory=$True)]\r\n[String]$yProperty,\r\n[Parameter(Mandatory=$True)]\r\n[string]$xLabel,\r\n[Parameter(ParameterSetName=\"Property\")]\r\n[string]$xProperty,\r\n[Parameter(ParameterSetName=\"Count\")]\r\n[switch]$Count,\r\n[Parameter(ParameterSetName=\"Sum\")]\r\n[string]$Sum,\r\n[Parameter(ParameterSetName=\"Sum\")]\r\n[ValidateSet(\"None\",\"KB\",\"MB\",\"GB\",\"TB\")]\r\n[string]$Format=\"None\",\r\n[Parameter(ParameterSetName=\"Sum\")]\r\n[ValidateScript({$_ -gt 0})]\r\n[int]$Round\r\n)\r\n\r\nBegin {\r\n    Write-Verbose \"Starting $($myinvocation.mycommand)\"\r\n    $Activity=\"PS Pivot Table\"\r\n    $status=\"Creating new table\"\r\n    Write-Progress -Activity $Activity -Status $Status\r\n    #initialize an array to hold results\r\n    $result=@()\r\n    #if no yLabel then use yProperty name\r\n    if (-Not $yLabel) {\r\n        $yLabel=$yProperty\r\n    }\r\n    Write-Verbose \"Vertical axis label is $ylabel\"\r\n}\r\nProcess {    \r\n    Write-Progress -Activity $Activity -status \"Pre-Processing\"\r\n    if ($Count -or $Sum) {\r\n        #create an array of all unique property names so that if one isn't \r\n        #found we can set a value of 0\r\n        Write-Verbose \"Creating a unique list based on $xLabel\"\r\n        &lt;#\r\n          Filter out blanks. Uniqueness is case sensitive so we first do a \r\n          quick filtering with Select-Object, then turn each of them to upper\r\n          case and finally get unique uppercase items. \r\n        #&gt;\r\n        $unique=$inputobject | Where {$_.$xlabel} | \r\n         Select-Object -ExpandProperty $xLabel -unique | foreach {\r\n           $_.ToUpper()} | Select-Object -unique\r\n         \r\n        Write-Verbose ($unique -join  ',' | out-String).Trim()\r\n      \r\n    } \r\n    else {\r\n     Write-Verbose \"Processing $xLabel for $xProperty\"    \r\n    }\r\n    \r\n    Write-Verbose \"Grouping objects on $yProperty\"\r\n    Write-Progress -Activity $Activity -status \"Pre-Processing\" -CurrentOperation \"Grouping by $yProperty\"\r\n    $grouped=$Inputobject | Group -Property $yProperty\r\n    $status=\"Analyzing data\"  \r\n    $i=0\r\n    $groupcount=($grouped | measure).count\r\n    foreach ($item in $grouped ) {\r\n      Write-Verbose \"Item $($item.name)\"\r\n      $i++\r\n      #calculate what percentage is complete for Write-Progress\r\n      $percent=($i\/$groupcount)*100\r\n      Write-Progress -Activity $Activity -Status $Status -CurrentOperation $($item.Name) -PercentComplete $percent\r\n      $obj=new-object psobject -property @{$yLabel=$item.name}   \r\n      #process each group\r\n        #Calculate value depending on parameter set\r\n        Switch ($pscmdlet.parametersetname) {\r\n        \r\n        \"Property\" {\r\n                    &lt;#\r\n                      take each property name from the horizontal axis and make \r\n                      it a property name. Use the grouped property value as the \r\n                      new value\r\n                    #&gt;\r\n                     $item.group | foreach {\r\n                        $obj | Add-member Noteproperty -name \"$($_.$xLabel)\" -value $_.$xProperty\r\n                      } #foreach\r\n                    }\r\n        \"Count\"  {\r\n                    Write-Verbose \"Calculating count based on $xLabel\"\r\n                     $labelGroup=$item.group | Group-Object -Property $xLabel \r\n                     #find non-matching labels and set count to 0\r\n                     Write-Verbose \"Finding 0 count entries\"\r\n                     #make each name upper case\r\n                     $diff=$labelGroup | Select-Object -ExpandProperty Name -unique | \r\n                     Foreach { $_.ToUpper()} |Select-Object -unique\r\n                     \r\n                     #compare the master list of unique labels with what is in this group\r\n                     Compare-Object -ReferenceObject $Unique -DifferenceObject $diff | \r\n                     Select-Object -ExpandProperty inputobject | foreach {\r\n                        #add each item and set the value to 0\r\n                        Write-Verbose \"Setting $_ to 0\"\r\n                        $obj | Add-member Noteproperty -name $_ -value 0\r\n                     }\r\n                     \r\n                     Write-Verbose \"Counting entries\"\r\n                     $labelGroup | foreach {\r\n                        $n=($_.name).ToUpper()\r\n                        write-verbose $n\r\n                        $obj | Add-member Noteproperty -name $n -value $_.Count -force\r\n                    } #foreach\r\n                 }\r\n         \"Sum\"  {\r\n                    Write-Verbose \"Calculating sum based on $xLabel using $sum\"\r\n                    $labelGroup=$item.group | Group-Object -Property $xLabel \r\n                 \r\n                     #find non-matching labels and set count to 0\r\n                     Write-Verbose \"Finding 0 count entries\"\r\n                     #make each name upper case\r\n                     $diff=$labelGroup | Select-Object -ExpandProperty Name -unique | \r\n                     Foreach { $_.ToUpper()} |Select-Object -unique\r\n                     \r\n                     #compare the master list of unique labels with what is in this group\r\n                     Compare-Object -ReferenceObject $Unique -DifferenceObject $diff | \r\n                     Select-Object -ExpandProperty inputobject | foreach {\r\n                        #add each item and set the value to 0\r\n                        Write-Verbose \"Setting $_ sum to 0\"\r\n                        $obj | Add-member Noteproperty -name $_ -value 0\r\n                     }\r\n                     \r\n                     Write-Verbose \"Measuring entries\"\r\n                     $labelGroup | foreach {\r\n                        $n=($_.name).ToUpper()\r\n                        write-verbose \"Measuring $n\"\r\n                        \r\n                        $measure= $_.Group | Measure-Object -Property $Sum -sum\r\n                        if ($Format -eq \"None\") {\r\n                            $value=$measure.sum\r\n                        }\r\n                        else {\r\n                            Write-Verbose \"Formatting to $Format\"\r\n                             $value=$measure.sum\/\"1$Format\"\r\n                            }\r\n                        if ($Round) {\r\n                            Write-Verbose \"Rounding to $Round places\"\r\n                            $Value=[math]::Round($value,$round)\r\n                        }\r\n                        $obj | Add-member Noteproperty -name $n -value $value -force\r\n                    } #foreach\r\n                }        \r\n        } #switch\r\n\r\n        #add each object to the results array\r\n      $result+=$obj\r\n    } #foreach item\r\n} #process\r\nEnd {\r\n    Write-Verbose \"Writing results to the pipeline\"\r\n    $result\r\n    Write-Verbose \"Ending $($myinvocation.mycommand)\"\r\n    Write-Progress -Completed -Activity $Activity -Status \"Ending\"\r\n}\r\n} #end function<\/pre>\n<p>There is a lot going on here but I've tried to use comments and Write-Verbose statements to make it easier to track. In short, the function takes a collection of data and builds a table based on the property names and values you specify. You can build a table on a property like I did with the services. You can create a table based on count or on size. For the latter you need to also specify what property name to measure to calculate the size.<\/p>\n<p>The function is writing an object to the pipeline which means you can transform the output however you need it.<\/p>\n<pre class=\"lang:batch decode:true \" >\r\nPS C:\\> $files=dir c:\\scripts -include *.ps1,*.txt,*.zip,*.bat -recurse\r\nPS C:\\> $pivot=New-PSPivotTable $files -yProperty Directory -xlabel Extension -sum length -round 2 -format kb\r\nPS C:\\> $pivot[0] | format-table -auto\r\n\r\nDirectory             .ZIP .BAT .PS1 .TXT\r\n---------             ---- ---- ---- ----\r\nC:\\scripts\\AD-Old\\New    0    0 2.32 1.49\r\nPS C:\\> $pivot | convertto-html -Title \"Extension Pivot\" | out-file extpivot.htm\r\n<\/pre>\n<p>Honestly, I think the best thing is for you to download <a href='http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/07\/new-pspivottable.txt' target='_blank'>New-PSPivotTable<\/a> and try it out. The download has full help and examples which you should read. I really hope you find it useful and if you run into some scenarios where this doesn't work the way you think it should, please let me know.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I was working on a question in the Ask Don and Jeff forum about multidimensional arrays. The ultimate goal of sorts was to create an HTML report that contained in essence a pivot table. This device allows you to slice and dice data so that you can identify trends or patterns. In PowerShell, there aren&#8217;t&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[4,8],"tags":[224,342,534,540],"class_list":["post-2434","post","type-post","status-publish","format-standard","hentry","category-powershell","category-scripting","tag-function","tag-group-object","tag-powershell","tag-scripting"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>PowerShell Pivot Tables &#8226; The Lonely Administrator<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/jdhitsolutions.com\/blog\/powershell\/2434\/powershell-pivot-tables\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"PowerShell Pivot Tables &#8226; The Lonely Administrator\" \/>\n<meta property=\"og:description\" content=\"I was working on a question in the Ask Don and Jeff forum about multidimensional arrays. The ultimate goal of sorts was to create an HTML report that contained in essence a pivot table. This device allows you to slice and dice data so that you can identify trends or patterns. In PowerShell, there aren&#039;t...\" \/>\n<meta property=\"og:url\" content=\"https:\/\/jdhitsolutions.com\/blog\/powershell\/2434\/powershell-pivot-tables\/\" \/>\n<meta property=\"og:site_name\" content=\"The Lonely Administrator\" \/>\n<meta property=\"article:published_time\" content=\"2012-07-05T18:01:48+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2013-08-09T12:44:32+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/07\/keyboardanalyze-150x150.png\" \/>\n<meta name=\"author\" content=\"Jeffery Hicks\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@JeffHicks\" \/>\n<meta name=\"twitter:site\" content=\"@JeffHicks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jeffery Hicks\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2434\\\/powershell-pivot-tables\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2434\\\/powershell-pivot-tables\\\/\"},\"author\":{\"name\":\"Jeffery Hicks\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"headline\":\"PowerShell Pivot Tables\",\"datePublished\":\"2012-07-05T18:01:48+00:00\",\"dateModified\":\"2013-08-09T12:44:32+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2434\\\/powershell-pivot-tables\\\/\"},\"wordCount\":415,\"commentCount\":4,\"publisher\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2434\\\/powershell-pivot-tables\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2012\\\/07\\\/keyboardanalyze-150x150.png\",\"keywords\":[\"Function\",\"Group-Object\",\"PowerShell\",\"Scripting\"],\"articleSection\":[\"PowerShell\",\"Scripting\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2434\\\/powershell-pivot-tables\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2434\\\/powershell-pivot-tables\\\/\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2434\\\/powershell-pivot-tables\\\/\",\"name\":\"PowerShell Pivot Tables &#8226; The Lonely Administrator\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2434\\\/powershell-pivot-tables\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2434\\\/powershell-pivot-tables\\\/#primaryimage\"},\"thumbnailUrl\":\"http:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2012\\\/07\\\/keyboardanalyze-150x150.png\",\"datePublished\":\"2012-07-05T18:01:48+00:00\",\"dateModified\":\"2013-08-09T12:44:32+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2434\\\/powershell-pivot-tables\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2434\\\/powershell-pivot-tables\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2434\\\/powershell-pivot-tables\\\/#primaryimage\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2012\\\/07\\\/keyboardanalyze.png\",\"contentUrl\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/wp-content\\\/uploads\\\/2012\\\/07\\\/keyboardanalyze.png\",\"width\":\"643\",\"height\":\"458\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/powershell\\\/2434\\\/powershell-pivot-tables\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"PowerShell\",\"item\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/category\\\/powershell\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"PowerShell Pivot Tables\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/\",\"name\":\"The Lonely Administrator\",\"description\":\"Practical Advice for the Automating IT Pro\",\"publisher\":{\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/jdhitsolutions.com\\\/blog\\\/#\\\/schema\\\/person\\\/d0258030b41f07fd745f4078bdf5b6c9\",\"name\":\"Jeffery Hicks\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\",\"caption\":\"Jeffery Hicks\"},\"logo\":{\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"PowerShell Pivot Tables &#8226; The Lonely Administrator","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2434\/powershell-pivot-tables\/","og_locale":"en_US","og_type":"article","og_title":"PowerShell Pivot Tables &#8226; The Lonely Administrator","og_description":"I was working on a question in the Ask Don and Jeff forum about multidimensional arrays. The ultimate goal of sorts was to create an HTML report that contained in essence a pivot table. This device allows you to slice and dice data so that you can identify trends or patterns. In PowerShell, there aren't...","og_url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2434\/powershell-pivot-tables\/","og_site_name":"The Lonely Administrator","article_published_time":"2012-07-05T18:01:48+00:00","article_modified_time":"2013-08-09T12:44:32+00:00","og_image":[{"url":"http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/07\/keyboardanalyze-150x150.png","type":"","width":"","height":""}],"author":"Jeffery Hicks","twitter_card":"summary_large_image","twitter_creator":"@JeffHicks","twitter_site":"@JeffHicks","twitter_misc":{"Written by":"Jeffery Hicks","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2434\/powershell-pivot-tables\/#article","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2434\/powershell-pivot-tables\/"},"author":{"name":"Jeffery Hicks","@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"headline":"PowerShell Pivot Tables","datePublished":"2012-07-05T18:01:48+00:00","dateModified":"2013-08-09T12:44:32+00:00","mainEntityOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2434\/powershell-pivot-tables\/"},"wordCount":415,"commentCount":4,"publisher":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2434\/powershell-pivot-tables\/#primaryimage"},"thumbnailUrl":"http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/07\/keyboardanalyze-150x150.png","keywords":["Function","Group-Object","PowerShell","Scripting"],"articleSection":["PowerShell","Scripting"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/2434\/powershell-pivot-tables\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2434\/powershell-pivot-tables\/","url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2434\/powershell-pivot-tables\/","name":"PowerShell Pivot Tables &#8226; The Lonely Administrator","isPartOf":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2434\/powershell-pivot-tables\/#primaryimage"},"image":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2434\/powershell-pivot-tables\/#primaryimage"},"thumbnailUrl":"http:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/07\/keyboardanalyze-150x150.png","datePublished":"2012-07-05T18:01:48+00:00","dateModified":"2013-08-09T12:44:32+00:00","breadcrumb":{"@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2434\/powershell-pivot-tables\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/jdhitsolutions.com\/blog\/powershell\/2434\/powershell-pivot-tables\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2434\/powershell-pivot-tables\/#primaryimage","url":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/07\/keyboardanalyze.png","contentUrl":"https:\/\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2012\/07\/keyboardanalyze.png","width":"643","height":"458"},{"@type":"BreadcrumbList","@id":"https:\/\/jdhitsolutions.com\/blog\/powershell\/2434\/powershell-pivot-tables\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"PowerShell","item":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},{"@type":"ListItem","position":2,"name":"PowerShell Pivot Tables"}]},{"@type":"WebSite","@id":"https:\/\/jdhitsolutions.com\/blog\/#website","url":"https:\/\/jdhitsolutions.com\/blog\/","name":"The Lonely Administrator","description":"Practical Advice for the Automating IT Pro","publisher":{"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/jdhitsolutions.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/jdhitsolutions.com\/blog\/#\/schema\/person\/d0258030b41f07fd745f4078bdf5b6c9","name":"Jeffery Hicks","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","url":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg","caption":"Jeffery Hicks"},"logo":{"@id":"https:\/\/secure.gravatar.com\/avatar\/832ae5d438fdcfc1420d720cd1991307927de8a0b12f2342e81c30f773e21098?s=96&d=wavatar&r=pg"}}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":4533,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/4533\/powershell-pivot-tables-revisited\/","url_meta":{"origin":2434,"position":0},"title":"PowerShell Pivot Tables Revisited","author":"Jeffery Hicks","date":"September 26, 2015","format":false,"excerpt":"A few years ago I wrote a PowerShell function to create an Excel-like pivot table in a PowerShell console. The other day I decided to revisit the function. I was surprised that it didn't really need too much updating but I did spend some time updating the documentation and adding\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":3093,"url":"https:\/\/jdhitsolutions.com\/blog\/scripting\/3093\/friday-fun-its-powershell-baby\/","url_meta":{"origin":2434,"position":1},"title":"Friday Fun: It&#8217;s PowerShell, Baby!","author":"Jeffery Hicks","date":"June 7, 2013","format":false,"excerpt":"The other day I received an email looking for guidance on using Invoke-Webrequest to pull data from a table on a web page. Specifically, he wanted to get the list of popular baby names from http:\/\/www.ssa.gov\/OACT\/babynames\/index.html. I gave him some quick tips but figured this would also be another teaching\u2026","rel":"","context":"In &quot;Friday Fun&quot;","block_context":{"text":"Friday Fun","link":"https:\/\/jdhitsolutions.com\/blog\/category\/friday-fun\/"},"img":{"alt_text":"baby","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2013\/06\/baby-150x150.png?resize=350%2C200","width":350,"height":200},"classes":[]},{"id":2704,"url":"https:\/\/jdhitsolutions.com\/blog\/scripting\/2704\/powershell-graphing-with-out-gridview\/","url_meta":{"origin":2434,"position":2},"title":"PowerShell Graphing with Out-Gridview","author":"Jeffery Hicks","date":"January 14, 2013","format":false,"excerpt":"I've received a lot of interest for my last few posts on graphing with the PowerShell console. But I decided I could add one more feature. Technically it might have made more sense to turn this into a separate function, but I decided to simply modify the last version of\u2026","rel":"","context":"In &quot;Powershell 3.0&quot;","block_context":{"text":"Powershell 3.0","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell-3-0\/"},"img":{"alt_text":"out-consolegraph-gv","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2013\/01\/out-consolegraph-gv-1024x548.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2013\/01\/out-consolegraph-gv-1024x548.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2013\/01\/out-consolegraph-gv-1024x548.png?resize=525%2C300 1.5x"},"classes":[]},{"id":6855,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell-7\/6855\/powershell-scripting-for-linux-is-still-about-the-objects\/","url_meta":{"origin":2434,"position":3},"title":"PowerShell Scripting for Linux is Still About the Objects","author":"Jeffery Hicks","date":"October 8, 2019","format":false,"excerpt":"I've been trying to increase my Linux skills, especially as I begin to write PowerShell scripts and tools that can work cross-platform. One very important concept I want to make sure you don't overlook is that even when scripting for non-Windows platforms, you must still be thinking about objects. The\u2026","rel":"","context":"In &quot;PowerShell 7&quot;","block_context":{"text":"PowerShell 7","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell-7\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":7468,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/7468\/powershell-7-scripting-with-the-powershell-ise\/","url_meta":{"origin":2434,"position":4},"title":"PowerShell 7 Scripting with the PowerShell ISE","author":"Jeffery Hicks","date":"May 11, 2020","format":false,"excerpt":"By now, everyone should have gotten the memo that with the move to PowerShell 7, the PowerShell ISE should be considered deprecated. When it comes to PowerShell script and module development for PowerShell 7, the recommended tool is Visual Studio Code. It is free and offers so much more than\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/05\/ise-ps7.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/05\/ise-ps7.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/05\/ise-ps7.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2020\/05\/ise-ps7.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":6996,"url":"https:\/\/jdhitsolutions.com\/blog\/powershell\/6996\/powershell-controller-scripts\/","url_meta":{"origin":2434,"position":5},"title":"PowerShell Controller Scripts","author":"Jeffery Hicks","date":"November 26, 2019","format":false,"excerpt":"When it comes to PowerShell scripting we tend to focus a lot on functions and modules. We place an emphasis on building re-usable tools. The idea is that we can then use these tools at a PowerShell prompt to achieve a given task. More than likely, these tasks are repetitive.\u2026","rel":"","context":"In &quot;PowerShell&quot;","block_context":{"text":"PowerShell","link":"https:\/\/jdhitsolutions.com\/blog\/category\/powershell\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/11\/image_thumb-21.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/11\/image_thumb-21.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/11\/image_thumb-21.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/jdhitsolutions.com\/blog\/wp-content\/uploads\/2019\/11\/image_thumb-21.png?resize=700%2C400&ssl=1 2x"},"classes":[]}],"_links":{"self":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/2434","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/comments?post=2434"}],"version-history":[{"count":0,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/posts\/2434\/revisions"}],"wp:attachment":[{"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/media?parent=2434"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/categories?post=2434"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jdhitsolutions.com\/blog\/wp-json\/wp\/v2\/tags?post=2434"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}