{"id":11871,"date":"2011-12-06T00:01:00","date_gmt":"2011-12-06T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2011\/12\/06\/add-modify-verify-and-sort-your-powershell-array\/"},"modified":"2011-12-06T00:01:00","modified_gmt":"2011-12-06T00:01:00","slug":"add-modify-verify-and-sort-your-powershell-array","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/add-modify-verify-and-sort-your-powershell-array\/","title":{"rendered":"Add, Modify, Verify, and Sort Your PowerShell Array"},"content":{"rendered":"<p><b>Summary<\/b>: Learn how to add, modify, or verify values in a Windows PowerShell array, and discover two easy techniques for sorting your array.<\/p>\n<p><img decoding=\"async\" alt=\"Hey, Scripting Guy! Question\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/q-for-powertip.jpg\" \/>&nbsp;Hey, Scripting Guy! I get that arrays are really simple in Windows PowerShell, but it seems that they are so simple that no one ever seems to tell us how to work with them. For example, I need to know how to add items to an array or how to change an item that is in an array. I have searched all over the Internet, and I cannot seem to find a straight answer. I know you guys seem to love hash tables, but that seems to be a lot of overhead for a simple array. Can you help?<\/p>\n<p>&mdash;PT<\/p>\n<p><img decoding=\"async\" alt=\"Hey, Scripting Guy! Answer\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/a-for-powertip.jpg\" \/>&nbsp;Hello PT,<\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. You are right. You are also right, and unfortunately, you are right&mdash;but I can help solve that problem. OK, maybe I had better explain a bit. You are right, arrays in Windows PowerShell are simple, and in fact, they are so simple that many people do not bother to talk about how simple they are. It is also true that Windows PowerShell loves hash tables, but the same is true for arrays. In fact, Windows PowerShell loves arrays so much that they are incredibly easy to use.<\/p>\n<p><b>Note<\/b>: This is part two of a multiple blog series about working with arrays and hash tables for data storage. In yesterday&rsquo;s Hey, Scripting Guy! Blog, <a href=\"http:\/\/blogs.technet.com\/b\/heyscriptingguy\/archive\/2011\/12\/05\/learn-simple-ways-to-handle-windows-powershell-arrays.aspx\" target=\"_blank\">Learn Simple Ways to Handle Windows PowerShell Arrays<\/a><i>,<\/i> I discussed creating arrays, indexing into arrays, and two techniques for walking through an array.<\/p>\n<h2>Working with specific array elements<\/h2>\n<p>One of the interesting things about arrays in Windows PowerShell is they are able to hold different data types. For example, I can store numbers and strings in the same array as shown here.<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; $a = 1,2,3,&#8221;four&#8221;<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; $a<\/p>\n<p style=\"padding-left: 30px\">1<\/p>\n<p style=\"padding-left: 30px\">2<\/p>\n<p style=\"padding-left: 30px\">3<\/p>\n<p style=\"padding-left: 30px\">Four<\/p>\n<h2>Changing element values<\/h2>\n<p>If I need to change an element in array, I can index into the array by using the square bracket and the index number. To find the upper boundary, I use the <b>GetUpperBound<\/b><i> <\/i>method, and when I have that value, I can easily find the element I need to modify. This technique is shown here.<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; $a.GetUpperBound(0)<\/p>\n<p style=\"padding-left: 30px\">3<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; $a[3] = 4<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; $a<\/p>\n<p style=\"padding-left: 30px\">1<\/p>\n<p style=\"padding-left: 30px\">2<\/p>\n<p style=\"padding-left: 30px\">3<\/p>\n<p style=\"padding-left: 30px\">4<\/p>\n<h2>Adding a new element to an existing array<\/h2>\n<p>If I want to add an element to an existing array, it might make sense to choose the next index number, and attempt to assign a value in the same way that I change an existing value. When I do this, however, Windows PowerShell generates an out of range error message. This command and error message are shown here.<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; $a[4] = 12<\/p>\n<p style=\"padding-left: 30px\">Array assignment failed because index &#8216;4&#8217; was out of range.<\/p>\n<p style=\"padding-left: 30px\">At line:1 char:4<\/p>\n<p style=\"padding-left: 30px\">+ $a[ &lt;&lt;&lt;&lt; 4] = 12<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; + CategoryInfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : InvalidOperation: (4:Int32) [], RuntimeException<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; + FullyQualifiedErrorId : IndexOutOfRange<\/p>\n<p>The way to add a new element to an existing array is to use the += operator as shown here.<\/p>\n<p style=\"padding-left: 30px\">$a += 12<\/p>\n<p>The commands to create an array, get the upper boundary of an array, change an element in an array, and add a new element to an array are shown here with their associated output.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4760.hsg-12-6-11-01.png\"><img decoding=\"async\" title=\"Image of script\" alt=\"Image of script\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4760.hsg-12-6-11-01.png\" \/><\/a><\/p>\n<h2>Searching for a specific value in an array<\/h2>\n<p>One question that comes up from time-to-time is, &ldquo;How do I know whether a value is contained in an array?&rdquo; The answer is, once again, rather easy, &ldquo;Use the <b>Contains<\/b><i> <\/i>operator&rdquo;. The following two commands use the previously created <b>$a<\/b> array. In the first command, the number 12 is present, and the value <b>True<\/b><i> <\/i>returns. In the second example, the array does not contain the number 14; and therefore, the returned value is <b>False<\/b><i>.<\/i><\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; $a -contains 12<\/p>\n<p style=\"padding-left: 30px\">True<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; $a -contains 14<\/p>\n<p style=\"padding-left: 30px\">False<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt;<\/p>\n<h2>Sorting an array<\/h2>\n<p>Now suppose I need to sort my array. There are actually two ways to do this. The first way to do this is to use the <b>Sort-Object <\/b>cmdlet (<b>Sort<\/b> is an alias for the <b>Sort-Object <\/b>cmdlet). The second way to sort an array is to use the static <b>Sort<\/b><i> <\/i>method from the <b>System.Array <\/b>.NET Framework class.<\/p>\n<h2>Use Sort and the pipeline<\/h2>\n<p>The first technique I will discuss is also the easiest to use. It is the pipeline method. All that this technique requires is to pipe the array to the cmdlet. This technique is shown here.<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; [int[]]$a = 1,5,7,2,12,4<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; $a | Sort-Object<\/p>\n<p style=\"padding-left: 30px\">1<\/p>\n<p style=\"padding-left: 30px\">2<\/p>\n<p style=\"padding-left: 30px\">4<\/p>\n<p style=\"padding-left: 30px\">5<\/p>\n<p style=\"padding-left: 30px\">7<\/p>\n<p style=\"padding-left: 30px\">12<\/p>\n<p>The thing to keep in mind is that this does not change the array, it merely changes the display output. If I want to modify the actual array, I need to write the results back to the original array. This technique is shown here.<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; $a = $a | sort<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; $a<\/p>\n<p style=\"padding-left: 30px\">1<\/p>\n<p style=\"padding-left: 30px\">2<\/p>\n<p style=\"padding-left: 30px\">4<\/p>\n<p style=\"padding-left: 30px\">5<\/p>\n<p style=\"padding-left: 30px\">7<\/p>\n<p style=\"padding-left: 30px\">12<\/p>\n<p>The commands to create an array of integers, sort the results with the <b>Sort-Object <\/b>cmdlet, and write the results back to the array are shown in the following image.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3716.hsg-12-6-11-02.png\"><img decoding=\"async\" title=\"Image of script\" alt=\"Image of script\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3716.hsg-12-6-11-02.png\" \/><\/a><\/p>\n<h2>Use Get-Random to create a random array<\/h2>\n<p>One of my favorite tricks is to create an array of numbers by using the <b>Get-Random <\/b>cmdlet. To do this, I use <b>Count<\/b><i> <\/i>to specify the number of values to select, and I use a range operator to create an array of numbers from which to choose. I then write the random values to a variable. This technique is shown here.<\/p>\n<p style=\"padding-left: 30px\">$rnd = Get-Random -Count 10 -InputObject (1..100000)<\/p>\n<h2>Use the static Sort<i> <\/i>method<\/h2>\n<p>To sort the random numbers, I use the <b>Sort<\/b><i> <\/i>static method from the <b>System.Array <\/b>.NET Framework class. Because <b>Sort<\/b><i> <\/i>is a static method, I need to use a double colon separator between the class name (in square brackets) and the method name. I supply the array of random numbers as an input value. This command is shown here.<\/p>\n<p style=\"padding-left: 30px\">[array]::sort($rnd)<\/p>\n<p>What is really interesting is that the <b>Sort<\/b><i> <\/i>static method, automatically writes the sorted values back to the array that is contained in the <b>$rnd<\/b> variable. The commands to create a random array of numbers, display those values, sort the array, and display the sorted list are shown in the following image.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0083.hsg-12-6-11-03.png\"><img decoding=\"async\" title=\"Image of script\" alt=\"Image of script\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/0083.hsg-12-6-11-03.png\" \/><\/a><\/p>\n<h2>Measuring the difference in performance<\/h2>\n<p>&ldquo;So, what is the difference between the two ways to sort arrays,&rdquo; you may ask. The difference is that the pipeline way of sorting is probably more intuitive to Windows PowerShell users. The other difference is that the static <b>Sort<\/b><i> <\/i>method from the <b>System.Array <\/b>class is way faster. To check this, I like to use the <b>Measure-Command <\/b>cmdlet. To ensure I have a large enough data set that will take a decent amount of time to sort, I create two random arrays by using the commands that are shown here.<\/p>\n<p style=\"padding-left: 30px\">$arrayA = Get-Random -Count 1000000 -InputObject (1..1000000)<\/p>\n<p style=\"padding-left: 30px\">$arrayB = Get-Random -Count 1000000 -InputObject (1..1000000)<\/p>\n<p>Next, I use the <b>Measure-Command <\/b>cmdlet to measure the two ways of sorting arrays. The two commands are shown here.<\/p>\n<p style=\"padding-left: 30px\">Measure-Command -Expression { $arrayA = $arrayA | Sort-Object }<\/p>\n<p style=\"padding-left: 30px\">Measure-Command -Expression { [array]::Sort($arrayB) }<\/p>\n<p>On my system (which is a fast computer), the first command takes a little over 40 seconds, whereas the second command takes a little more than 8 seconds. Therefore, the second command appears to be five times faster than the first command that uses the pipeline.<\/p>\n<p>The commands that create the two random arrays use <b>Measure-Command <\/b>to check the speed of the two commands, and they display the first two numbers in each of the newly sorted arrays, as shown in the following image.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6724.hsg-12-6-11-04.png\"><img decoding=\"async\" title=\"Image of script\" alt=\"Image of script\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6724.hsg-12-6-11-04.png\" \/><\/a><\/p>\n<p><span style=\"font-size: 18px;font-weight: bold\" class=\"Apple-style-span\">Sorting arrays that contain multiple types<\/span><\/p>\n<p>There is one more caveat when it comes to using the two sort methods. Because an array in Windows PowerShell can contain different types, the <b>Sort-Object <\/b>method may be the preferred way of sorting objects. This is because in using the default comparer, the <b>Sort<\/b><i> <\/i>static method fails when the array contains different types.<\/p>\n<p>In the following example, I create an array that contains both integers and strings. I then pipe the array to the <b>Sort-Object <\/b>cmdlet (using <b>Sort<\/b> as the alias). Next, I attempt to use the static <b>Sort<\/b> method from the <b>System.Array <\/b>class, and that generates an error message.<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; $array = 1,2,9,8,3,&#8221;four&#8221;,&#8221;tree&#8221;,&#8221;Cat&#8221;,&#8221;bat&#8221;<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; $array | sort<\/p>\n<p style=\"padding-left: 30px\">1<\/p>\n<p style=\"padding-left: 30px\">2<\/p>\n<p style=\"padding-left: 30px\">3<\/p>\n<p style=\"padding-left: 30px\">8<\/p>\n<p style=\"padding-left: 30px\">9<\/p>\n<p style=\"padding-left: 30px\">bat<\/p>\n<p style=\"padding-left: 30px\">Cat<\/p>\n<p style=\"padding-left: 30px\">four<\/p>\n<p style=\"padding-left: 30px\">tree<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; [array]::sort($array)<\/p>\n<p style=\"padding-left: 30px\">Exception calling &#8220;Sort&#8221; with &#8220;1&#8221; argument(s): &#8220;Failed to compare two elements in the array.&#8221;<\/p>\n<p style=\"padding-left: 30px\">At line:1 char:14<\/p>\n<p style=\"padding-left: 30px\">+ [array]::sort &lt;&lt;&lt;&lt; ($array)<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; + CategoryInfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : NotSpecified: (:) [], MethodInvocationException<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; + FullyQualifiedErrorId : DotNetMethodException<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt;<\/p>\n<p>Because an array can contain other objects (besides strings and integers), I decide to perform one additional test, and I therefore store an instance of the <b>System.Diagnostics.Process<\/b> .NET Framework class in the last element. This command is shown here.<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; $array = 1,2,9,8,3,&#8221;four&#8221;,&#8221;tree&#8221;,&#8221;Cat&#8221;,&#8221;bat&#8221;,(get-process winword)<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; $array<\/p>\n<p style=\"padding-left: 30px\">1<\/p>\n<p style=\"padding-left: 30px\">2<\/p>\n<p style=\"padding-left: 30px\">9<\/p>\n<p style=\"padding-left: 30px\">8<\/p>\n<p style=\"padding-left: 30px\">3<\/p>\n<p style=\"padding-left: 30px\">four<\/p>\n<p style=\"padding-left: 30px\">tree<\/p>\n<p style=\"padding-left: 30px\">Cat<\/p>\n<p style=\"padding-left: 30px\">bat<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Handles&nbsp; NPM(K)&nbsp;&nbsp;&nbsp; PM(K)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WS(K) VM(M)&nbsp;&nbsp; CPU(s)&nbsp;&nbsp;&nbsp;&nbsp; Id ProcessName<\/p>\n<p style=\"padding-left: 30px\">&#8212;&#8212;-&nbsp; &#8212;&#8212;&nbsp;&nbsp;&nbsp; &#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8211; &#8212;&#8211;&nbsp;&nbsp; &#8212;&#8212;&nbsp;&nbsp;&nbsp;&nbsp; &#8212; &#8212;&#8212;&#8212;&#8211;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; 463&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 62&nbsp;&nbsp;&nbsp; 41772&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 89736&nbsp;&nbsp; 369&nbsp;&nbsp;&nbsp; 39.17&nbsp;&nbsp; 4460 WINWORD<\/p>\n<p>Next, I decide to sort the array. Once again, the <b>Sort-Object<\/b> cmdlet comes through with no problems. This output is shown here.<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt; $array | sort<\/p>\n<p style=\"padding-left: 30px\">1<\/p>\n<p style=\"padding-left: 30px\">2<\/p>\n<p style=\"padding-left: 30px\">3<\/p>\n<p style=\"padding-left: 30px\">8<\/p>\n<p style=\"padding-left: 30px\">9<\/p>\n<p style=\"padding-left: 30px\">bat<\/p>\n<p style=\"padding-left: 30px\">Cat<\/p>\n<p style=\"padding-left: 30px\">four<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">Handles&nbsp; NPM(K)&nbsp; &nbsp;&nbsp;PM(K)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WS(K) VM(M)&nbsp;&nbsp; CPU(s)&nbsp;&nbsp;&nbsp;&nbsp; Id ProcessName<\/p>\n<p style=\"padding-left: 30px\">&#8212;&#8212;-&nbsp; &#8212;&#8212;&nbsp;&nbsp;&nbsp; &#8212;&#8211;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8212;&#8211; &#8212;&#8211;&nbsp;&nbsp; &#8212;&#8212;&nbsp;&nbsp;&nbsp;&nbsp; &#8212; &#8212;&#8212;&#8212;&#8211;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;&nbsp;&nbsp; 463&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 62&nbsp;&nbsp;&nbsp; 41772&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 89736&nbsp;&nbsp; 369&nbsp;&nbsp;&nbsp; 39.17&nbsp;&nbsp; 4460 WINWORD<\/p>\n<p style=\"padding-left: 30px\">tree<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">&nbsp;<\/p>\n<p style=\"padding-left: 30px\">PS C:\\&gt;<\/p>\n<p>&nbsp;<\/p>\n<p>PT, that is all there is to modifying values in an array, adding to an array, checking to see if an array contains a specific value, and sorting the array. Array Week will continue tomorrow when I will store different types of objects in an array (including other arrays). It will be fun and educational. See ya!<\/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: Learn how to add, modify, or verify values in a Windows PowerShell array, and discover two easy techniques for sorting your array. &nbsp;Hey, Scripting Guy! I get that arrays are really simple in Windows PowerShell, but it seems that they are so simple that no one ever seems to tell us how to work [&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":[292,51,3,4,45],"class_list":["post-11871","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-arrays-hashtables-and-dictionary-objects","tag-getting-started","tag-scripting-guy","tag-scripting-techniques","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Learn how to add, modify, or verify values in a Windows PowerShell array, and discover two easy techniques for sorting your array. &nbsp;Hey, Scripting Guy! I get that arrays are really simple in Windows PowerShell, but it seems that they are so simple that no one ever seems to tell us how to work [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/11871","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=11871"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/11871\/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=11871"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=11871"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=11871"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}