{"id":1081,"date":"2014-07-02T00:01:00","date_gmt":"2014-07-02T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2014\/07\/02\/back-to-the-basics-part-3-do-something-with-your-data\/"},"modified":"2022-06-10T12:48:50","modified_gmt":"2022-06-10T19:48:50","slug":"back-to-the-basics-part-3-do-something-with-your-data","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/back-to-the-basics-part-3-do-something-with-your-data\/","title":{"rendered":"Back to the Basics Part 3: Do Something with Your Data"},"content":{"rendered":"<p><b style=\"font-size:12px\">Summary<\/b><span style=\"font-size:12px\">: Microsoft PFE, Gary Siepser, further investigates the basics of the Windows PowerShell pipeline.<\/span><\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. It&#8217;s midweek already! Time sure flies, especially when you have a guest blogger for the week. Welcome back Gary Siepser for the third part in a series. To catch up, read:<\/p>\n<ul>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/scripting\/back-to-the-basics-part-1-learn-about-the-powershell-pipeline\/\" target=\"_blank\" rel=\"noopener\">Back to the Basics Part 1: Learn About the PowerShell Pipeline<\/a><\/li>\n<li><a href=\"https:\/\/devblogs.microsoft.com\/scripting\/back-to-the-basics-part-2-learn-about-the-pipeline-and-getters\/\" target=\"_blank\" rel=\"noopener\">Back to the Basics Part 2: Learn about the Pipeline and &#8220;Getters&#8221;<\/a><\/li>\n<\/ul>\n<p>In Part 2 of this series, we looked at how you start a pipeline. In this part, we\u2019ll see some basic and easy-to-use commands that let us manipulate that data to suit our needs.<span style=\"font-size:12px\">\u00a0<\/span><\/p>\n<p>First, let\u2019s do a quick review of cmdlets. They are single-purpose commands that can be used together in a pipeline as building blocks for a real solution. Because most cmdlets truly are single purpose, they usually lack common functionality, such as exporting to other file formats or sorting the output. Often <strong>Get<\/strong> cmdlets don\u2019t even have very rich filtering capabilities. This is intentional. We have other single-purpose cmdlets to address those needs.<\/p>\n<p>Let\u2019s also recall that the pipeline is simply a way to string commands together. The output of one command becomes the input of the next command. All of the cmdlets we are going to look at in this post were specifically designed to be used in the pipeline. As a matter of fact, if you try to start a line with these commands, they typically don\u2019t work like you would expect. They were meant to be used in the pipeline, so we need to use them that way.<\/p>\n<p>For the rest of this post, we\u2019ll focus on four simple but key ways we need to work with our data:<\/p>\n<ul>\n<li>Sorting<\/li>\n<li>Simplifying<\/li>\n<li>Counting<\/li>\n<li>Filtering<\/li>\n<\/ul>\n<p>The best part about the cmdlets that perform these feats is that they work with ANYTHING. They were designed to work with any objects coming through the pipeline. They even have the noun of <strong>Object<\/strong> to keep them generic. The big win is that you learn them once, and use them forever!<\/p>\n<p>We\u2019ll start with the simplest: <strong>Sort-Object<\/strong>. The <strong>Sort-Object<\/strong> cmdlet is so simple to use. There are really only two things to think about:<\/p>\n<p>1&#46; What you want to sort by<\/p>\n<p>2&#46; Ascending or descending sort<\/p>\n<p>The latter is the easier one to talk about. If you want an ascending sort, don\u2019t do anything. This is what the cmdlet does by default.<\/p>\n<p>Now for choosing what to sort by&#8230;<\/p>\n<p>Most of time, I will look at the unsorted results first to spot what property I want to sort by (or column if it\u2019s a table). If I spot something, just use the Up arrow in the Windows PowerShell console to bring up the last command, and pipe it to the <strong>Sort-Object<\/strong> cmdlet. You\u2019ll specify the property name that you want to sort by after the cmdlet.<\/p>\n<p style=\"margin-left:30px\">\n  <b>Note<\/b>\u00a0\u00a0<b>Sort<\/b> is command alias for <b>Sort-Object<\/b>. I am not normally a big fan of using many shortcuts in Windows PowerShell, but this is one I really like because it keeps your pipeline very readable\u2014almost like spoken language.\n<\/p>\n<p>Take a look at the following examples of using <strong>Sort-Object<\/strong>. For more help with the command, like always, check out the Help topic (Get-Help Sort-Object \u2013ShowWindow).<span style=\"font-size:12px\">\u00a0<\/span><\/p>\n<p><span style=\"font-size:12px\"><a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/Capture1.PNG\"><img decoding=\"async\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/Capture1.PNG\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/span><\/p>\n<p><a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/0207.Capture2.PNG\"><img decoding=\"async\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/0207.Capture2.PNG\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p><a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/Capture3.PNG\"><img decoding=\"async\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/Capture3.PNG\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>If you try to use a property name that you saw (for example, the <strong>WS(K)<\/strong> column heading from <strong>Get-Process<\/strong>), and you find that something isn\u2019t quite working as expected, there is a technique to solve your issue. This works for all the <strong>Object<\/strong> cmdlets we are going to cover.<\/p>\n<p>The issue here is that the default view you get when you run a command can sometimes lie to us a little. There is some default formatting magic that occurs in Windows Powershell to make these default views look better (beauty is always in the eye of the beholder, of course). This magic can make it a little harder to look at column headings and use them with your cmdlets. Always try them first, but if it fails, **Get-Member **is your savior.<\/p>\n<p><strong>Get-Member<\/strong> is an investigative cmdlet that will show us what we are working with. Down the road, when you really start geeking-out with Windows Powershell and objects, <strong>Get-Member<\/strong> is truly a great asset. Even in the beginning stages of our Windows Powershell lives, we can get value from it without diving in too deeply. Pipe whatever you are working with to the <strong>Get-Member<\/strong> cmdlet, and it will show you a list of all the real properties for the object. For now, ignore anything that doesn\u2019t have the word <strong>property<\/strong> in its <strong>MemberType<\/strong> column.<\/p>\n<p><a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/7506.Capture4.PNG\"><img decoding=\"async\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/7506.Capture4.PNG\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>There is some truncation in the previous example to show a few different types of members without making you scroll too far.<\/p>\n<p>Armed with <strong>Get-Member<\/strong>, you can now choose what property you are going to sort by. As I mentioned earlier, this applies to not only all the <strong>Object<\/strong> cmdlets in this post, but all across Windows Powershell. <strong>Get-Member<\/strong> will show you what you are really working with instead of the more \u201cuser-friendly\u201d default views we normally see.<\/p>\n<p>Now that we can sort our data, let\u2019s move on to simplifying what you are working with. <strong>Select-Object<\/strong> is, in my opinion, the Swiss Army knife of Windows Powershell. It can really manipulate your objects a lot. To keep things simple right now, we\u2019ll look at how it can strip down your objects to only the properties you want to deal with. This is really easy.<\/p>\n<p>Follow the <strong>Select-Object<\/strong> (the alias is <strong>Select<\/strong>) cmdlet with a comma-separated list of the properties you want to keep. There is a really cool side effect of doing this. After you have simplified your objects, the default formatting I referred to earlier has really neat behavior. If you strip down an object to four or less properties, you will see them as a table. If you strip it down to five or more properties, you will get a list.<\/p>\n<p>This is cool because default formatting isn\u2019t normally dynamic. It\u2019s a logical choice that Windows PowerShell makes for you, and I see a lot of folks using it for that reason. In Part\u00a05 of this series, we will look at outputting your data. Using <strong>Select-Object<\/strong> reduces some need to directly control the output and formatting by dynamically choosing them for you.<\/p>\n<p>Take a look at how this looks:<\/p>\n<p><a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/2248.Capture5.PNG\"><img decoding=\"async\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/2248.Capture5.PNG\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p><span style=\"font-size:12px\">You can see that in the first example, there were only four properties, so we saw a table. The second example had five properties, and Windows PowerShell automatically generated a list. Also, because of the width of the command, I took advantage of line-continuation in Windows PowerShell by hitting ENTER after the pipeline character. If you are working in the ISE Console, press Shift + ENTER.<\/span><\/p>\n<p><strong>Select-Object<\/strong>\u00a0can do so much more than this, but we want to keep things simple in this post and series. To see more, check out the Help for\u00a0<strong>Select-Object<\/strong>\u00a0(Get-Help Select-Object \u2013ShowWindow). The examples in the Help show many different options.<\/p>\n<p>Next, we\u2019ll use\u00a0<strong>Measure-Object<\/strong>\u00a0to get a count of objects in the pipeline. (The alias is\u00a0<strong>Measure<\/strong>. Are we seeing a trend with the alias names?) This is something I use all the time! There are several ways in Windows PowerShell to get this count, but I love just piping to\u00a0<strong>Measure<\/strong>.<\/p>\n<p><strong>Measure-Object<\/strong>\u00a0can get several other calculations for numeric properties such as sum and average. It can also analyze text for lines and characters, and analyze words for string objects and properties. For more information, check the Help file (Get-Help Measure-Object \u2013ShowWindow).<\/p>\n<p>Take a look at these examples for counting objects:<\/p>\n<p><a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/Capture6.PNG\"><img decoding=\"async\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/Capture6.PNG\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p><span style=\"font-size:12px\">Lastly, we\u2019ll look at some simple examples of filtering objects. We filter objects in the pipeline by using the <\/span><b style=\"font-size:12px\">Where-Object<\/b><span style=\"font-size:12px\"> cmdlet. (Surprise, we have the alias: <\/span><b style=\"font-size:12px\">Where<\/b><span style=\"font-size:12px\">.) Using <\/span><b style=\"font-size:12px\">Where-Object<\/b><span style=\"font-size:12px\"> can get a little advanced, and in this post, we are going to look at only using the simplified syntax. This easier-to-use and easier-to-look-at syntax was introduced in Windows PowerShell\u00a03.0, and it covers a good majority of the filtering that I see with <\/span><b style=\"font-size:12px\">Where-Object<\/b><span style=\"font-size:12px\">.<\/span><\/p>\n<p>To filter objects, we need to tell <strong>Where-Object<\/strong> what property we want to test, how we want to test it, and what value we are testing against. That may sound a little complicated, but it\u2019s actually pretty straight-forward. Like all the other cmdlets, though, looking at the Help file will clear up all the ways that the cmdlet works (Get-Help Where-Object \u2013ShowWindow).<\/p>\n<p>Take a look at these examples of filtering by using <strong>Where-Object<\/strong> to see what I am talking about. I love that they are fairly high-level language and quite readable.<\/p>\n<p><a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/Capture7.PNG\"><img decoding=\"async\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/Capture7.PNG\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>I can\u2019t help but read these two example lines and think to myself that any IT admin is going to understand what is happening, even if they have never ever heard of Windows PowerShell. I like intuitive, and this is definitely it.<\/p>\n<p>Before I close this post, I want to show one more example where we bring a few of these cmdlets together at the same time into a more complex, but still easy-to-understand pipeline:<\/p>\n<p><a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/Capture8.PNG\"><img decoding=\"async\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/TNBlogsFS\/prod.evol.blogs.technet.com\/CommunityServer.Blogs.Components.WeblogFiles\/00\/00\/00\/76\/18\/Capture8.PNG\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p><span style=\"font-size:12px\">Now that, my friends, is piping.<\/span><\/p>\n<p>In Part\u00a04, we will look at a few even cooler things that we can do with our data in the pipeline, for example, grouping by similar values, teeing our objects in two directions, and the original non-simplified syntax for <strong>Where-Object<\/strong>.<\/p>\n<p>~Gary<\/p>\n<p>Thank you, Gary, for sharing your time and knowledge.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\" rel=\"noopener\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\" rel=\"noopener\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\" rel=\"noopener\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\" rel=\"noopener\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><strong>Ed Wilson, Microsoft Scripting Guy<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft PFE, Gary Siepser, further investigates the basics of the Windows PowerShell pipeline. Microsoft Scripting Guy, Ed Wilson, is here. It&#8217;s midweek already! Time sure flies, especially when you have a guest blogger for the week. Welcome back Gary Siepser for the third part in a series. To catch up, read: Back to the [&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":[317,51,56,149,3,45],"class_list":["post-1081","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-gary-siepser","tag-getting-started","tag-guest-blogger","tag-pipeline","tag-scripting-guy","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Microsoft PFE, Gary Siepser, further investigates the basics of the Windows PowerShell pipeline. Microsoft Scripting Guy, Ed Wilson, is here. It&#8217;s midweek already! Time sure flies, especially when you have a guest blogger for the week. Welcome back Gary Siepser for the third part in a series. To catch up, read: Back to the [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/1081","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=1081"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/1081\/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=1081"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=1081"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=1081"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}