{"id":1505,"date":"2014-04-29T00:01:00","date_gmt":"2014-04-29T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2014\/04\/29\/powershell-looping-using-the-foreach-object-cmdlet\/"},"modified":"2014-04-29T00:01:00","modified_gmt":"2014-04-29T00:01:00","slug":"powershell-looping-using-the-foreach-object-cmdlet","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/powershell-looping-using-the-foreach-object-cmdlet\/","title":{"rendered":"PowerShell Looping: Using the Foreach-Object Cmdlet"},"content":{"rendered":"<p><b>Summary<\/b>: Microsoft Scripting Guy, Ed Wilson, talks about using the <b>Foreach-Object<\/b> cmdlet in Part&nbsp;2 of the Looping Week series.<\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. Today I want to address a major point of confusion for newbie Windows PowerShell scripters. That point is the <b>Foreach-Object<\/b> cmdlet. Part of the confusion comes with the alias, <strong>F<\/strong><b>oreach<\/b>, which is the same as the command name, <strong>Foreach<\/strong>.<\/p>\n<p>But that is only part of the confusion. For people trying to come to grips with looping through a collection, adding the <b>Foreach-Object<\/b> cmdlet into the mixture is just asking for trouble. Or asking for help. And that is what I am going to provide today; I&#039;ll attempt to demystify part of the equation.<\/p>\n<p style=\"margin-left:30px\"><b>Note<\/b> &nbsp;This is Part&nbsp;2 of a four-part series about looping. In Part&nbsp;1, <a href=\"https:\/\/devblogs.microsoft.com\/scripting\/basics-of-powershell-looping-foreach\/\" target=\"_blank\">Basics of PowerShell Looping: Foreach<\/a>, I looked at the <b>Foreach<\/b> statement and talked about the problem of collections, arrays, and accessing specific items. Today, I am going to talk about using the <b>Foreach-Object<\/b> cmdlet to work with individual items from a collection.<\/p>\n<p>I want to go back to the array that I created yesterday. I store three values in three different variables. I then stored those three variables into the <b>$d<\/b> variable as shown here:<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $a = 5<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $b = 6<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $c = 7<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $d = $a, $b, $c<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $d<\/p>\n<p style=\"margin-left:30px\">5<\/p>\n<p style=\"margin-left:30px\">6<\/p>\n<p style=\"margin-left:30px\">7<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt;<\/p>\n<p>Yesterday, I used the <b>Foreach<\/b> command to add five to each of the items stored in the array. I can do the same thing by using the pipeline. In fact, it will be easier to write and work with. The key point is that the <b>$_<\/b> variable represents the current item in the pipeline. I can then work with <b>$_<\/b> in the same way that I worked with the <b>$i<\/b> variable yesterday in the <b>Foreach<\/b> statement.<\/p>\n<p>It might be a bit easier to show the script. I take the <b>$d<\/b> variable (which contains the three values), and I send it down the pipeline to the <b>Foreach-Object<\/b> cmdlet. Inside the script block (curly braces), I use the <b>$_<\/b> automatic variable, and I add the number 5 to each item that comes across. This script is shown here:<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $d | ForEach-Object { $_ + 5 }<\/p>\n<p style=\"margin-left:30px\">10<\/p>\n<p style=\"margin-left:30px\">11<\/p>\n<p style=\"margin-left:30px\">12<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt;<\/p>\n<p>The command and the Windows PowerShell console are shown in the following image.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-4-29-14-01.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-4-29-14-01.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>There are a number of advantages to using the <b>Foreach-Object<\/b> cmdlet as opposed to the <b>Foreach<\/b> statement. The first is that I do not have to create an enumerator variable, and I can leave out the parenthesis portion of the code block.<\/p>\n<p>The second advantage is that I have a number of aliases for the <b>Foreach-Object<\/b> cmdlet. The shortest one is the <b>% <\/b>symbol. If I look at this symbol just right, I can see an <b>o<\/b>, and a <b>|<\/b>, and another <b>o<\/b>. This illustrates a value crossing the pipeline&mdash;at least this is the way I remember it. So my previous script becomes:<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $d | % { $_ + 5 }<\/p>\n<p style=\"margin-left:30px\">10<\/p>\n<p style=\"margin-left:30px\">11<\/p>\n<p style=\"margin-left:30px\">12<\/p>\n<p>Another thing that is cool is that I do not need the <b>$d<\/b> variable at all. I can pipe my array of variables directly to the <b>Foreach-Object<\/b> cmdlet. This technique is shown here:<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $a,$b,$c | ForEach-Object { $_ + 5 }<\/p>\n<p style=\"margin-left:30px\">10<\/p>\n<p style=\"margin-left:30px\">11<\/p>\n<p style=\"margin-left:30px\">12<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt;<\/p>\n<p>In addition, tab expansion works with the <b>Foreach-Object<\/b> cmdlet, so I do not have to type out <b>Foreach-Object<\/b> each time I want to use it. I just type a few letters, hit the <b>Tab<\/b> key, and the cmdlet name expands. Or I can use the <b>%<\/b> symbol (which is what I use when I work interactively from the Windows PowerShell console).<\/p>\n<p>One of the things that I like to do when using the <b>Foreach-Object<\/b> cmdlet with the pipeline, is to send the results to another Windows PowerShell cmdlet, such as the <b>Sort-Object<\/b> cmdlet. This makes for some really powerful script, and it is easy to work out.<\/p>\n<p>For example, I have three values stored in three variables: <b>$e<\/b>, <b>$f<\/b>, and <b>$g<\/b>. This is shown here:<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $e = 15<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $f = 9<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $g = 17<\/p>\n<p>Notice that the values are not in order&mdash;not in any sort of order at all. I want to add two to each of the values, and then I want to sort the list. To do this, I pipe the array of three variables to the <b>Foreach-Object<\/b> cmdlet. Inside the script block, I add two, and then I pipe the results to the <b>Sort-Object<\/b> cmdlet. I sort on the same <b>$_<\/b> automatic variable, and then I choose the <b>&ndash;Descending<\/b> switch. This script is shown here:<\/p>\n<p style=\"margin-left:30px\">PS C:\\&gt; $e, $f, $g | % { $_ + 2 } | sort $_ -Descending<\/p>\n<p style=\"margin-left:30px\">19<\/p>\n<p style=\"margin-left:30px\">17<\/p>\n<p style=\"margin-left:30px\">11<\/p>\n<p>The command and the output are shown in the following image:<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-4-29-14-02.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-4-29-14-02.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>The neat thing is that by using the <b>Foreach-Object<\/b> cmdlet, it is so easy to work with collections that I do not have to write any script. Notice that today I did not bother to open the Windows PowerShell ISE. With the <b>Foreach<\/b> language statement, I generally feel compelled to open the Windows PowerShell ISE&hellip;it just seems like the thing to do. But with the <b>Foreach-Object<\/b> statement, I don&rsquo;t need to do so at all.<\/p>\n<p>That is all there is to using the <b>Foreach-Object<\/b> cmdlet. Looping Week will continue tomorrow when I will talk about using the <b>While<\/b> statement.<\/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\" target=\"_blank\">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><b>Ed Wilson, Microsoft Scripting Guy<\/b>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about using the Foreach-Object cmdlet in Part&nbsp;2 of the Looping Week series. Microsoft Scripting Guy, Ed Wilson, is here. Today I want to address a major point of confusion for newbie Windows PowerShell scripters. That point is the Foreach-Object cmdlet. Part of the confusion comes with the alias, [&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":[51,95,3,4,45],"class_list":["post-1505","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-getting-started","tag-looping","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Microsoft Scripting Guy, Ed Wilson, talks about using the Foreach-Object cmdlet in Part&nbsp;2 of the Looping Week series. Microsoft Scripting Guy, Ed Wilson, is here. Today I want to address a major point of confusion for newbie Windows PowerShell scripters. That point is the Foreach-Object cmdlet. Part of the confusion comes with the alias, [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/1505","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=1505"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/1505\/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=1505"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=1505"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=1505"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}