{"id":71022,"date":"2017-05-19T13:49:57","date_gmt":"2017-05-19T13:49:57","guid":{"rendered":"https:\/\/www.simple-talk.com\/?p=71022"},"modified":"2026-03-18T11:12:34","modified_gmt":"2026-03-18T11:12:34","slug":"high-performance-powershell-linq","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/development\/dotnet-development\/high-performance-powershell-linq\/","title":{"rendered":"PowerShell LINQ Guide: Operators &#038; Performance"},"content":{"rendered":"<h2>Contents<\/h2>\n<div style=\"-webkit-column-gap: 8px; -moz-column-gap: 8px; -ms-column-gap: 8px; -o-column-gap: 8px; column-gap: 8px; -moz-column-width: 15em; -webkit-column-width: 15em; column-width: 15em;\">\n<ul style=\"margin-bottom: 0; line-height: 20px;\">\n<li><a href=\"#post-71022-_Toc482783690\">General Notes<\/a>\n<ul style=\"margin-bottom: 0; line-height: 20px;\">\n<li><a href=\"#post-71022-_Toc482783691\">Format of Entries<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783692\">Deferred vs. Immediate Execution<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783693\">Calling a LINQ Operator<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783694\">Explicit Argument Typing<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783695\">Creating and Passing Delegates<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783696\">Generic LINQ Operators<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783697\">LINQ Chaining<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#post-71022-_Toc482783698\">Performance<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783699\">LINQ to PowerShell Lexicon<\/a>\n<ul style=\"margin-bottom: 0; line-height: 20px;\">\n<li><a href=\"#post-71022-_Toc482783700\">Aggregate<\/a>\n<ul style=\"margin-bottom: 0; line-height: 20px;\">\n<li><a href=\"#post-71022-_Toc482783701\">Count<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783702\">LongCount<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783703\">Sum<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783704\">Average<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783705\">Max<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783706\">Min<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783707\">Aggregate<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#post-71022-_Toc482783708\">Conversion<\/a>\n<ul style=\"margin-bottom: 0; line-height: 20px;\">\n<li><a href=\"#post-71022-_Toc482783709\">Cast<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783710\">OfType<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783711\">ToArray<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783712\">ToList<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783713\">ToDictionary<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783714\">ToLookup<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#post-71022-_Toc482783715\">Elements<\/a>\n<ul style=\"margin-bottom: 0; line-height: 20px;\">\n<li><a href=\"#post-71022-_Toc482783716\">First<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783717\">FirstOrDefault<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783718\">Last<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783719\">LastOrDefault<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783720\">ElementAt<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783721\">ElementAtOrDefault<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783722\">Single<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783723\">SingleOrDefault<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#post-71022-_Toc482783724\">Generation<\/a>\n<ul style=\"margin-bottom: 0; line-height: 20px;\">\n<li><a href=\"#post-71022-_Toc482783725\">Range<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783726\">Repeat<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783727\">Empty<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783728\">DefaultIfEmpty<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#post-71022-_Toc482783729\">Grouping<\/a>\n<ul style=\"margin-bottom: 0; line-height: 20px;\">\n<li><a href=\"#post-71022-_Toc482783730\">GroupBy<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#post-71022-_Toc482783731\">Join<\/a>\n<ul style=\"margin-bottom: 0; line-height: 20px;\">\n<li><a href=\"#post-71022-_Toc482783732\">Cross Join<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783733\">Group Join<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783734\">Concat<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783735\">Zip<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#post-71022-_Toc482783736\">Ordering<\/a>\n<ul style=\"margin-bottom: 0; line-height: 20px;\">\n<li><a href=\"#post-71022-_Toc482783737\">OrderBy<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783738\">OrderByDescending<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783739\">ThenBy<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783740\">ThenByDescending<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783741\">Reverse<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#post-71022-_Toc482783742\">Partitioning<\/a>\n<ul style=\"margin-bottom: 0; line-height: 20px;\">\n<li><a href=\"#post-71022-_Toc482783743\">Take<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783744\">Skip<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783745\">TakeWhile<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783746\">SkipWhile<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#post-71022-_Toc482783747\">Projection<\/a>\n<ul style=\"margin-bottom: 0; line-height: 20px;\">\n<li><a href=\"#post-71022-_Toc482783748\">Select<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783749\">SelectMany<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#post-71022-_Toc482783750\">Quantifiers<\/a>\n<ul style=\"margin-bottom: 0; line-height: 20px;\">\n<li><a href=\"#post-71022-_Toc482783751\">Any<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783752\">All<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783753\">Contains<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783754\">SequenceEqual<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#post-71022-_Toc482783755\">Restriction (Filtering)<\/a>\n<ul style=\"margin-bottom: 0; line-height: 20px;\">\n<li><a href=\"#post-71022-_Toc482783756\">Where<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#post-71022-_Toc482783757\">Sets<\/a>\n<ul style=\"margin-bottom: 0; line-height: 20px;\">\n<li><a href=\"#post-71022-_Toc482783758\">Distinct<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783759\">Union<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783760\">Intersection<\/a><\/li>\n<li><a href=\"#post-71022-_Toc482783761\">Except<\/a><\/li>\n<\/ul>\n<\/li>\n<li><a href=\"#post-71022-_Toc482783762\">Conclusion<\/a><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/div>\n<p>You can call LINQ operators directly in PowerShell using static extension method syntax &#8211; [Linq.Enumerable]::MethodName($collection, $delegate) &#8211; to get significant performance improvements over native PowerShell loops, especially on large data sets. PowerShell loops can run 100x slower than equivalent LINQ operations because of interpreted execution overhead and .NET security stack checks. This reference provides working PowerShell examples for every LINQ operator, alongside C# equivalents and native PowerShell alternatives, so you can judge when the LINQ overhead is worth the performance gain.<\/p>\n<p>My recent article <a href=\"https:\/\/www.simple-talk.com\/dotnet\/net-development\/visual-lexicon-linq\/\">A Visual Lexicon of LINQ<\/a> and accompanying <a href=\"https:\/\/www.simple-talk.com\/dotnet\/net-development\/visual-lexicon-linq-wallchart\/\">wallchart<\/a> provided a new, easier-to-use reference for LINQ operators when working in C#. But since one of PowerShell\u2019s mantras is \u201canything you can do in C# can be done in PowerShell, too!\u201d it is only fitting to provide a LINQ reference for PowerShell as well. This reference again itemizes every LINQ operator (and in the same order as the original article) and gives some emphasis to potential performance gains from using LINQ where possible when doing operations on large data sets.<\/p>\n<p>PowerShell is an interpreted scripting language, and so is slow at using an iterative loop of any great size. By \u2018slow\u2019, it can be the difference between <a href=\"https:\/\/blogs.msdn.microsoft.com\/anantd\/2014\/07\/25\/why-cant-powershell-run-loops-fast\/\">ten minutes in PowerShell as opposed to six seconds in C#<\/a>! If a loop iterates more than sixteen times, the code of the loop is compiled dynamically as .NET code and the dynamic method is then invoked inside the loop. Also, because any scripting language presents a potential security risk, .NET must run a security check on the stack, which slows the loop down. LINQ has many aggregate and filtering functions that can be used instead of the PowerShell equivalent, and they are very likely to give you an appreciable performance improvement\u2014but at the cost of a tedious overhead in writing the script, as detailed next.<\/p>\n<h2><a id=\"post-71022-_Toc482783690\"><\/a>General Notes<\/h2>\n<p>Why do I mention a tedious overhead of use? In PowerShell, it is straightforward to access conventional C# methods\u2014for example,<span style=\"color: #996633; font-weight: bold;\"><code>\"abc\".Replace(\"a\", \"A\")<\/code><\/span> works just fine in PowerShell. However, most LINQ operators are static extension methods and many of those require delegate arguments, so invoking them from PowerShell is more involved. (You could say that technically those arguments are <em>anonymous functions<\/em> or even <em>lambda expressions<\/em> but I\u2019ve chosen to use the term <em>delegate<\/em> here as it is shorter and practically equivalent in this context.) For this reason, I\u2019ve given, in this article working examples of the use of every LINQ operator, along with the C# equivalent and the conventional PowerShell way of doing the same thing. This should enable you to judge for yourself.<br \/><strong>Read also:<\/strong> <a href=\"https:\/\/www.red-gate.com\/simple-talk\/sysadmin\/powershell\/how-to-use-parameters-in-powershell\/\"><span data-sheets-root=\"1\">PowerShell parameters and script fundamentals<\/span><\/a><br \/><br \/><br \/><\/p>\n<h3><a id=\"post-71022-_Toc482783691\"><\/a>Format of Entries<\/h3>\n<p>For each entry you will find:<\/p>\n<ol>\n<li>A useful yet simple (or simple-ish) example of how to use the LINQ operator in C# as a reference point.<\/li>\n<li>A translation of that example into PowerShell, i.e. calling the actual LINQ operator from PowerShell.<\/li>\n<li>An alternate version of code to perform the same operation using <a href=\"https:\/\/www.red-gate.com\/simple-talk\/sysadmin\/powershell\/powershell-functions-reusability-restartability-azure\/\">native PowerShell<\/a> (i.e. doing it \u201cthe PowerShell way\u201d).<\/li>\n<\/ol>\n<h3><a id=\"post-71022-_Toc482783692\"><\/a>Deferred vs. Immediate Execution<\/h3>\n<p>Unlike conventional functions and methods, many LINQ methods use <em>deferred execution<\/em> instead of <em>immediate execution<\/em>. That is, an expression with some LINQ operators does not actually calculate and yield a result until it is actually needed. (The <a href=\"https:\/\/www.simple-talk.com\/dotnet\/net-development\/visual-lexicon-linq-wallchart\/\">wallchart<\/a> shows you at a glance which operators this applies to.) Rather, those operators return a query (essentially an <span style=\"color: #996633; font-weight: bold;\"><code>IEnumerable&lt;T&gt;<\/code><\/span>). Unless you are doing further LINQ operations on it, you need to convert it with a LINQ operator that materializes the result to work with it further in PowerShell; <span style=\"color: green; font-weight: bold;\"><code>ToArray<\/code><\/span> or <span style=\"color: green; font-weight: bold;\"><code>ToList<\/code><\/span> are the most common LINQ methods for doing that.<\/p>\n<h3><a id=\"post-71022-_Toc482783693\"><\/a>Calling a LINQ Operator<\/h3>\n<p>LINQ operators are <em>static extension methods<\/em>. In PowerShell plain <em>static<\/em> method calls require this syntax:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">[ClassName]::MethodName(arguments...)<\/pre>\n<p><em>Extension<\/em> methods in C#, as you\u2019ll recall, look like any other method available from an object, e.g.<\/p>\n<pre class=\"theme:vs2012 lang:cs decode:true\">ObjectInstance.MethodName(arguments...)<\/pre>\n<p>But in PowerShell, the <span style=\"color: #996633; font-weight: bold;\"><code>ObjectInstance<\/code><\/span> moves into the first argument position of the static call:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">[ClassName]::MethodName(ObjectInstance, arguments...)<\/pre>\n<p>The only other piece you need to know is the <span style=\"color: #996633; font-weight: bold;\"><code>ClassName<\/code><\/span> to use, which will always be <span style=\"color: #996633; font-weight: bold;\"><code>Linq.Enumerable<\/code><\/span>. Thus, <span style=\"color: #996633; font-weight: bold;\"><code>numbers.Sum()<\/code><\/span> in C# becomes <span style=\"color: #996633; font-weight: bold;\"><code>[Linq.Enumerable]::Sum($numbers)<\/code><\/span> in PowerShell. However, that will only work if the <span style=\"color: #996633; font-weight: bold;\"><code>$numbers<\/code><\/span> array has the correct type and by default it does <em>not<\/em>. The next section explains further.<\/p>\n<h3><a id=\"post-71022-_Toc482783694\"><\/a>Explicit Argument Typing<\/h3>\n<p>PowerShell is a dynamically typed language rather than a statically typed language. And it is not strongly-typed (because a variable can change its type at runtime). But PowerShell does support explicit typing of variables if you choose to use it\u2014and for LINQ calls you have no choice in the matter! Consider the rather innocuous LINQ call in C#:<\/p>\n<pre class=\"theme:vs2012 lang:cs decode:true\">Enumerable.Range(0, 100).Sum()<\/pre>\n<p>This would seem to translate to PowerShell readily as:<\/p>\n<pre class=\"theme:vs2012 lang:cs decode:true\">[Linq.Enumerable]::Sum(0..100)<\/pre>\n<p>Unfortunately, the result of that expression is an error:<\/p>\n<p><em>Cannot find an overload for &#8220;Sum&#8221; and the argument count: &#8220;1&#8221;. <\/em><\/p>\n<p>That error makes you think the argument count is wrong but in fact it is the type of the argument that is incorrect, as we can demonstrate.<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; (0..100).GetType().Name\nObject[]\n<\/pre>\n<p>The <span style=\"color: green; font-weight: bold;\"><code>Sum<\/code><\/span> method does not take an <span style=\"color: #996633; font-weight: bold;\"><code>Object<\/code><\/span> array, but it has overloads for a variety of numerical types. Thus you need to explicitly type the array; here is one way to do that:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [Linq.Enumerable]::Sum([int[]]@(0..100))\n5050 \n<\/pre>\n<h3><a id=\"post-71022-_Toc482783695\"><\/a>Creating and Passing Delegates<\/h3>\n<p>Passing simple arguments to LINQ, as just shown, require explicit typing. This is even more important when using a LINQ operator with an argument that is a delegate (or anonymous function). Consider the ubiquitous <span style=\"color: green; font-weight: bold;\"><code>Where<\/code><\/span> operator. Let\u2019s say you have an array of date objects and you wish to filter those. In C# you might write:<\/p>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var result = dates.Where(d =&gt; d.Year &gt; 2016);<\/pre>\n<p>In PowerShell, you write the equivalent delegate like this:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [Func[DateTime,bool]] $delegate = { param($d); return $d.Year -gt 2016 }<\/pre>\n<p>Then can make the call:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [Linq.Enumerable]::Where($dates, $delegate)<\/pre>\n<p>Or if you prefer to write a single expression, you still need explicit typing (I\u2019ve added line breaks just for clarity):<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">[Linq.Enumerable]::Where(\n    $dates,\n    [Func[DateTime,bool]] { param($d); return $d.Year -gt 2016 }\n)\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783696\"><\/a>Generic LINQ Operators<\/h3>\n<p>Just 3 LINQ operators are generic: <span style=\"color: green; font-weight: bold;\"><code>Cast<\/code><\/span>, <span style=\"color: green; font-weight: bold;\"><code>OfType<\/code><\/span>, and <span style=\"color: green; font-weight: bold;\"><code>Empty<\/code><\/span>. As it turns out, calling a generic, static, extension LINQ method requires a rather convoluted incantation in PowerShell. Consider this standard LINQ call in C# to filter a list to just strings:<\/p>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var stuff = new object[] { \"12345\", 12, \"def\" };\nvar stringsInList = stuff.OfType&lt;string&gt;();\n<\/pre>\n<p>The first step for PowerShell conversion, oddly enough is to rewrite that\u2014still in C#\u2014 so that it can be translated to PowerShell (yes, I know this is ugly!):<\/p>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var stuff = new object[] { \"12345\", 12, \"def\" };\nvar ofTypeForString = typeof(System.Linq.Enumerable)\n    .GetMethod(\"OfType\")\n    .MakeGenericMethod(typeof(string));\nvar stringsInList = ofTypeForString.Invoke(null, new[] { stuff });\n<\/pre>\n<p>But now, you <em>can<\/em> get there from here (i.e. you can write it in PowerShell):<\/p>\n<pre class=\"crayon:false\" style=\"color: white; white-space: pre; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; line-height: 130%; padding: 8px; background: #1F3864; margin: 4px 0in 4px 0px;\">PS&gt; $stuff = @(\"12345\", 12, \"def\")\nPS&gt; $stringType = \"\".GetType() <span style=\"color: green;\"># set to your target type<\/span>\nPS&gt; $ofTypeForString =\n    [Linq.Enumerable].GetMethod(\"OfType\").MakeGenericMethod($stringType)\n<span style=\"color: green;\"># The last comma below wraps the array arg $stuff within another array<\/span>\nPS&gt; $ofTypeForString.Invoke($null, (,$stuff))\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783697\"><\/a>LINQ Chaining<\/h3>\n<p>One of the strong benefits of LINQ is its chaining capability. Here\u2019s a simple example in C#:<\/p>\n<pre>var result = dates.OrderBy(d =&gt; d.Year).ThenBy(d =&gt; d.Month);<\/pre>\n<p>While you can still do this in PowerShell, it unfortunately does not allow that wonderfully smooth fluent syntax because of the way you have to write calls to extension methods explained above. You are limited to only conventional method calls:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">[Linq.Enumerable]::ThenBy(\n        [Linq.Enumerable]::OrderBy($dates, $yearDelegate),\n        $monthDelegate)\n<\/pre>\n<h2><a id=\"post-71022-_Toc482783698\"><\/a>Performance<\/h2>\n<p>Why bother with all this tedious overhead mentioned so far? In a word, performance! PowerShell was never designed to compete in terms of speed with the likes of C#. And most of the time that is perfectly fine. With small data structures or simple programs you may never even notice performance that is sub-optimal. But PowerShell is a first-class language, so you <em>could<\/em> write elaborate code dealing with huge data structures. That is when performance should definitely be kept in mind.<\/p>\n<p>First, here\u2019s a handy little function showing one way to measure performance. Note that if you just want the performance numbers, the built-in <span style=\"color: #996633; font-weight: bold;\"><code>Measure-Command<\/code><\/span> cmdlet would work fine, but I wanted to get <em>two<\/em> outputs: the performance <em>and<\/em> the actual result of the evaluation (the reason for this is explained just a bit further down).<\/p>\n<pre class=\"theme:powershell-ise lang:ps decode:true\">function Measure-Expression($codeAsString)\n{\n    $stopwatch = [system.diagnostics.stopwatch]::startNew() \n    $result = Invoke-Expression $codeAsString\n    $stopwatch.Stop()\n    'result={0}, milliseconds={1,10}' `\n        -f $result, $stopwatch.Elapsed.TotalMilliseconds.ToString(\"0.0\")\n}\n<\/pre>\n<p>To use this, simply wrap the expression you wish to evaluate in a string and pass it to the function. This code compares the LINQ <span style=\"color: green; font-weight: bold;\"><code>Sum<\/code><\/span> method with three other ways to do the same thing in native PowerShell:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">[int[]] $numbers = 1..10000\nMeasure-Expression '[Linq.Enumerable]::Sum($numbers)'\nMeasure-Expression '($numbers | Measure-Object -sum).Sum'\nMeasure-Expression '$numbers | ForEach { $sum += $_ } -Begin { $sum = 0 } -End { $sum }\u2019\nMeasure-Expression '$sum = 0; foreach ($n in $numbers) { $sum += $n }; $sum'\n<\/pre>\n<p>It has long been known that the <span style=\"color: #996633; font-weight: bold;\"><code>foreach<\/code><\/span> operator is much more snappy than piping data to the <span style=\"color: #996633; font-weight: bold;\"><code>ForEach-Object<\/code><\/span> cmdlet (see e.g. Thomas Lee\u2019s <a href=\"http:\/\/tfl09.blogspot.com\/2011\/11\/performance-with-powershell.html\">Performance with PowerShell<\/a> ). Also, <a href=\"https:\/\/msdn.microsoft.com\/en-us\/powershell\/wmf\/5.1\/engine-improvements\">PowerShell Engine Improvements<\/a> reveals that WMF 5.1 (released January 2017) has made substantial improvements in the core PowerShell engine; of specific interest is that piping to the <span style=\"color: #996633; font-weight: bold;\"><code>ForEach-Object<\/code><\/span> cmdlet is twice as fast as it used to be (but still <span style=\"color: #996633; font-weight: bold;\"><code>foreach<\/code><\/span> prevails). Also, be sure to take a look at the short list of <a href=\"https:\/\/docs.microsoft.com\/en-us\/windows-server\/administration\/performance-tuning\/powershell\/script-authoring-considerations\">PowerShell scripting performance considerations<\/a> from Microsoft.<\/p>\n<p>Those considerations are important, yes, but take a look at the actual results here: LINQ outperforms even the best native PowerShell by an order of magnitude!<\/p>\n<table>\n<thead>\n<tr>\n<td>\n<p>Basic Command<\/p>\n<\/td>\n<td>\n<p>Time (milliseconds)<\/p>\n<\/td>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>\n<p>[Linq.Enumerable]::Sum($numbers)<\/p>\n<\/td>\n<td>\n<p>0.4<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>($numbers | Measure-Object -sum).Sum<\/p>\n<\/td>\n<td>\n<p>79.8<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>$numbers | ForEach { $sum += $_ } -Begin { $sum = 0 } -End { $sum }<\/p>\n<\/td>\n<td>\n<p>156.0<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p>$sum = 0; foreach ($n in $numbers) { $sum += $n }; $sum<\/p>\n<\/td>\n<td>\n<p>29.5<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>One minor detail to note on the above figures: The first time you invoke a LINQ expression in a PowerShell session there is some overhead loading the assembly. That slows down the performance by an order of magnitude\u2014so that it is only as fast as the fastest native PowerShell call (the <span style=\"color: #996633; font-weight: bold;\"><code>foreach<\/code><\/span> loop). But for every invocation thereafter in the same session, you get the much faster execution times.<\/p>\n<p>Note that I am not claiming that every LINQ operator will show this dramatic performance difference. It seems to hold true for the important aggregate operators like <span style=\"color: green; font-weight: bold;\"><code>Sum<\/code><\/span> (<span style=\"color: green; font-weight: bold;\"><code>Count<\/code><\/span>, <span style=\"color: green; font-weight: bold;\"><code>Average<\/code><\/span>, etc.) but I have not performance-tested the whole gamut of other LINQ operators.<\/p>\n<p>One final consideration when doing performance studies of LINQ operators in PowerShell: you need to take into account whether the operator uses deferred or immediate execution. <span style=\"color: green; font-weight: bold;\"><code>Sum<\/code><\/span>, used in the above example, uses immediate execution. That is, it produces an output that can be consumed by the rest of your PowerShell code. So if you are comparing a LINQ expression with a non-LINQ one, make sure you\u2019re comparing like expressions. That is, if you use an operator with deferred execution, you need to include something like a <span style=\"color: green; font-weight: bold;\"><code>ToArray<\/code><\/span> call to realize the results as part of your measurement. That\u2019s why I wrote the <span style=\"color: #996633; font-weight: bold;\"><code>Measure-Expression<\/code><\/span> function above to report not just the execution time but also the result of the expression; you will see right away if you\u2019re doing a valid \u201capples-to-apples\u201d comparison.<br \/><strong>Read also:\u00a0<\/strong><a href=\"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/performance-sql-server\/how-to-avoid-conditional-joins-in-t-sql\/\"><span data-sheets-root=\"1\">SQL Server performance tuning strategies<\/span><\/a><\/p>\n<h2><a id=\"post-71022-_Toc482783699\"><\/a>LINQ to PowerShell Lexicon<\/h2>\n<h2><a id=\"post-71022-_Toc482783700\"><\/a>Aggregate<\/h2>\n<h3><a id=\"post-71022-_Toc482783701\"><\/a>Count<\/h3>\n<p>Returns the number of elements in a sequence. When the result is expected to be greater than <span style=\"color: #996633; font-weight: bold;\"><code>Int32.MaxValue()<\/code><\/span>, use <span style=\"color: green; font-weight: bold;\"><code>LongCount<\/code><\/span>. If you specify an optional condition, <span style=\"color: green; font-weight: bold;\"><code>Count<\/code><\/span> returns the number of elements in a sequence that satisfies that condition.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">int[] numbers = { 3, 1, 4, 1, 5, 9, 2 };\nvar countAll = numbers.Count();\nvar countSome = numbers.Count(n =&gt; n &gt; 2);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [int[]] $numbers = @(3, 1, 4, 1, 5, 9, 2)\nPS&gt; [Linq.Enumerable]::Count($numbers)\n7\nPS&gt; [Linq.Enumerable]::Count($numbers, [Func[int,bool]] { $args[0] -gt 2 })\n4\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; $numbers.Count\n7\nPS&gt; $numbers.Count | Where { $_ -gt 2 }\n4\n<\/pre>\n<p>or<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; ($numbers | Measure-Object).Count\n7\nPS&gt; ($numbers | Where { $_ -gt 2 } | Measure-Object).Count\n4\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783702\"><\/a>LongCount<\/h3>\n<p>Returns <em>as an Int64<\/em> the number of elements in a sequence. Use <span style=\"color: green; font-weight: bold;\"><code>LongCount<\/code><\/span> rather than <span style=\"color: green; font-weight: bold;\"><code>Count<\/code><\/span> when the result is expected to be greater than <span style=\"color: #996633; font-weight: bold;\"><code>Int32.MaxValue()<\/code><\/span>. <span style=\"color: green; font-weight: bold;\"><code>LongCount<\/code><\/span>, like <span style=\"color: green; font-weight: bold;\"><code>Count<\/code><\/span>, allows an optional condition.<\/p>\n<p>Works identically to <span style=\"color: green; font-weight: bold;\"><code>Count<\/code><\/span>.<\/p>\n<h3><a id=\"post-71022-_Toc482783703\"><\/a>Sum<\/h3>\n<p>Computes the <em>sum<\/em> of a sequence of values. If you specify an optional transformation function, <span style=\"color: green; font-weight: bold;\"><code>Sum<\/code><\/span> computes the sum of a sequence of values after applying that transformation on each element.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">int[] numbers = Enumerable.Range(1, 10000);\nFunc&lt;int,int&gt; func = n =&gt; n % 3 ? n : -n;\n\nvar sumOriginal = numbers.Sum();\nvar sumConverted = numbers.Sum(func));\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [int[]] $numbers = 1..10000\nPS&gt; [Func[int,int]] $delegate = { param ($n); if ($n % 3) { $n } else { -$n } }\n\nPS&gt; [Linq.Enumerable]::Sum($numbers)\nPS&gt; [Linq.Enumerable]::Sum($numbers, $delegate)\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"crayon:false\" style=\"color: white; white-space: pre; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; line-height: 130%; padding: 8px; background: #00284d; margin: 4px 0in 4px 0px;\">PS&gt; [int[]] $numbers = 1..10000\nPS&gt; function func($n) { if ($n % 3) { $n } else { -$n } }\n\n<span style=\"color: green;\"><span style=\"color: green;\"># basic command<\/span><\/span>\nPS&gt; ($numbers | Measure-Object -Sum).Sum\nPS&gt; $numbers | ForEach { $sum += $_ } -Begin { $sum = 0 } -End { $sum }\nPS&gt; $sum = 0; foreach ($n in $numbers) { $sum += $n }; $sum\n\n<span style=\"color: green;\"><span style=\"color: green;\"># command with transformation<\/span><\/span>\nPS&gt; ($numbers | ForEach { func $_  } | Measure-Object -Sum).Sum\nPS&gt; $sum = 0; foreach ($n in $numbers) { $sum += func $n }; $sum\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783704\"><\/a>Average<\/h3>\n<p>Computes the <em>average<\/em> of a sequence of values. If you specify an optional transformation function, <span style=\"color: green; font-weight: bold;\"><code>Average<\/code><\/span> computes the average of a sequence of values after applying that transformation on each element.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">int[] numbers = Enumerable.Range(1, 10000);\nFunc&lt;int,int&gt; func = n =&gt; n % 5 ? 100*n : n;\n\nvar averageOriginal = numbers.Average();\nvar averageConverted = numbers.Average(func));\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [int[]] $numbers = 1..10000\nPS&gt; [Func[int,int]] $delegate = { param ($n); if ($n % 5) { 100 * $n } else { $n } }\n\nPS&gt; [Linq.Enumerable]::Average($numbers)\nPS&gt; [Linq.Enumerable]::Average($numbers, $delegate)\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"crayon:false\" style=\"color: white; white-space: pre; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; line-height: 130%; padding: 8px; background: #00284d; margin: 4px 0in 4px 0px;\">PS&gt; [int[]] $numbers = 1..10000\nPS&gt; function func($n) { if ($n % 5) { 100 * $n } else { $n } }\n\n<span style=\"color: green;\"><span style=\"color: green;\"># basic command<\/span><\/span>\nPS&gt; ($numbers | Measure-Object -Average).Average\nPS&gt; $numbers | ForEach { $sum += $_ } -Begin { $sum = 0 } -End { $sum \/ $numbers.Length }\nPS&gt; $sum = 0; foreach ($n in $numbers) { $sum += $n }; $sum \/ $numbers.Length\n\n<span style=\"color: green;\"><span style=\"color: green;\"># command with transformation<\/span><\/span>\nPS&gt; ($numbers | ForEach { func $_  } | Measure-Object -Average).Average\nPS&gt; $sum = 0; foreach ($n in $numbers) { $sum += func $n }; $sum \/ $numbers.Length\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783705\"><\/a>Max<\/h3>\n<p>Returns the <em>maximum<\/em> value in a sequence. If you specify an optional transformation function, <span style=\"color: green; font-weight: bold;\"><code>Max <\/code><\/span>returns the maximum value in a sequence after applying that transformation on each element.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">int[] numbers = Enumerable.Range(1, 10000);\nFunc&lt;int,int&gt; func = n =&gt; n % 5 ? 100*n : n;\n\nvar maximumOriginal = numbers.Max();\nvar maximumConverted = numbers.Max(func));\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [int[]] $numbers = 1..10000\nPS&gt; [Func[int,int]] $delegate = { param ($n); if ($n % 5) { 100 * $n } else { $n } }\n\nPS&gt; [Linq.Enumerable]::Max($numbers)\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"crayon:false\" style=\"color: white; white-space: pre; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; line-height: 130%; padding: 8px; background: #00284d; margin: 4px 0in 4px 0px;\">PS&gt; [int[]] $numbers = 1..10000\nPS&gt; function func($n) { if ($n % 5) { 100 * $n } else { $n } }\n\n<span style=\"color: green;\"><span style=\"color: green;\"># basic command<\/span><\/span>\nPS&gt; ($numbers | Measure-Object -Maximum).Maximum\nPS&gt; $numbers | ForEach {if ($_ -gt $max) {$max=$_}} -Begin {$max=[int]::MinValue} -End {$max}\nPS&gt; $max=[int]::MinValue; foreach ($n in $numbers) { if ($n -gt $max) {$max=$n}}; $max\n\n<span style=\"color: green;\"><span style=\"color: green;\"># command with transformation<\/span><\/span>\nPS&gt; ($numbers | ForEach { func $_  } | Measure-Object -Maximum).Maximum\nPS&gt; $max=[int]::MinValue; foreach ($n in $numbers) {$n=func $n; if ($n -gt $max) {$max=$n}}; $max\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783706\"><\/a>Min<\/h3>\n<p>Returns the <em>minimum<\/em> value in a sequence. If you specify an optional transformation function, <span style=\"color: green; font-weight: bold;\"><code>Min<\/code><\/span> returns the minimum value in a sequence after applying that transformation on each element.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">int[] numbers = Enumerable.Range(1, 10000);\nFunc&lt;int,int&gt; func = n =&gt; n % 5 ? 100*n : n;\n\nvar maximumOriginal = numbers.Min();\nvar maximumConverted = numbers.Min(func));\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [int[]] $numbers = 1..10000\nPS&gt; [Func[int,int]] $delegate = { param ($n); if ($n % 5) { -100 * $n } else { $n } }\n\nPS&gt; [Linq.Enumerable]::Min($numbers)\nPS&gt; [Linq.Enumerable]::Min($numbers, $delegate)\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"crayon:false\" style=\"color: white; white-space: pre; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; line-height: 130%; padding: 8px; background: #00284d; margin: 4px 0in 4px 0px;\">PS&gt; [int[]] $numbers = 1..10000\nPS&gt; function func($n) { if ($n % 5) { -100 * $n } else { $n } }\n\n<span style=\"color: green;\"># basic command<\/span>\nPS&gt; ($numbers | Measure-Object -Minimum).Minimum\nPS&gt; $numbers | ForEach {if ($_ -lt $min) {$min=$_}} -Begin {$min=[int]::MaxValue} -End {$min}\nPS&gt; $min=[int]::MaxValue; foreach ($n in $numbers) { if ($n -lt $min) {$min=$n}}; $min\n\n<span style=\"color: green;\"># command with transformation<\/span>\nPS&gt; ($numbers | ForEach { func $_  } | Measure-Object -Minimum).Minimum\nPS&gt; $min=[int]::MaxValue; foreach ($n in $numbers) {$n=func $n; if ($n -lt $min) {$min=$n}}; $min\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783707\"><\/a>Aggregate<\/h3>\n<p>Applies an accumulator function over a sequence. You specify a two-argument function to perform an arbitrary aggregation function of your choice. The first parameter is the accumulated results so far, which is initialized to the default value for the element type, and the second parameter is the sequence element.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">int[] numbers = { 5, 4, 1, 3, 9 };\n\nvar result = numbers.Aggregate(\n\t(resultSoFar, next) =&gt; resultSoFar * next);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [int[]]$numbers = @( 5, 4, 1, 3, 9 )\nPS&gt; [Func[int,int,int]] $delegate = { param($resultSoFar, $next); $resultSoFar * $next }\nPS&gt; [Linq.Enumerable]::Aggregate($numbers, $delegate)\n540\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; $numbers | ForEach-Object { $result = 1 } { $result *= $_ } { $result }\n540\n<\/pre>\n<p>If you specify an initial seed, <span style=\"color: green; font-weight: bold;\"><code>Aggregate<\/code><\/span> applies an accumulator function over a sequence with that initial seed value. While the seed could just be (depending on your needs) some constant integer or constant string, it could also create an object that your accumulator function will call methods against, as shown next. Here a <span style=\"color: #996633; font-weight: bold;\"><code>StringBuilder<\/code><\/span> is created that is used in each step of the aggregation.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var words = new[] { \"w1\", \"w2\", \"w3\", \"w4\" };\n\nvar text = words.Aggregate(\n\tnew StringBuilder(),\n\t(a, b) =&gt; a.Append(b + '.')\n);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [string[]]$words = @(\"w1\", \"w2\", \"w3\", \"w4\")\nPS&gt; $delegate = [Func[System.Text.StringBuilder, string, System.Text.StringBuilder]]\n{ param($builder, $s); $builder.Append($s + '.')}\nPS&gt; [Linq.Enumerable]::Aggregate(\n        $words,\n        [System.Text.StringBuilder]::new(),\n        $delegate\n    ).ToString()\nw1.w2.w3.w4.\n<\/pre>\n<h2><a id=\"post-71022-_Toc482783708\"><\/a>Conversion<\/h2>\n<h3><a id=\"post-71022-_Toc482783709\"><\/a>Cast<\/h3>\n<p>Casts the elements of an <span style=\"color: #996633; font-weight: bold;\"><code>IEnumerable<\/code><\/span> to the specified type, effectively converting <span style=\"color: #996633; font-weight: bold;\"><code>IEnumerable<\/code><\/span> to <span style=\"color: #996633; font-weight: bold;\"><code>IEnumerable&lt;T&gt;<\/code><\/span>, which then makes the sequence amenable to further LINQ operations. Alternately, it can be used like <span style=\"color: green; font-weight: bold;\"><code>OfType<\/code><\/span> which filters based on a specified type. However, whereas <span style=\"color: green; font-weight: bold;\"><code>OfType<\/code><\/span> ignores members that are not convertible to the target type, <span style=\"color: green; font-weight: bold;\"><code>Cast<\/code><\/span> throws an exception when it encounters such members, as the examples here reveal.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var stuff = new object[] { \"12345\", 12, \"def\" };\nvar stringsInList = stuff.Cast(); \/\/ throws exception because of the int in the array\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<p>As discussed in the introduction, generic calls need to be rewritten before being translated:<\/p>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var stuff = new object[] { \"12345\", 12, \"def\" };\nvar castForString = typeof(System.Linq.Enumerable)\n    .GetMethod(\"Cast\")\n    .MakeGenericMethod(typeof(string));\nvar stringsInList = castForString.Invoke(null, new[] { stuff }); \/\/ throws exception due to int\n<\/pre>\n<p>And that translates to PowerShell as:<\/p>\n<pre class=\"crayon:false\" style=\"color: white; white-space: pre; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; line-height: 130%; padding: 8px; background: #00284d; margin: 4px 0in 4px 0px;\">PS&gt; $stuff = @(\"12345\", 12, \"def\")\nPS&gt; $stringType = \"\".GetType() <span style=\"color: green;\"># set to your target type<\/span>\nPS&gt; $castForString =\n    [Linq.Enumerable].GetMethod(\"Cast\").MakeGenericMethod($stringType)\n<span style=\"color: green;\"># The last comma below wraps the array arg $stuff within another array<\/span>\nPS&gt; $castForString.Invoke($null, (,$stuff))\n<span style=\"color: red;\">Unable to cast object of type 'System.Int32' to type 'System.String'<\/span> \n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"crayon:false\" style=\"color: white; white-space: pre; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; line-height: 130%; padding: 8px; background: #00284d; margin: 4px 0in 4px 0px;\">PS&gt; $stuff = @(\"12345\", 12, \"def\")\nPS&gt; $stuff | ForEach-Object {\n        if ($_ -is [string]) { $_ } else { throw \"$($_): incompatible type\" }\n    }\n<span style=\"color: red;\">12: incompatible type<\/span> \n<\/pre>\n<h3><a id=\"post-71022-_Toc482783710\"><\/a>OfType<\/h3>\n<p>Filters the elements of an <span style=\"color: #996633; font-weight: bold;\"><code>IEnumerable<\/code><\/span> based on a specified type.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var stuff = new object[] { \"12345\", 12, \"def\" };\nvar stringsInList = stuff.OfType&lt;string&gt;();\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<p>As discussed in the introduction, generic calls need to be rewritten before being translated:<\/p>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var stuff = new object[] { \"12345\", 12, \"def\" };\nvar ofTypeForString = typeof(System.Linq.Enumerable)\n    .GetMethod(\"OfType\")\n    .MakeGenericMethod(typeof(string));\nvar stringsInList = ofTypeForString.Invoke(null, new[] { stuff });\n<\/pre>\n<p>And that translates to PowerShell as:<\/p>\n<pre class=\"crayon:false\" style=\"color: white; white-space: pre; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; line-height: 130%; padding: 8px; background: #00284d; margin: 4px 0in 4px 0px;\">PS&gt; $stuff = @(\"12345\", 12, \"def\")\nPS&gt; $stringType = \"\".GetType() <span style=\"color: green;\"># set to your target type<\/span>\nPS&gt; $ofTypeForString =\n    [Linq.Enumerable].GetMethod(\"OfType\").MakeGenericMethod($stringType)\n<span style=\"color: green;\"># The last comma below wraps the array arg $stuff within another array<\/span>\nPS&gt; $ofTypeForString.Invoke($null, (,$stuff)) \n12345\ndef\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">  $stuff | Where-Object { $_ -is [string] }\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783711\"><\/a>ToArray<\/h3>\n<p>Creates an array from an <span style=\"color: #996633; font-weight: bold;\"><code>IEnumerable&lt;T&gt;<\/code><\/span>.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var query = Enumerable.Range(0, 4);\nvar array = query.ToArray();\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">$query = [Linq.Enumerable]::Range(0,4)\n$array = [Linq.Enumerable]::ToArray($query)\n<\/pre>\n<p>If you have a deferred LINQ query, you can view its result set in PowerShell as if it were seemingly an array or list but you cannot access its member elements until you actually complete the LINQ invocation. An example shows this simply. Here, <span style=\"color: #996633; font-weight: bold;\"><code>$query<\/code><\/span> looks like an array or list when evaluated in line (2), but line (3) shows it is not:<\/p>\n<pre class=\"crayon:false\" style=\"color: white; white-space: pre; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; line-height: 130%; padding: 8px; background: #00284d; margin: 4px 0in 4px 0px;\">(1)&gt; $query = [Linq.Enumerable]::Range(0,4)\n(2)&gt; $query\n0\n1\n2\n3\n(3)&gt; $query[3]\n<span style=\"color: red;\">Unable to index into an object of type System.Linq.Enumerable+&lt;RangeIterator&gt;d__110<\/span>\n<\/pre>\n<p>Rather, you need to use <span style=\"color: green; font-weight: bold;\"><code>ToArray<\/code><\/span> to realize the results of the query:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">(1)&gt; $query = [Linq.Enumerable]::Range(0,4)\n(2)&gt; $array = [Linq.Enumerable]::ToArray($query)\n(3)&gt; $array.GetType.Name\nInt32[]\n(4) $array[3]\n3\n(5) $array[3].GetType().Name\nInt32\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783712\"><\/a>ToList<\/h3>\n<p>Creates a <span style=\"color: #996633; font-weight: bold;\"><code>List&lt;T&gt;<\/code><\/span> from an <span style=\"color: #996633; font-weight: bold;\"><code>IEnumerable&lt;T&gt;<\/code><\/span>.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var query = Enumerable.Range(0, 4);\nvar list = query.ToList();\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">$query = [Linq.Enumerable]::Range(0,4)\n$list = [Linq.Enumerable]::ToList($query)\n<\/pre>\n<p>If you have a deferred LINQ query, you can view its result set in PowerShell as if it were seemingly an array or list but you cannot access its member elements until you actually complete the LINQ invocation. An example shows this simply. Here, <span style=\"color: #996633; font-weight: bold;\"><code>$query<\/code><\/span> looks like an array or list when evaluated in line (2), but line (3) shows it is not:<\/p>\n<pre class=\"crayon:false\" style=\"color: white; white-space: pre; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; line-height: 130%; padding: 8px; background: #00284d; margin: 4px 0in 4px 0px;\">(1)&gt; $query = [Linq.Enumerable]::Range(0,4)\n(2)&gt; $query\n0\n1\n2\n3\n(3)&gt; $query[3]\n<span style=\"color: red;\">Unable to index into an object of type System.Linq.Enumerable+&lt;RangeIterator&gt;d__110<\/span>\n<\/pre>\n<p>Rather, you need to use <span style=\"color: green; font-weight: bold;\"><code>ToList<\/code><\/span> to realize the results of the query:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">(1)&gt; $query = [Linq.Enumerable]::Range(0,4)\n(2)&gt; $list = [Linq.Enumerable]::ToList($query)\n(3)&gt; $list.GetType.Name\nList`1\n(4) $list[3]\n3\n(5) $list[3].GetType().Name\nInt32\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783713\"><\/a>ToDictionary<\/h3>\n<p>Creates a <span style=\"color: #996633; font-weight: bold;\"><code>Dictionary&lt;TKey,\u2002TValue&gt;<\/code><\/span> from an <span style=\"color: #996633; font-weight: bold;\"><code>IEnumerable&lt;T&gt;<\/code><\/span> according to a specified key selector function (<span style=\"color: #996633; font-weight: bold;\"><code>person =&gt; person.SSN<\/code><\/span> in this example).<\/p>\n<p>A <span style=\"color: #996633; font-weight: bold;\"><code>Dictionary<\/code><\/span> is a one-to-one map, and is editable after creation. Querying on a non-existent key throws an exception. Contrast this with <span style=\"color: green; font-weight: bold;\"><code>ToLookup<\/code><\/span>.<\/p>\n<p>(C# adapted from <a href=\"https:\/\/weblogs.asp.net\/psteele\/linq-quickly-create-dictionaries-with-todictionary\">LINQ: Quickly Create Dictionaries with ToDictionary<\/a>.)<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">class Person\n{\n    public string SSN { get; set; }\n    public string FirstName { get; set; }\n    public string Surname { get; set; }\n}\nvar peopleList = new List&lt;Person&gt; {\n    new Person {SSN = \"1001\", FirstName = \"Bob\", Surname = \"Smith\"},\n    new Person {SSN = \"2002\", FirstName = \"Jane\", Surname = \"Doe\"},\n    new Person {SSN = \"3003\", FirstName = \"Fester\", Surname = \"Adams\"}\n};\n\nVar peopleDict  = peopleList.ToDictionary(person =&gt; person.SSN);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">class Person\n{\n    [string] $SSN;\n    [string] $FirstName;\n    [string] $Surname;\n\n    Person([string]$SSN, [string]$firstname, [string]$surname)\n    {\n        $this.Surname = $surname\n        $this.FirstName = $firstname\n        $this.SSN = $ssn\n    }\n}\n\n[Person[]]$peopleList = @(\n    [Person]::new(\"1001\", \"Bob\", \"Smith\"),\n    [Person]::new(\"2002\", \"Jane\", \"Doe\"),\n    [Person]::new(\"3003\", \"Fester\", \"Adams\")\n)\nPS&gt; $keyDelegate = [Func[Person,string]] { $args[0].SSN }\nPS&gt; $dict = [Linq.Enumerable]::ToDictionary($peopleList, $keyDelegate)\nPS&gt; $dict\n\nKey  Value \n---  ----- \n1001 Person\n2002 Person\n3003 Person\n\nPS&gt; $dict['1001']\n\nSSN  FirstName Surname\n---  --------- -------\n1001 Bob       Smith\n<\/pre>\n<p>The value of the dictionary entry (<span style=\"color: #996633; font-weight: bold;\"><code>TValue<\/code><\/span>) is just the current input element from the sequence unless you specify the optional element selector function, in which case the value is computed with that function. The next example creates a composite full name for the value.<\/p>\n<pre class=\"crayon:false\" style=\"color: white; white-space: pre; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; line-height: 130%; padding: 8px; background: #00284d; margin: 4px 0in 4px 0px;\"><span style=\"color: green;\"># Use the same setup as above, then just...<\/span>\nPS&gt; $fullNameDelegate = [Func[Person,string]] { '{0} {1}' -f $args[0].FirstName, $args[0].Surname }\nPS&gt; $dict = [Linq.Enumerable]::ToDictionary($peopleList, $keyDelegate, $fullNameDelegate)\nPS&gt; $dict\n\nKey  Value       \n---  -----       \n1001 Bob Smith   \n2002 Jane Doe    \n3003 Fester Adams\n\nPS&gt; $dict['1001']\nBob Smith\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<p>PowerShell uses hash tables natively. They work very much like .NET dictionaries but you have a <span style=\"color: #996633; font-weight: bold;\"><code>Name<\/code><\/span> and <span style=\"color: #996633; font-weight: bold;\"><code>Value<\/code><\/span> instead of a <span style=\"color: #996633; font-weight: bold;\"><code>Key<\/code><\/span> and <span style=\"color: #996633; font-weight: bold;\"><code>Value<\/code><\/span>:<\/p>\n<pre class=\"crayon:false\" style=\"color: white; white-space: pre; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; line-height: 130%; padding: 8px; background: #00284d; margin: 4px 0in 4px 0px;\"><span style=\"color: green;\"># Use the same setup as above, then just...<\/span>\nPS&gt; $peopleList | foreach { $hash = @{} } { $hash[$_.SSN] = $_ }\nPS&gt; $hash\n\nName                           Value                                                                                                                       \n----                           -----                                                                                                                       \n2002                           Person                                                                                                                      \n3003                           Person                                                                                                                      \n1001                           Person                                                                                                                      \n\n[508]: $hash['1001']\n\nSSN  FirstName Surname\n---  --------- -------\n1001 Bob       Smith  \n\nPS&gt; $peopleList | foreach { $hash = @{} }\n        { $hash[$_.ssn] = ('{0} {1}' -f $_.FirstName, $_.Surname) }\nPS&gt; $hash\n\nName                           Value                                                                                                                       \n----                           -----                                                                                                                       \n2002                           Jane Doe                                                                                                                    \n3003                           Fester Adams                                                                                                                \n1001                           Bob Smith\n\nPS&gt; $hash['1001']\nBob Smith\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783714\"><\/a>ToLookup<\/h3>\n<p>Creates a <span style=\"color: #996633; font-weight: bold;\"><code>Lookup&lt;TKey,\u2002TElement&gt;<\/code><\/span> from an <span style=\"color: #996633; font-weight: bold;\"><code>IEnumerable&lt;T&gt;<\/code><\/span> according to a specified key selector function (<span style=\"color: #996633; font-weight: bold;\"><code>c =&gt;<\/code><\/span> <span style=\"color: #996633; font-weight: bold;\"><code>c.Length<\/code><\/span> in this example). If the optional element selector function is also provided, the value of the lookup element (<span style=\"color: #996633; font-weight: bold;\"><code>TElement<\/code><\/span>) is computed with that function (not used in this example; see <span style=\"color: green; font-weight: bold;\"><code>ToDictionary<\/code><\/span> for a sample usage).<\/p>\n<p>A <span style=\"color: #996633; font-weight: bold;\"><code>Lookup<\/code><\/span> is a one-to-many map that is <em>not<\/em> mutable after creation. Querying on a non-existent key returns an empty sequence. Contrast this with <span style=\"color: green; font-weight: bold;\"><code>ToDictionary<\/code><\/span>. (Note that <span style=\"color: #996633; font-weight: bold;\"><code>Lookup&lt;TKey,TValue&gt;<\/code><\/span> is roughly comparable to a <span style=\"color: #996633; font-weight: bold;\"><code>Dictionary&lt;TKey,IEnumerable&lt;TValue&gt;&gt;<\/code><\/span>. Thanks to Mark Gravell for this tip on <a href=\"http:\/\/stackoverflow.com\/a\/5659080\/115690\">Stack Overflow<\/a>.)<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var colors = new List {\n    \"green\",\n    \"blue\",\n    \"red\",\n    \"yellow\",\n    \"orange\",\n    \"black\"\n};\nvar result = colors.ToLookup(c =&gt; c.Length);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"crayon:false\" style=\"color: white; white-space: pre; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; line-height: 130%; padding: 8px; background: #00284d; margin: 4px 0in 4px 0px;\">PS&gt; [string[]]$colors = @(\n    \"green\",\n    \"blue\",\n    \"red\",\n    \"yellow\",\n    \"orange\",\n    \"black\"\n)\nPS&gt; $lengthDelegate = [Func[string,int]] { $args[0].Length }\nPS&gt; $lookup = [Linq.Enumerable]::ToLookup($colors, $lengthDelegate)\n<span style=\"color: green;\"># Keys in the Lookup are string lengths per the given delegate<\/span>\nPS&gt; $lookup[6]\nyellow\norange\n<span style=\"color: green;\"># But the result is not a list or array yet!<\/span>\nPS&gt; $lookup[6].GetType().Name\nGrouping\nPS&gt; $6LetterColors = [Linq.Enumerable]::ToArray($lookup[6])\nPS&gt; $6LetterColors[0]\nyellow\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<p><span style=\"color: green; font-weight: bold;\"><code>ToLookup<\/code><\/span> groups objects by a certain key&#8230; which is just what <span style=\"color: #996633; font-weight: bold;\"><code>Group-Object<\/code><\/span> does when you specify the <span style=\"color: #996633; font-weight: bold;\"><code>-AsHashTable<\/code><\/span> parameter.<\/p>\n<pre class=\"crayon:false\" style=\"color: white; white-space: pre; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; line-height: 130%; padding: 8px; background: #00284d; margin: 4px 0in 4px 0px;\"><span style=\"color: green;\"># Use the same setup as above, then just...<\/span>\nPS&gt; $groups = $colors | Group-Object -Property Length -AsHashTable\nPS&gt; $groups\n\nName                           Value                                                                                                                       \n----                           -----                                                                                                                       \n6                              {yellow, orange}                                                                                                            \n5                              {green, black}                                                                                                              \n4                              {blue}                                                                                                                      \n3                              {red}                                                                                                                       \n<\/pre>\n<h2><a id=\"post-71022-_Toc482783715\"><\/a>Elements<\/h2>\n<h3><a id=\"post-71022-_Toc482783716\"><\/a>First<\/h3>\n<p>Returns the first element of a sequence. Throws an exception if the sequence contains no elements. Note that evaluation stops at the first element in the sequence; the remainder of the sequence is not evaluated.<\/p>\n<p>If you specify an optional condition, <span style=\"color: green; font-weight: bold;\"><code>First<\/code><\/span> returns the first element in a sequence that satisfies that condition. Throws an exception if no elements satisfy the condition. Note that evaluation stops at the first element satisfying the condition in the sequence; the remainder of the sequence is not evaluated.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">int[] numbers = { 2, 0, 5, -11, 29 };\nvar firstNumber = numbers.First();\nvar firstNumberConditionally = numbers.First(n =&gt; n &gt; 4);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [int[]] $numbers = @(2, 0, 5, -11, 29)\nPS&gt; [Linq.Enumerable]::First($numbers)\n2\nPS&gt; $delegate = [Func[int,bool]] { $args[0] -gt 4 }\nPS&gt; [Linq.Enumerable]::First($numbers, $delegate)\n5\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; $numbers = @(2, 0, 5, -11, 29)\nPS&gt; $numbers[0]\n2\nPS&gt; ($numbers | Where-Object { $_ -gt 4 })[0]\n5\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783717\"><\/a>FirstOrDefault<\/h3>\n<p>Returns the <em>first<\/em> element of a sequence, or a default value if the sequence contains no elements. Note that evaluation stops at the first element in the sequence; the remainder of the sequence is not evaluated.<\/p>\n<p>If you specify an optional condition, <span style=\"color: green; font-weight: bold;\"><code>FirstOrDefault<\/code><\/span> returns the first element in a sequence that satisfies that condition, or a default value if the sequence contains no elements. Note that evaluation stops at the first element satisfying the condition in the sequence; the remainder of the sequence is not evaluated.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">int[] numbers = { 2, 0, 5, -11, 29 };\nvar firstNumber = numbers.FirstOrDefault();\nvar firstNumberConditionally = numbers.FirstOrDefault(n =&gt; n &gt; 100);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [int[]] $numbers = @(2, 0, 5, -11, 29)\nPS&gt; [Linq.Enumerable]::FirstOrDefault($numbers)\n2\nPS&gt; $delegate = [Func[int,bool]] { $args[0] -gt 100 }\nPS&gt; [Linq.Enumerable]::First($numbers, $delegate)\n0\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; $numbers = @(2, 0, 5, -11, 29)\nPS&gt; if ($numbers) { $ numbers[0] } else { 0 }\n2\nPS&gt; $results = $numbers | Where { $_ -gt 100 }; if ($results) { $results[0] } else { 0 }\n0\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783718\"><\/a>Last<\/h3>\n<p>Returns the <em>last<\/em> element of a sequence. Throws an exception if the sequence contains no elements. The entire sequence must be evaluated to get to the last element.<\/p>\n<p>If you specify an optional condition, <span style=\"color: green; font-weight: bold;\"><code>Last<\/code><\/span> returns the last element of a sequence that satisfies that condition. Throws an exception if the sequence contains no elements. The entire sequence must be evaluated to identify the target element, even if it ends up not being the actual last one in the sequence.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">int[] numbers = { 2, 0, 5, -11, 29 };\nvar lastNumber = numbers.Last();\nvar lastNumberConditionally = numbers.Last(n =&gt; n &lt; 5);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [int[]] $numbers = @(2, 0, 5, -11, 29)\nPS&gt; [Linq.Enumerable]::Last($numbers)\n29\nPS&gt; $delegate = [Func[int,bool]] { $args[0] -lt 5 }\nPS&gt; [Linq.Enumerable]::Last($numbers, $delegate)\n-11\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; $numbers = @(2, 0, 5, -11, 29)\nPS&gt; $numbers | Select-Object -last 1\n29\nPS&gt; $numbers | Where-Object { $_ -lt 5 } | Select-Object -last 1\n-11\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783719\"><\/a>LastOrDefault<\/h3>\n<p>Returns the <em>last<\/em> element of a sequence, or a default value if the sequence contains no elements. The entire sequence must be evaluated to get to the last element.<\/p>\n<p>If you specify an optional condition, <span style=\"color: green; font-weight: bold;\"><code>LastOrDefault<\/code><\/span> returns the last element of a sequence that satisfies that condition, or a default value if the sequence contains no elements. The entire sequence must be evaluated to identify the target element, even if it ends up not being the actual last one in the sequence.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">int[] numbers = { 2, 0, 5, -11, 29 };\nvar lastNumber = numbers.LastOrDefault();\nvar lastNumberConditionally = numbers.LastOrDefault(n =&gt; n &lt; 5);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [int[]] $numbers = @(2, 0, 5, -11, 29)\nPS&gt; [Linq.Enumerable]::LastOrDefault($numbers)\n29\nPS&gt; $delegate = [Func[int,bool]] { $args[0] -gt 1000 }\nPS&gt; [Linq.Enumerable]::LastOrDefault($numbers, $delegate)\n0\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; $numbers = @(2, 0, 5, -11, 29)\nPS&gt; if ($numbers) { $numbers | Select-Object -last 1 } else { 0 }\n29\nPS&gt; $result = $numbers | Where-Object { $_ -gt 1000 }; if ($result) { $result | Select-Object -last 1 } else { 0 }\n0\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783720\"><\/a>ElementAt<\/h3>\n<p>Returns the element at a specified index (zero-based) in a sequence. Throws an exception if the index is out of range.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var stringData = new[] { \"unn\", \"dew\", \"tri\", \"peswar\", \"pymp\" };\nvar thirdValue = stringData.ElementAt(2);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [string[]] $StringData = @(\"unn\", \"dew\", \"tri\", \"peswar\", \"pymp\")\nPS&gt; [Linq.Enumerable]::ElementAt($StringData, 2)\ntri\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; $StringData = @(\"unn\", \"dew\", \"tri\", \"peswar\", \"pymp\")\nPS&gt; $StringData[2]\ntri\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783721\"><\/a>ElementAtOrDefault<\/h3>\n<p>Returns the element at a specified index (zero-based) in a sequence, or a default value if the index is out of range.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">int[] numbers = { 2, 0, 5, -11, 29 };\nvar absentValue = numbers.ElementAtOrDefault(99);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [int[]] $numbers = @(2, 0, 5, -11, 29)\nPS&gt; [Linq.Enumerable]::ElementAtOrDefault($numbers, 99)\n0\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; $numbers = @(2, 0, 5, -11, 29)\nPS&gt; if ($numbers.Length -gt 99) { $numbers[99] } else { 0 }\n0\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783722\"><\/a>Single<\/h3>\n<p>Returns the <em>only<\/em> element of a sequence. Throws an exception if the sequence contains more than one element.<\/p>\n<p>If you specify an optional condition, <span style=\"color: green; font-weight: bold;\"><code>Single<\/code><\/span> returns the only element in a sequence that satisfies that condition. Throws an exception if either no elements or more than one element satisfy the condition.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var stringData = new[] { \"unn\", \"dew\", \"tri\", \"peswar\", \"pymp\" };\nvar fourCharWord = stringData.Single(w =&gt; w.Length == 4);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [string[]]$StringData = @(\"unn\", \"dew\", \"tri\", \"peswar\", \"pymp\")\nPS&gt; $delegate = [Func[string,bool]] { $args[0].Length -eq 4 }\nPS&gt; [Linq.Enumerable]::Single($StringData, $delegate)\npymp\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; $StringData = @(\"unn\", \"dew\", \"tri\", \"peswar\", \"pymp\")\nPS&gt; $result = @($StringData | Where { $_.Length -eq 4 }) # force into an array\nPS&gt; if ($result.Length -ne 1) { throw \u201cSequence does NOT contain just one element\" }\nPS&gt; $result\npymp\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783723\"><\/a>SingleOrDefault<\/h3>\n<p>Returns the <em>only<\/em> element of a sequence or a default value if the sequence is empty. Throws an exception if the sequence contains more than one element.<\/p>\n<p>If you specify an optional condition, <span style=\"color: green; font-weight: bold;\"><code>SingleOrDefault<\/code><\/span> returns the only element in a sequence that satisfies that condition, or a default value if the sequence is empty. Throws an exception if the sequence contains more than one element.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">int[] numbers = { 2, 0, 5, -11, 29 };\nvar absentValue = numbers.SingleOrDefault(n =&gt; n &gt; 42);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [int[]] $numbers = @(2, 0, 5, -11, 29)\nPS&gt; $delegate = [Func[int,bool]] { $args[0] -gt 42 }\nPS&gt; [Linq.Enumerable]::SingleOrDefault($numbers, $delegate)\n0\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"crayon:false\" style=\"color: white; white-space: pre; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; line-height: 130%; padding: 8px; background: #00284d; margin: 4px 0in 4px 0px;\">PS&gt; $numbers = @(2, 0, 5, -11, 29)\nPS&gt; $result = @($numbers | Where { $_ -gt 42 }) <span style=\"color: green;\"># force into an array<\/span>\nPS&gt; if ($result.Length -gt 1) { throw \u201cSequence contains more than one element\" }\nPS&gt; if ($result.Length -eq 1) { $result[0] } else { 0 }\n0\n<\/pre>\n<h2><a id=\"post-71022-_Toc482783724\"><\/a>Generation<\/h2>\n<h3><a id=\"post-71022-_Toc482783725\"><\/a>Range<\/h3>\n<p>Generates a sequence of integral numbers within a specified range.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">  var numbers = Enumerable.Range(0,5);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [Linq.Enumerable]::Range(0,5)\n0\n1\n2\n3\n4\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; 0..4\n0\n1\n2\n3\n4\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783726\"><\/a>Repeat<\/h3>\n<p>Generates a sequence that contains a repeated value a specified number of times.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">  var numbers = Enumerable.Repeat(\u201cone\u201d, 3);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [Linq.Enumerable]::Repeat(\"one\", 3)\none\none\none\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; 1..3 | ForEach-Object { \"one\" }\none\none\none\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783727\"><\/a>Empty<\/h3>\n<p>Returns an empty <span style=\"color: #996633; font-weight: bold;\"><code>IEnumerable&lt;T&gt;<\/code><\/span> that has the specified type argument.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">  var emptyList = Enumerable.Empty&lt;string&gt;();\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var emptyForString = typeof(System.Linq.Enumerable)\n\t.GetMethod(\"Empty\")\n\t.MakeGenericMethod(typeof(string));\nvar emptyList = emptyForString.Invoke(null, new object[] { });\n<\/pre>\n<p>And that translates to PowerShell as:<\/p>\n<pre class=\"crayon:false\" style=\"color: white; white-space: pre; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; line-height: 130%; padding: 8px; background: #00284d; margin: 4px 0in 4px 0px;\">PS&gt; $stringType = \"\".GetType() <span style=\"color: green;\"># set to your target type<\/span>\nPS&gt; $emptyForString =\n    [Linq.Enumerable].GetMethod(\"Empty\").MakeGenericMethod($stringType)\n<span style=\"color: green;\"># The last comma below wraps the array arg $stuff within another array<\/span>\nPS&gt; $emptyList = $emptyForString.Invoke($null, @()) \nPS&gt; $emptyList.Count\n0\nPS&gt; $emptyList.GetType().name\nString[]\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">  PS&gt; [string[]]$emptyList = @()\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783728\"><\/a>DefaultIfEmpty<\/h3>\n<p>Returns the default value of the sequence\u2019s elements (or, if a type parameter is explicitly specified, that type\u2019s default value) in a singleton collection if the sequence is empty. In this first example, the list is not empty so it returns the original sequence.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">string[] words = { \"one\",\"two\",\"three\" };\nvar result = words\n    .Where(w =&gt; w.Length == 3)\n    .DefaultIfEmpty(\"unknown\");\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [string[]] $words = @( \"one\",\"two\",\"three\" )\nPS&gt; $filteredWords = [Linq.Enumerable]::Where(\n        $words,\n        [Func[string,bool]] { $args[0].Length -eq 3 })\nPS&gt; [Linq.Enumerable]::DefaultIfEmpty($filteredWords, \"unknown\")\none\ntwo\n<\/pre>\n<p>But if the condition is changed so the filtered list has no elements, then:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; $filteredWords = [Linq.Enumerable]::Where(\n        $words,\n        [Func[string,bool]] { $args[0].Length -eq 2 })\nPS&gt; [Linq.Enumerable]::DefaultIfEmpty($filteredWords, \"unknown\")\nunknown\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"crayon:false\" style=\"color: white; white-space: pre; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; line-height: 130%; padding: 8px; background: #00284d; margin: 4px 0in 4px 0px;\">PS&gt; $words = @( \"one\",\"two\",\"three\" )\nPS&gt; $filteredWords = $words | Where-Object { $_.Length -eq 2 }\nPS&gt; if ($filteredWords) { $filteredWords } else { \"unknown\" }\none\ntwo\n\n<span style=\"color: green;\"># Again, the filter is changed here to now filter out all items<\/span>\nPS&gt; $filteredWords = $words | Where-Object { $_.Length -eq 3 }\nunknown\n<\/pre>\n<h2><a id=\"post-71022-_Toc482783729\"><\/a>Grouping<\/h2>\n<h3><a id=\"post-71022-_Toc482783730\"><\/a>GroupBy<\/h3>\n<p>Groups the elements of a sequence according to a specified key selector function (<span style=\"color: #996633; font-weight: bold;\"><code>pet =&gt;<\/code><\/span> <span style=\"color: #996633; font-weight: bold;\"><code>pet.Age<\/code><\/span>). In the result, the second group is expanded to show its contents, containing 2 members of age 4. Notice that the elements of the group are objects of the original type, <span style=\"color: #996633; font-weight: bold;\"><code>Pet<\/code><\/span>.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">class Pet\n{\n    public string Name { get; set; }\n    public int Age { get; set; }\n}\n\nvar pets = new List&lt;Pet&gt;{\n            new Pet {Name=\"Barley\",  Age=8},\n            new Pet {Name=\"Boots\",   Age=4},\n            new Pet {Name=\"Whiskers\",Age=1},\n            new Pet {Name=\"Daisy\",   Age=4}\n        };\n\nvar resultA = pets.GroupBy(pet =&gt; pet.Age);\nvar resultB = pets.GroupBy(pet =&gt; pet.Age, pet =&gt; pet.Name);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">class Pet\n{\n    [string] $Name;\n    [int] $Age;\n\n    Pet([string]$name, [int] $age)\n    {\n        $this.Name = $name\n        $this.Age = $age\n    }\n}\n\n[Pet[]]$pets = @(\n    [Pet]::new(\"Barley\", 8),\n    [Pet]::new(\"Boots\", 4),\n    [Pet]::new(\"Whiskers\", 1),\n    [Pet]::new(\"Daisy\", 4)\n)\n\nPS&gt; $ageDelegate = [Func[Pet,int]] { $args[0].Age }\n\nPS&gt; $groupQueryA = [Linq.Enumerable]::GroupBy($pets, $ageDelegate)\nPS&gt; $groupQueryA\nName     Age\n----     ---\nBarley     8\nBoots      4\nDaisy      4\nWhiskers   1\n\nPS&gt; $groups = [Linq.Enumerable]::ToArray($groupQueryA)\nPS&gt; $groups[1]\nName  Age\n----  ---\nBoots   4\nDaisy   4\n<\/pre>\n<p>If you specify an optional projection function, <span style=\"color: green; font-weight: bold;\"><code>GroupBy<\/code><\/span> further projects the elements for each group with that function (<span style=\"color: #996633; font-weight: bold;\"><code>pet =&gt;<\/code><\/span> <span style=\"color: #996633; font-weight: bold;\"><code>pet.Name<\/code><\/span> in this next example). In the result, the second group is expanded to show its contents, containing 2 members of age 4. Notice that the elements of the group are now comprised of just the projected property, the pet\u2019s name.<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; $nameDelegate = [Func[Pet,string]] { $args[0].Name }\nPS&gt; $groupQueryB = [Linq.Enumerable]::GroupBy($pets, $ageDelegate, $nameDelegate)\nPS&gt; $groupQueryB\nBarley\nBoots\nDaisy\nWhiskers\nPS&gt; $groups = [Linq.Enumerable]::ToArray($groupQueryB)\nPS&gt; $groups[1]\nBoots\nDaisy\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"crayon:false\" style=\"color: white; white-space: pre; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; line-height: 130%; padding: 8px; background: #00284d; margin: 4px 0in 4px 0px;\"><span style=\"color: green;\"># Use the same setup as above, then just...<\/span>\nPS&gt; $groups = $pets | Group-Object -Property Age\nCount Name                      Group                                                                                                                      \n----- ----                      -----                                                                                                                      \n    1 8                         {Pet}                                                                                                                      \n    2 4                         {Pet, Pet}                                                                                                                 \n    1 1                         {Pet}   \nPS&gt; $groups[1].Group\nName  Age\n----  ---\nBoots   4\nDaisy   4\n<\/pre>\n<h2><a id=\"post-71022-_Toc482783731\"><\/a>Join<\/h2>\n<h3><a id=\"post-71022-_Toc482783732\"><\/a>Cross Join<\/h3>\n<p>Correlates the elements of two sequences based on matching keys. If the first sequence has no corresponding elements in the second sequence, it is <em>not<\/em> represented in the result. <span style=\"color: green; font-weight: bold;\"><code>Join<\/code><\/span> is equivalent to an inner join in SQL.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">class User\n{\n    public int Id { get; set; }\n    public string Name { get; set; }\n}\n\nclass Book\n{\n    public int Id { get; set; }\n    public string Title { get; set; }\n}\n\nvar users = new List&lt;User&gt; {\n    new User{Id=1, Name = \"Sam\"},\n    new User{Id=6, Name = \"Dean\"},\n    new User{Id=3, Name = \"Crowley\"},\n    new User{Id=4, Name = \"Chuck\"},\n    new User{Id=5, Name = \"Castiel\"}\n};\n\nvar books = new List&lt;Book&gt;\n{\n    new Book{Id = 3, Title = \"Inferno\"},\n    new Book{Id = 9, Title = \"Bliss\"},\n    new Book{Id = 5, Title = \"Heaven Can Wait\"},\n    new Book{Id = 1, Title = \"Beowulf\"},\n    new Book{Id = 6, Title = \"Bates Motel\"}\n};\n\nvar booksMatchedWithUsers = users.Join(\n    books,\n    u =&gt; u.Id,\n    b =&gt; b.Id,\n    (u, b) =&gt; $\"{u.Name} =&gt; {b.Title}\"\n);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">class User\n{\n    [int] $Id;\n    [string] $Name;\n\n    User($id, $name) {\n        $this.Id = $id\n        $this.Name = $name\n    }\n}\n\nclass Book\n{\n    [int] $Id;\n    [string] $Title;\n    Book($id, $title) {\n        $this.Id = $id\n        $this.Title = $title\n    }\n}\n\n[User[]]$users = @(\n    [User]::new(1, \"Sam\"),\n    [User]::new(6, \"Dean\"),\n    [User]::new(3, \"Crowley\"),\n    [User]::new(4, \"Chuck\"),\n    [User]::new(5, \"Castiel\")\n)\n\n[Book[]]$books = @(\n    [Book]::new(3, \"Inferno\"),\n    [Book]::new(9, \"Bliss\"),\n    [Book]::new(5, \"Heaven Can Wait\"),\n    [Book]::new(1, \"Beowulf\"),\n    [Book]::new(6, \"Bates Motel\")\n)\n\nPS&gt; $outerKeyDelegate = [Func[User,int]] { $args[0].Id }\nPS&gt; $innerKeyDelegate = [Func[Book,int]] { $args[0].Id }\nPS&gt; $resultDelegate = [Func[User,Book,string]] { '{0} =&gt; {1}' -f $args[0].Name, $args[1].Title }\nPS&gt; [Linq.Enumerable]::Join(\n        $users, $books, $outerKeyDelegate, $innerKeyDelegate, $resultDelegate)\n\nSam =&gt; Beowulf\nDean =&gt; Bates Motel\nCrowley =&gt; Inferno\nCastiel =&gt; Heaven Can Wait\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"crayon:false\" style=\"color: white; white-space: pre; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; line-height: 130%; padding: 8px; background: #00284d; margin: 4px 0in 4px 0px;\"><span style=\"color: green;\"># Use the same setup as above, then just...<\/span>\nPS&gt; $users | ForEach-Object { \n        $user = $_\n        $book = $books | Where-Object Id -eq $user.Id\n        if ($book) { \"{0} =&gt; {1}\" -f $user.Name, $book.Title }\n    }\nSam =&gt; Beowulf\nDean =&gt; Bates Motel\nCrowley =&gt; Inferno\nCastiel =&gt; Heaven Can Wait\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783733\"><\/a>Group Join<\/h3>\n<p>Correlates the elements of two sequences based on equality of keys and groups the results. If the first sequence has no corresponding elements in the second sequence, it is <em>still<\/em> represented in the result but its group contains no members. In the example, notice that user Chuck (id=4) has no books associated with him. <span style=\"color: green; font-weight: bold;\"><code>Group Join<\/code><\/span> is equivalent to a left outer join in SQL.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">class User\n{\n    public int Id { get; set; }\n    public string Name { get; set; }\n}\n\nclass Book\n{\n    public int Id { get; set; }\n    public string Title { get; set; }\n}\n\nvar users = new List&lt;User&gt; {\n    new User{Id=1, Name = \"Sam\"},\n    new User{Id=6, Name = \"Dean\"},\n    new User{Id=3, Name = \"Crowley\"},\n    new User{Id=4, Name = \"Chuck\"},\n    new User{Id=5, Name = \"Castiel\"}\n};\n\nvar books = new List&lt;Book&gt;\n{\n    new Book{Id = 3, Title = \"Inferno\"},\n    new Book{Id = 1, Title = \"Inferno\"},\n    new Book{Id = 9, Title = \"Bliss\"},\n    new Book{Id = 5, Title = \"Heaven Can Wait\"},\n    new Book{Id = 1, Title = \"Beowulf\"},\n    new Book{Id = 6, Title = \"Bates Motel\"}\n};\n\nvar booksMatchedWithUsers = users.GroupJoin(\n    books,\n    u =&gt; u.Id,\n    b =&gt; b.Id,\n    (u, bList) =&gt; $\"{u.Name} =&gt; {bList.Count()}\"\n);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<p>While this example is extremely similar to that for <span style=\"color: green; font-weight: bold;\"><code>Cross Join<\/code><\/span> above, it has one key change\u2014requiring a list in the delegate\u2014that is inexplicably causing it to fail, as noted towards the bottom.<\/p>\n<pre class=\"crayon:false\" style=\"color: white; white-space: pre; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; padding: 8px; line-height: 130%; background-color: #00284d; margin: 4px 0in 4px 0px;\">class User\n{\n    [int] $Id;\n    [string] $Name;\n\n    User($id, $name) {\n        $this.Id = $id\n        $this.Name = $name\n    }\n}\n\nclass Book\n{\n    [int] $Id;\n    [string] $Title;\n    Book($id, $title) {\n        $this.Id = $id\n        $this.Title = $title\n    }\n}\n\n[User[]]$users = @(\n    [User]::new(1, \"Sam\"),\n    [User]::new(6, \"Dean\"),\n    [User]::new(3, \"Crowley\"),\n    [User]::new(4, \"Chuck\"),\n    [User]::new(5, \"Castiel\")\n)\n\n[Book[]]$books = @(\n    [Book]::new(3, \"Inferno\"),\n    [Book]::new(1, \"Inferno\"),\n    [Book]::new(9, \"Bliss\"),\n    [Book]::new(5, \"Heaven Can Wait\"),\n    [Book]::new(1, \"Beowulf\"),\n    [Book]::new(6, \"Bates Motel\")\n)\n\nPS&gt; $outerKeyDelegate = [Func[User,int]] { $args[0].Id }\nPS&gt; $innerKeyDelegate = [Func[Book,int]] { $args[0].Id }\n\n<span style=\"color: green;\"># Thanks to reader \"ili\" for deciphering the needed middle type here!\n# Turns out we need an IEnumerable[Book] rather than Book[] as I tried.<\/span>\nPS&gt; $resultDelegate = [Func[User,[Collections.Generic.IEnumerable[Book]],string]]\n         { '{0} =&gt; {1}' -f $args[0].Name, $args[1].Count }\n\nPS&gt; [Linq.Enumerable]::GroupJoin(\n         $users, $books, $outerKeyDelegate, $innerKeyDelegate, $resultDelegate)\n\nSam =&gt; 2 \nDean =&gt; 1 \nCrowley =&gt; 1 \nChuck =&gt; 0 \nCastiel =&gt; 1\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783734\"><\/a>Concat<\/h3>\n<p>Concatenates two sequences into a single sequence; further LINQ operations would then operate on the new, combined sequence.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">string[] words1 = { \"one\",\"two\",\"three\" };\nstring[] words2 = { \"green\",\"red\",\"blue\" };\nvar combined = words1.Concat(words2);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">var result = words\n    .Where(w =&gt; w.Length == 3)\n    .DefaultIfEmpty(\"unknown\");one\ntwo\nthree\ngreen\nred\nblue\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; $words1 = @( \"one\",\"two\",\"three\" )\nPS&gt; $words2 = @( \"green\",\"red\",\"blue\" )\nPS&gt; $words1 + $words2\none\ntwo\nthree\ngreen\nred\nblue\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783735\"><\/a>Zip<\/h3>\n<p>Applies a specified function to the corresponding elements of two sequences, producing a new sequence of the results. If the first sequence is longer than the second, one element past the common length will be evaluated (\u201cd\u201d in the example) at which point a determination is made that the second sequence has been consumed, and further evaluation stops (so \u201ce\u201d is not evaluated). If the second sequence is longer than the first, its extra values will not be evaluated at all. Note that \u201czip\u201d in this context has nothing to do with zip archives!<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">string[] words = { \"a\", \"b\", \"c\", \"d\", \"e\" };\nint[] numbers = { 1, 2, 3 };\nvar result = words.Zip(numbers, (w, n) =&gt; w + n);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [string[]] $words = @( \"a\", \"b\", \"c\", \"d\", \"e\" )\nPS&gt; [int[]] $numbers = @( 1, 2, 3 )\nPS&gt; $delegate = [Func[string,int,string]] { $args[0] + $args[1] }\nPS&gt; [Linq.Enumerable]::Zip($words, $numbers, $delegate)\na1\nb2\nc3\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; $words | foreach-object  {$i=0} {if ($i -lt $numbers.Count) {$_ + $numbers[$i++]}}\na1\nb2\nc3\n<\/pre>\n<h2><a id=\"post-71022-_Toc482783736\"><\/a>Ordering<\/h2>\n<h3><a id=\"post-71022-_Toc482783737\"><\/a>OrderBy<\/h3>\n<p>Sorts the elements of a sequence in <em>ascending<\/em> order according to a key selector function.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var stringData = new[] { \"unn\", \"dew\", \"tri\", \"peswar\", \"pymp\" };\nvar sortedValues = stringData.OrderBy(word =&gt; word);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [string[]] $StringData = @(\"unn\", \"dew\", \"tri\", \"peswar\", \"pymp\")\nPS&gt; [Linq.Enumerable]::OrderBy($StringData, [Func[string,string]] { $args[0] })\ndew\npeswar\npymp\ntri\nunn \n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"crayon:false\" style=\"color: white; white-space: pre; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; line-height: 130%; padding: 8px; background: #00284d; margin: 4px 0in 4px 0px;\">PS&gt; $StringData = @(\"unn\", \"dew\", \"tri\", \"peswar\", \"pymp\")\n<span style=\"color: green;\"># simple strings; no properties need to be used; compare to next example<\/span>\nPS&gt; $StringData | Sort-Object \ndew\npeswar\npymp\ntri\nunn \n<\/pre>\n<h3><a id=\"post-71022-_Toc482783738\"><\/a>OrderByDescending<\/h3>\n<p>Sorts the elements of a sequence in <em>descending<\/em> order according to a key selector function.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var stringData = new[] { \"unn\", \"dew\", \"tri\", \"peswar\", \"pymp\" };\nvar sortedValues = stringData.OrderByDescending(word =&gt; word.Length);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [string[]] $StringData = @(\"unn\", \"dew\", \"tri\", \"peswar\", \"pymp\")\nPS&gt; [Linq.Enumerable]::OrderByDescending($StringData, [Func[string,string]] { $args[0].Length })\npeswar\npymp\nunn\ndew\ntri\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; $StringData = @(\"unn\", \"dew\", \"tri\", \"peswar\", \"pymp\")\nPS&gt; $stringData | Sort-Object -Property Length -Descending \npeswar\npymp\nunn\ndew\ntri\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783739\"><\/a>ThenBy<\/h3>\n<p>Performs a <em>subsequent<\/em> ordering of the elements in a sequence in <em>ascending<\/em> order according to a key selector function (<span style=\"color: #996633; font-weight: bold;\"><code>d =&gt;<\/code><\/span> <span style=\"color: #996633; font-weight: bold;\"><code>d.Month<\/code><\/span> in this example). Note that unlike most other LINQ operators, which accept an <span style=\"color: #996633; font-weight: bold;\"><code>IEnumerable&lt;T&gt; <\/code><\/span>input, <span style=\"color: green; font-weight: bold;\"><code>ThenBy<\/code><\/span> accepts an <span style=\"color: #996633; font-weight: bold;\"><code>IOrderedEnumerable&lt;T&gt;<\/code><\/span> input\u2014which happens to be the output of <span style=\"color: green; font-weight: bold;\"><code>OrderBy<\/code><\/span>.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var dates = new DateTime[] {\n    new DateTime(2017, 10, 23),\n    new DateTime(2016, 12, 3),\n    new DateTime(2016, 2, 13)\n};\n\nvar result = dates.OrderBy(d =&gt; d.Year).ThenBy(d =&gt; d.Month);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [DateTime[]]$dates = \n    (Get-Date -Year 2017 -Month 10 -Day 23),\n    (Get-Date -Year 2016 -Month 12 -Day 3),\n    (Get-Date -Year 2016 -Month 2 -Day 13)\nPS&gt; $yearDelegate = [Func[DateTime,int]] { $args[0].Year } \nPS&gt; $monthDelegate = [Func[DateTime,int]] { $args[0].Month }\nPS&gt; [Linq.Enumerable]::ThenBy(\n        [Linq.Enumerable]::OrderBy($dates, $yearDelegate),\n        $monthDelegate)\nSaturday, February 13, 2016 4:22:31 PM\nSaturday, December 3, 2016 4:22:31 PM\nMonday, October 23, 2017 4:22:31 PM\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [DateTime[]]$dates = \n    (Get-Date -Year 2017 -Month 10 -Day 23),\n    (Get-Date -Year 2016 -Month 12 -Day 3),\n    (Get-Date -Year 2016 -Month 2 -Day 13)\nPS&gt; $dates | Sort-Object -Property @{ Expression=\"Year\"; Descending=$false },\n    @{ Expression=\"Month\"; Descending=$false }\nSaturday, February 13, 2016 4:22:31 PM\nSaturday, December 3, 2016 4:22:31 PM\nMonday, October 23, 2017 4:22:31 PM\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783740\"><\/a>ThenByDescending<\/h3>\n<p>Performs a <em>subsequent<\/em> ordering of the elements in a sequence in <em>descending<\/em> order according to a key selector function. Note that unlike most other LINQ operators, which accept an <span style=\"color: #996633; font-weight: bold;\"><code>IEnumerable&lt;T&gt; <\/code><\/span>input, <span style=\"color: green; font-weight: bold;\"><code>ThenBy<\/code><\/span> accepts an <span style=\"color: #996633; font-weight: bold;\"><code>IOrderedEnumerable&lt;T&gt;<\/code><\/span> input\u2014which happens to be the output of <span style=\"color: green; font-weight: bold;\"><code>OrderBy<\/code><\/span>.<\/p>\n<p>Works identically to <span style=\"color: green; font-weight: bold;\"><code>ThenBy<\/code><\/span> except you set the Descending property to true in the native PowerShell example.<\/p>\n<h3><a id=\"post-71022-_Toc482783741\"><\/a>Reverse<\/h3>\n<p>Inverts the order of the elements in a sequence.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var stringData = new[] { \"unn\", \"dew\", \"tri\", \"peswar\", \"pymp\" };\nvar reversedValues = stringData.Reverse();\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [string[]] $StringData = @(\"unn\", \"dew\", \"tri\", \"peswar\", \"pymp\")\nPS&gt; [Linq.Enumerable]::Reverse($StringData)\npymp\npeswar\ntri\ndew\nunn\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"crayon:false\" style=\"color: white; white-space: pre; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; line-height: 130%; padding: 8px; background: #00284d; margin: 4px 0in 4px 0px;\">PS&gt; $StringData = @(\"unn\", \"dew\", \"tri\", \"peswar\", \"pymp\")\n<span style=\"color: green;\"># Careful! This call modifies the *original* array and does *not* output it.<\/span>\nPS&gt; [array]::Reverse($StringData)\n<span style=\"color: green;\"># Then to see the output:<\/span>\nPS&gt; $StringData\npymp\npeswar\ntri\ndew\nunn\n<\/pre>\n<h2><a id=\"post-71022-_Toc482783742\"><\/a>Partitioning<\/h2>\n<h3><a id=\"post-71022-_Toc482783743\"><\/a>Take<\/h3>\n<p>Returns a specified number of elements from the start of a sequence. Evaluation of the sequence stops after that as no further elements are needed.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">int[] numbers = Enumerable.Range(1, 10);\nvar firstHalfQuery = numbers.Take(5);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">[int[]]$numbers = 1..10\n$firstHalfQuery = [Linq.Enumerable]::Take($numbers, 5)\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">[int[]]$numbers = 1..10\n$firstHalf = $numbers[0..4]\n$firstHalf = $numbers | Select-Object -First 5\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783744\"><\/a>Skip<\/h3>\n<p>Bypasses a specified number of elements in a sequence and then returns the remaining elements.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">int[] numbers = Enumerable.Range(1, 10);\nvar lastHalfQuery = numbers.Skip(5);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">[int[]]$numbers = 1..10 \n$lastHalfQuery = [Linq.Enumerable]::Skip($numbers, 5)\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">[int[]]$numbers = 1..10 \n$lastHalf = $numbers[5..9]\n$lastHalf = $numbers | Select-Object -Skip 5\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783745\"><\/a>TakeWhile<\/h3>\n<p>Returns elements from the start of a sequence as long as a specified condition is true. Evaluation of the sequence stops after that as no further elements are needed.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };\nvar initialNumbersUntil7trigger = numbers.TakeWhile(n =&gt; n &lt; 7);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">[int[]]$numbers = @(5, 4, 1, 3, 9, 8, 6, 7, 2, 0);\n$delegate = [Func[int,bool]] { $args[0] -lt 7 }\n$initialNumbersUntil7trigger = [Linq.Enumerable]::TakeWhile($numbers, $delegate)\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<p>PowerShell does not have an equivalent one-liner to do a <span style=\"color: green; font-weight: bold;\"><code>TakeWhile<\/code><\/span>, but with the <a href=\"https:\/\/blogs.msdn.microsoft.com\/jaredpar\/2009\/01\/16\/powershell-linq-take-count-and-take-while\/\">Take-While function created by JaredPar<\/a>, you could just do this:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">[int[]]$numbers = @(5, 4, 1, 3, 9, 8, 6, 7, 2, 0);\n$initialNumbersUntil7trigger = $numbers | Take-While {$args[0] -lt 7}\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783746\"><\/a>SkipWhile<\/h3>\n<p>Bypasses elements in a sequence as long as a specified condition is true and then returns the remaining elements.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };\nvar numbersAfter7trigger = numbers.SkipWhile(n =&gt; n &lt; 7);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">[int[]]$numbers = @(5, 4, 1, 3, 9, 8, 6, 7, 2, 0);\n$delegate = [Func[int,bool]] { $args[0] -lt 7 }\n$numbersAfter7trigger = [Linq.Enumerable]::SkipWhile($numbers, $delegate)\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<p>PowerShell does not have an equivalent one-liner to do a <span style=\"color: green; font-weight: bold;\"><code>SkipWhile<\/code><\/span>, but with the <a href=\"https:\/\/blogs.msdn.microsoft.com\/jaredpar\/2009\/01\/14\/powershell-linq-skip-while\/\">Skip-While function created by JaredPar<\/a>, you could just do this:<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">[int[]]$numbers = @(5, 4, 1, 3, 9, 8, 6, 7, 2, 0);\n$numbersAfter7trigger = $numbers | Skip-While {$args[0] -lt 7}\n<\/pre>\n<h2><a id=\"post-71022-_Toc482783747\"><\/a>Projection<\/h2>\n<h3><a id=\"post-71022-_Toc482783748\"><\/a>Select<\/h3>\n<p>Applies a specified transformation to each element of a sequence; this transformation is generally referred to as \u201cprojection\u201d. Often you might project into a new object that is a subset of the original object, essentially discarding unneeded properties. In the illustration, the sequence is transformed to a new sequence with just the <span style=\"color: #996633; font-weight: bold;\"><code>DayOfYear<\/code><\/span> property.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var dates = new DateTime[] {\n    new DateTime(2017, 10, 23),\n    new DateTime(2013, 12, 3),\n    new DateTime(2016, 2, 13)\n};\n\nvar result = dates.Select(d =&gt; d.DayOfYear);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [DateTime[]]$dates = \n    (Get-Date -Year 2017 -Month 10 -Day 23),\n    (Get-Date -Year 2013 -Month 12 -Day 3),\n    (Get-Date -Year 2016 -Month 2 -Day 13)\nPS&gt; [Linq.Enumerable]::Select($dates, [Func[DateTime,int]] { $args[0].DayOfYear})\n296\n337\n44\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [DateTime[]]$dates = \n    (Get-Date -Year 2017 -Month 10 -Day 23),\n    (Get-Date -Year 2013 -Month 12 -Day 3),\n    (Get-Date -Year 2016 -Month 2 -Day 13)\nPS&gt; $dates | Select-Object -ExpandProperty DayOfYear\n296\n337\n44\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783749\"><\/a>SelectMany<\/h3>\n<p>Projects each element of a sequence to an <span style=\"color: #996633; font-weight: bold;\"><code>IEnumerable&lt;T&gt; <\/code><\/span>and flattens the resulting sequences into a single sequence. If, in the illustration, <span style=\"color: #996633; font-weight: bold;\"><code>Select<\/code><\/span> had been used instead of <span style=\"color: #996633; font-weight: bold;\"><code>SelectMany<\/code><\/span>, each element of the result would be a list of <span style=\"color: #996633; font-weight: bold;\"><code>User<\/code><\/span> objects (i.e. a list of string <em>arrays<\/em>) rather than a list of <em>strings<\/em>, as shown, and the result would be just a 2-element list rather than a 6 element list.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">class DayTally\n{\n    public DateTime Day { get; set; }\n    public string[] User { get; set; }\n}\n\nIEnumerable&lt;string&gt; Process() {\n    var days = new List&lt;DayTally&gt; {\n        new DayTally{\n            Day = new DateTime(2017, 10, 23),\n            User = new[]\n            { \"user1\", \"user2\", \"user5\", \"user4\" }\n        },\n        new DayTally{\n            Day = new DateTime(2017, 2, 5),\n            User = new[]\n            { \"user3\", \"user6\" }\n        }\n    };\n    return days.SelectMany(d =&gt; d.User);\n}\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"crayon:false\" style=\"color: white; white-space: pre; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; line-height: 130%; padding: 8px; background: #00284d; margin: 4px 0in 4px 0px;\">class DayTally\n{\n    [DateTime] $Day;\n    [string[]] $User;\n    \n    DayTally([DateTime] $day, [string[]] $user) {\n        $this.Day = $day;\n        $this.User = $user;\n    }\n}\n\n[DayTally[]]$days = @(\n    [DayTally]::new(\n        (Get-Date -Year 2017 -Month 10 -Day 23), \n        [string[]] @( \"user1\", \"user2\", \"user5\", \"user4\" ));\n    [DayTally]::new(\n        (Get-Date -Year 2017 -Month 2 -Day 5), \n        [string[]] @( \"user3\", \"user6\" ));\n)\n\n<span style=\"color: green;\"># Careful with the delegate signature! E.g. change 'string[]' to 'string' and watch what happens<\/span>\nPS&gt; [Func[DayTally,string[]]] $delegate = { return $args[0].User }\nPS&gt; [Linq.Enumerable]::SelectMany($days, $delegate)\nuser1\nuser2\nuser5\nuser4\nuser3\nuser6\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"crayon:false\" style=\"color: white; white-space: pre; font-family: 'Lucida Console', 'Courier New', Courier, monospace; font-size: 11px; line-height: 130%; padding: 8px; background: #00284d; margin: 4px 0in 4px 0px;\"><span style=\"color: green;\"># Use the same setup as above, then just...<\/span>\nPS&gt; $days | Select -ExpandProperty User\nuser1\nuser2\nuser5\nuser4\nuser3\nuser6\n<\/pre>\n<h2><a id=\"post-71022-_Toc482783750\"><\/a>Quantifiers<\/h2>\n<h3><a id=\"post-71022-_Toc482783751\"><\/a>Any<\/h3>\n<p>Determines whether <em>any<\/em> element of a sequence (i.e. at least one element) satisfies a condition. All elements of the sequence need to be evaluated to provide a <span style=\"color: #996633; font-weight: bold;\"><code>false<\/code><\/span> result (first figure). However, if at any time during evaluating the sequence an element evaluates to <span style=\"color: #996633; font-weight: bold;\"><code>true<\/code><\/span>, the sequence evaluation stops at that element (second figure). Of course, if <em>only<\/em> the last element satisfies the condition, all elements will need to be evaluated and <span style=\"color: #996633; font-weight: bold;\"><code>true<\/code><\/span> will be returned.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var stringData = new[] { \"unn\", \"dew\", \"tri\", \"peswar\", \"pymp\" };\nvar anyPresent = stringData.Any(s =&gt; Regex.IsMatch(s, \".*war\"));\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; $StringData = @(\"unn\", \"dew\", \"tri\", \"peswar\", \"pymp\")\nPS&gt; $delegate =  [Func[string,bool]]{ $args[0] -match '.*war' }\nPS&gt; [Linq.Enumerable]::Any([string[]]$StringData, $delegate)\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<p>PowerShell does not have an equivalent one-liner to do <span style=\"color: green; font-weight: bold;\"><code>Any<\/code><\/span>, but there are a variety of suggestions to implement <span style=\"color: #996633; font-weight: bold;\"><code>Test-Any<\/code><\/span> in <a href=\"http:\/\/stackoverflow.com\/q\/1499466\/115690\">this StackOverflow post<\/a>. The key is stopping the pipeline once you make a determination; see the discussion on StackOverflow for details.<\/p>\n<h3><a id=\"post-71022-_Toc482783752\"><\/a>All<\/h3>\n<p>Determines whether <em>all<\/em> elements of a sequence satisfy a condition. All elements of the sequence need to be evaluated to provide a <span style=\"color: #996633; font-weight: bold;\"><code>true<\/code><\/span> result (first figure). However, if at any time during evaluating the sequence an element evaluates to <span style=\"color: #996633; font-weight: bold;\"><code>false<\/code><\/span>, the sequence evaluation stops at that element (second figure). Of course, if <em>only<\/em> the last element fails to satisfy the condition, all elements will need to be evaluated and <span style=\"color: #996633; font-weight: bold;\"><code>false<\/code><\/span> will be returned.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var stringData = new[] { \"unn\", \"dew\", \"tri\", \"peswar\", \"pymp\" };\nvar allPresent = stringData.All(s =&gt; s.Contains(\"e\"));\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; $StringData = @(\"unn\", \"dew\", \"tri\", \"peswar\", \"pymp\")\nPS&gt; $delegate =  [Func[string,bool]]{ $args[0].Contains(\"e\") }\nPS&gt; [Linq.Enumerable]::Any([string[]]$StringData, $delegate)\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<p>PowerShell does not have an equivalent one-liner to do <span style=\"color: green; font-weight: bold;\"><code>All<\/code><\/span>, <a href=\"http:\/\/stackoverflow.com\/a\/35258435\/115690\">but this StackOverflow post<\/a> shows how to implement a <span style=\"color: #996633; font-weight: bold;\"><code>Test-All<\/code><\/span> function. (Note, however, that that function does not optimizing performance in terms of stopping the pipeline once a determination is made; see comments on <span style=\"color: green; font-weight: bold;\"><code>Any<\/code><\/span>.)<\/p>\n<h3><a id=\"post-71022-_Toc482783753\"><\/a>Contains<\/h3>\n<p>Determines whether a sequence contains a specified element. The sequence may, of course, contain objects of an arbitrary type. In the case of strings, however, note that this method matches against each element in its entirety. Contrast this to the <em>string<\/em> method <span style=\"color: #996633; font-weight: bold;\"><code>Contains<\/code><\/span> that determines whether a string matches against a substring. (See the example for <span style=\"color: green; font-weight: bold;\"><code>All<\/code><\/span>.)<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var stringData = new[] { \"unn\", \"dew\", \"tri\", \"peswar\", \"pymp\" };\nvar result = stringData.Contains(\"dew\");\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">[string[]] $StringData = @(\"unn\", \"dew\", \"tri\", \"peswar\", \"pymp\")\n[Linq.Enumerable]::Contains($StringData, \"dew\")\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">$StringData = @(\"unn\", \"dew\", \"tri\", \"peswar\", \"pymp\")\n$StringData -contains \"dew\"\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783754\"><\/a>SequenceEqual<\/h3>\n<p>Determines whether two sequences are equal; specifically, if the two sequences contain the <em>same<\/em> elements in the <em>same<\/em> order. When dealing with value types, as in the illustration, the use is intuitive: the lists differ at the third position so a determination has been made that they are different, and no further elements of the sequence need to be evaluated. Note that if you use reference types, the elements are matched with <em>reference equality<\/em>; they need to be the actual, same object, not just objects with all the same property values<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">int[] num1 = { 3, 1, 4, 1, 5 };\nint[] num2 = { 3, 1, 5, 1, 4 };\nvar result =  num1.SequenceEqual(num2);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">[int[]] $num1 = @(3, 1, 4, 1, 5 );\n[int[]] $num2 = @(3, 1, 5, 1, 4 ); \n[Linq.Enumerable]:: SequenceEqual($num1, $num2)\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<p>This is similar, in that it compares two sequences, but it is order-independent. This example will return true here while the LINQ expression above returned false.<\/p>\n<pre class=\"theme:powershell-output lang:ps decode:true\">$num1 = @(3, 1, 4, 1, 5 );\n$num2 = @(3, 1, 5, 1, 4 );\n[bool]((Compare-Object -Reference $num1 -Difference $num2) -eq $null)\n<\/pre>\n<h2><a id=\"post-71022-_Toc482783755\"><\/a>Restriction (Filtering)<\/h2>\n<h3><a id=\"post-71022-_Toc482783756\"><\/a>Where<\/h3>\n<p>Filters a sequence of values based on a predicate.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var dates = new DateTime[] {\n    new DateTime(2017, 10, 23),\n    new DateTime(2013, 12, 3),\n    new DateTime(2016, 2, 13)\n};\n\nvar result = dates.Where(d =&gt; d.Year &gt; 2016);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [DateTime[]]$dates = \n    (Get-Date -Year 2017 -Month 10 -Day 23),\n    (Get-Date -Year 2013 -Month 12 -Day 3),\n    (Get-Date -Year 2016 -Month 2 -Day 13)\nPS&gt; [Func[DateTime,bool]] $delegate = { param($d); return $d.Year -gt 2016 }\nPS&gt; [Linq.Enumerable]::Where($dates, $delegate)\nMonday, October 23, 2017 3:38:48 PM\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [DateTime[]]$dates = \n    (Get-Date -Year 2017 -Month 10 -Day 23),\n    (Get-Date -Year 2013 -Month 12 -Day 3),\n    (Get-Date -Year 2016 -Month 2 -Day 13)\nPS&gt; $dates | Where-Object Year -gt 2016\nMonday, October 23, 2017 3:38:48 PM\n<\/pre>\n<h2><a id=\"post-71022-_Toc482783757\"><\/a>Sets<\/h2>\n<h3><a id=\"post-71022-_Toc482783758\"><\/a>Distinct<\/h3>\n<p>Returns distinct elements from a sequence. Note that the sequence does <em>not<\/em> need to be sorted.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">int[] factorsOf300 = { 2, 3, 5, 2, 5};\nint uniqueFactors = factorsOf300.Distinct();\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [int[]] $factorsOf300 = @(2, 3, 5, 2, 5)\nPS&gt; [Linq.Enumerable]::Distinct($factorsOf300)\n2\n3\n5\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; $factorsOf300 = @(2, 3, 5, 2, 5)\nPS&gt; $factorsOf300 | Select-Object -Unique\n2\n3\n5\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783759\"><\/a>Union<\/h3>\n<p>Produces the set union of two sequences. Includes elements in both sequences but without duplication.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">int[] numbersA = { 0, 2, 4, 5 };\nint[] numbersB = { 5, 2, 7, 1 };\nvar uniqueNumbers =numbersA.Union(numbersB);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [int[]] $numbersA = @(0, 2, 4, 5)\nPS&gt; [int[]] $numbersB = @(5, 2, 7, 1)\nPS&gt; [Linq.Enumerable]::Union($numbersA, $numbersB)\n0\n2\n4\n5\n7\n1\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; $numbersA = @(0, 2, 4, 5)\nPS&gt; $numbersB = @(5, 2, 7, 1)\nPS&gt; $numbersA + $numbersB | Select-Object -Unique\n0\n2\n4\n5\n7\n1\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783760\"><\/a>Intersection<\/h3>\n<p>Produces the set intersection of two sequences. Just those elements that exist in both sequences appear in the result.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">int[] numbersA = { 0, 2, 4, 5 };\nint[] numbersB = { 5, 2, 7, 1 };\nvar commonNumbers =numbersA.Intersect(numbersB);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [int[]] $numbersA = @(0, 2, 4, 5)\nPS&gt; [int[]] $numbersB = @(5, 2, 7, 1)\nPS&gt; [Linq.Enumerable]::Intersect($numbersA, $numbersB)\n2\n5\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; $numbersA = @(0, 2, 4, 5)\nPS&gt; $numbersB = @(5, 2, 7, 1)\nPS&gt; $numbersA | Select-Object -Unique | Where-Object { $numbersB -contains $_ }\n2\n5\n<\/pre>\n<h3><a id=\"post-71022-_Toc482783761\"><\/a>Except<\/h3>\n<p>Produces the set difference of one sequence with a second sequence. Just those elements that exist in the first sequence and do <em>not<\/em> exist in the second sequence appear in the result.<\/p>\n<h4>LINQ in C#<\/h4>\n<pre class=\"theme:vs2012 lang:cs decode:true\">int[] numbersA = { 0, 2, 4, 5, 8 };\nint[] numbersB = { 5, 2, 7, 1 };\nvar  aOnlyNumbers = numbersA.Except(numbersB);\n<\/pre>\n<h4>LINQ in PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; [int[]] $numbersA = @(0, 2, 4, 5, 8)\nPS&gt; [int[]] $numbersB = @(5, 2, 7, 1)\nPS&gt; [Linq.Enumerable]::Except($numbersA, $numbersB)\n0\n4\n8\n<\/pre>\n<h4>Native PowerShell<\/h4>\n<pre class=\"theme:powershell-output lang:ps decode:true\">PS&gt; $numbersA = @(0, 2, 4, 5, 8)\nPS&gt; $numbersB = @(5, 2, 7, 1)\nPS&gt; $numbersA | Select-Object -Unique | Where-Object { $numbersB -notcontains $_ }\n0\n4\n8\n<\/pre>\n<h2><a id=\"post-71022-_Toc482783762\"><\/a>Conclusion<\/h2>\n<p>So, yes! LINQ can be done in PowerShell. Depending on the operator, it can be rather burdensome to do so. PowerShell is designed to be quick and easy to use, so be sure that you need the performance boost that LINQ can offer and, indeed, make sure that there is a performance boost for <em>your<\/em> data, and most importantly that the resulting data is correct. As part of your analysis, you may find it useful to have the accompanying wallchart that, for example, shows you at a glance which operators use deferred execution and which use immediate execution. <a href=\"https:\/\/www.simple-talk.com\/wp-content\/plugins\/download-attachments\/includes\/download.php?id=70883\">Click here to download the PDF reference chart<\/a>.<\/p>\n<p><a href=\"https:\/\/www.simple-talk.com\/wp-content\/plugins\/download-attachments\/includes\/download.php?id=70883\"><img loading=\"lazy\" decoding=\"async\" width=\"644\" height=\"377\" class=\"wp-image-71023\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2017\/05\/word-image-32.png\" \/><\/a><\/p>\n\n\n<section id=\"faq\" class=\"faq-block my-5xl\">\n    <h2>FAQs: LINQ in PowerShell<\/h2>\n\n                        <h3 class=\"mt-4xl\">1. Is LINQ faster than native PowerShell loops?<\/h3>\n            <div class=\"faq-answer\">\n                <p>Yes, significantly. PowerShell is an interpreted language that runs a .NET security check on every loop iteration, which makes large loops extremely slow. LINQ operators execute as compiled .NET code, bypassing that overhead. The difference can be dramatic &#8211; operations that take minutes in a native PowerShell loop may complete in seconds with LINQ.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">2. How do you call a LINQ operator in PowerShell?<\/h3>\n            <div class=\"faq-answer\">\n                <p>LINQ operators are static extension methods, so in PowerShell you call them with [Linq.Enumerable]::MethodName($collection, $delegate). The object instance moves into the first argument position, and any delegate arguments must be explicitly typed and created as [Func[Type,Type]] objects.<\/p>\n            <\/div>\n                    <h3 class=\"mt-4xl\">3. What LINQ operators work in PowerShell?<\/h3>\n            <div class=\"faq-answer\">\n                <p>All standard LINQ operators work in PowerShell, including aggregation (Count, Sum, Average, Min, Max), filtering (Where), projection (Select, SelectMany), ordering (OrderBy), grouping (GroupBy), set operations (Distinct, Union, Except), and element operators (First, Last, Single). Each requires explicit delegate typing when called from PowerShell.<\/p>\n            <\/div>\n            <\/section>\n","protected":false},"excerpt":{"rendered":"<p>Complete reference for using LINQ operators in PowerShell. Covers syntax, delegates, performance gains over native loops, and working examples for every LINQ operator.&hellip;<\/p>\n","protected":false},"author":221868,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143538,35],"tags":[4706],"coauthors":[6802],"class_list":["post-71022","post","type-post","status-publish","format-standard","hentry","category-dotnet-development","category-powershell","tag-linq"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/71022","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/221868"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=71022"}],"version-history":[{"count":38,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/71022\/revisions"}],"predecessor-version":[{"id":109301,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/71022\/revisions\/109301"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=71022"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=71022"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=71022"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=71022"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}