{"id":2341,"date":"2012-06-13T17:36:00","date_gmt":"2012-06-13T17:36:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/powershell\/2012\/06\/13\/new-v3-language-features\/"},"modified":"2019-02-18T13:05:39","modified_gmt":"2019-02-18T20:05:39","slug":"new-v3-language-features","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/powershell\/new-v3-language-features\/","title":{"rendered":"New V3 Language Features"},"content":{"rendered":"<p>We&rsquo;ve already discussed the biggest new PowerShell language feature &ndash; workflows &ndash; in a previous post.&nbsp; In this post, I&rsquo;m going to describe a number of small changes we&rsquo;ve made to the language.&nbsp; Most of the changes described here don&rsquo;t introduce any new syntax, but I think you&rsquo;ll agree that most of these changes make various aspects of scripting in PowerShell simpler.&nbsp; To me, many of these features are what make PowerShell a joy to use.<\/p>\n<p>&nbsp;<\/p>\n<h3><\/h3>\n<h3><span style=\"color: #4f81bd\">Member Enumeration<\/span><\/h3>\n<p>To start, I&rsquo;m going to describe a little feature that had no official name until I started this blog post.&nbsp; I&rsquo;m also starting with this feature because it was a surprise hit (to me anyway) when we demonstrated to the PowerShell MVPs recently.<\/p>\n<p>If you find yourself frequently piping a collection to ForEach-Object or Select-Object (or more likely the aliases % or select) to get a single property, then you&rsquo;ll love this feature.<\/p>\n<p>Say you want a list of full paths to some files.&nbsp; In PowerShell V2.0, you&rsquo;d write:<\/p>\n<p align=\"left\">\n<p><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"><span style=\"color: #0000ff;font-family: Lucida Console;font-size: x-small\"><span style=\"color: #000000\"><\/span>dir<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">|<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #0000ff;font-family: Lucida Console;font-size: x-small\">%<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> { <\/span><span style=\"color: #ff4500;font-family: Lucida Console;font-size: x-small\">$_<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">.<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">FullName }<\/span><\/span><\/p>\n<p align=\"left\">In PowerShell V3.0, you can write:<\/p>\n<p><span style=\"color: #0000ff;font-family: Lucida Console;font-size: x-small\">(dir)<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">.<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">FullName<\/span><\/p>\n<p>It doesn&rsquo;t matter if the cmdlet is returning one result or multiple results.&nbsp; Under the covers, PowerShell is automatically handling the differences for you, as though you were using ForEach-Object in the first example, except it&rsquo;s faster because the ForEach-Object cmdlet isn&rsquo;t actually running.<\/p>\n<p>This new capability doesn&rsquo;t introduce any new syntax and it just works wherever you would get a property or invoke a method.&nbsp; But you can&rsquo;t use this syntax to set properties.<\/p>\n<p>We added this feature to make it easier to deal with commands that return one or many objects.&nbsp; Experienced PowerShell scripters knew they needed to use @() to handle that situation correctly, but we really thought that was less than perfect.<\/p>\n<p>Member enumeration is one piece of handling commands that return one or many objects, but there are a few other details that we&rsquo;ve taken care of as well.<\/p>\n<p>You can now use Count or Length on any object, even if it didn&rsquo;t have the property.&nbsp; If the object didn&rsquo;t have a Count or Length property, it will will return 1 (or 0 for $null).&nbsp; Objects that have Count or Length properties will continue to work as they always have.<\/p>\n<p><span style=\"font-family: Lucida Console\"><span style=\"font-size: x-small\">PS&gt; <span style=\"color: #ff4500\">$a<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #a9a9a9\">=<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #800080\">42<\/span><\/span><\/span> <br \/><span style=\"font-family: Lucida Console\"><span style=\"font-size: x-small\">PS&gt; <span style=\"color: #ff4500\">$a<span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">.<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">Count<\/span><\/span> <br \/><\/span><\/span><span style=\"font-family: Lucida Console\"><span style=\"color: #ff4500\"><span style=\"font-size: x-small\"><span style=\"color: #000000\">1<\/span><\/span><\/span><\/span><\/p>\n<p>You can also index into any object even if it didn&rsquo;t have an index operation.&nbsp; If the object has no indexer, index 0 simply returns the object, any other index returns nothing (or an error if strict-mode is enabled).<\/p>\n<p><span style=\"font-family: Lucida Console\"><span style=\"font-size: x-small\">PS&gt; <span style=\"color: #ff4500\">$a<\/span><span style=\"color: #a9a9a9\">[<span style=\"color: #800080\">0<\/span>] <br \/><span style=\"font-family: Lucida Console\"><span style=\"color: #ff4500\"><span style=\"font-size: x-small\"><span style=\"color: #000000\">42 <br \/><span style=\"font-family: Lucida Console\"><span style=\"font-size: x-small\">PS&gt; <span style=\"color: #ff4500\">$a<\/span><span style=\"color: #a9a9a9\">[<span style=\"color: #800080\">-1<\/span>] <br \/><span style=\"font-family: Lucida Console\"><span style=\"color: #ff4500\"><span style=\"font-size: x-small\"><span style=\"color: #000000\">42<\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/span><\/p>\n<p>Combining indexing and Count, you can now use for loops without worrying if the input is an array or single object:<span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"><\/span><\/p>\n<p align=\"left\">\n<p><span style=\"color: #ff4500;font-family: Lucida Console;font-size: x-small\">$x<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">=<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #0000ff;font-family: Lucida Console;font-size: x-small\">dir<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #006400;font-family: Lucida Console;font-size: x-small\"># returns 1 or more objects <br \/><\/span><span style=\"color: #00008b;font-family: Lucida Console;font-size: x-small\">for<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> (<\/span><span style=\"color: #ff4500;font-family: Lucida Console;font-size: x-small\">$i<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">=<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #800080;font-family: Lucida Console;font-size: x-small\">0<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">; <\/span><span style=\"color: #ff4500;font-family: Lucida Console;font-size: x-small\">$i<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">&ndash;lt<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #ff4500;font-family: Lucida Console;font-size: x-small\">$x<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">.<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">Count; <\/span><span style=\"color: #ff4500;font-family: Lucida Console;font-size: x-small\">$i<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">++<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">) <br \/>{ <br \/><\/span><span style=\"color: #ff4500;font-family: Lucida Console;font-size: x-small\">&nbsp;&nbsp;&nbsp; $x<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">[<\/span><span style=\"color: #ff4500;font-family: Lucida Console;font-size: x-small\">$i<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">]<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #8a2be2;font-family: Lucida Console;font-size: x-small\">&#8230; <br \/><\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">}<\/span><\/p>\n<p align=\"left\">\n<p>These language features could actually change the behavior some scripts.&nbsp; We&rsquo;ve found a few real-world scripts that stopped working due to these changes.&nbsp; But we also found, after closer review of these scripts, that they were already broken.&nbsp; In one example the script was actually failing to process all of the data it was trying to verify.&nbsp; We are not aware of any scripts where this change broke a script, but did not expose an underlying problem in the script.<\/p>\n<p>&nbsp;<\/p>\n<\/p>\n<p><span style=\"color: #4f81bd;font-size: medium\">New Redirection Operators<\/span><\/p>\n<p class=\"MsoNormal\">There are new redirection operators so you can redirect verbose, warning, and debug streams.&nbsp; Merging and file redirections work in the same way as error redirection.&nbsp; Here are some examples:<\/p>\n<p align=\"left\">\n<p><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"><span style=\"color: #0000ff;font-family: Lucida Console;font-size: x-small\">Do-Something<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">3&gt;<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #8a2be2;font-family: Lucida Console;font-size: x-small\">warning.txt<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">&nbsp; <\/span><span style=\"color: #006400;font-family: Lucida Console;font-size: x-small\"># Writes warning output to warning.txt <br \/><\/span><span style=\"color: #0000ff;font-family: Lucida Console;font-size: x-small\">Do-Something<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">4&gt;&gt;<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #8a2be2;font-family: Lucida Console;font-size: x-small\">verbose.txt<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #006400;font-family: Lucida Console;font-size: x-small\"># Appends verbose.txt with the verbose output <br \/><\/span><span style=\"color: #0000ff;font-family: Lucida Console;font-size: x-small\">Do-Something<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">5&gt;&amp;1<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #006400;font-family: Lucida Console;font-size: x-small\"># Writes debug output to the output stream <br \/><\/span><span style=\"color: #0000ff;font-family: Lucida Console;font-size: x-small\">Do-Something<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">*&gt;<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #8a2be2;font-family: Lucida Console;font-size: x-small\">out.txt<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #006400;font-family: Lucida Console;font-size: x-small\"># Redirects all streams (output, error, warning, verbose, and debug) to out.txt<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"><\/span><\/span><\/span><\/p>\n<p align=\"left\">\n<p class=\"Code\">We didn&rsquo;t get a chance to add redirection support for host output (Write-Host, $host.UI.Write&hellip;).<\/p>\n<p class=\"Code\">&nbsp;<\/p>\n<\/p>\n<p><span style=\"color: #4f81bd;font-size: medium\">Passing Local Variables to Remote Sessions<\/span><\/p>\n<p>In PowerShell 2.0, if you want to use local variables when executing a script block remotely, you have to do something like:<\/p>\n<p><span style=\"font-family: Lucida Console\"><span style=\"font-size: x-small\">PS&gt; <span style=\"color: #ff4500\">$localVar<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #a9a9a9\">=<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #800080\">42 <\/span><\/span><\/span> <br \/><span style=\"font-family: Lucida Console\"><span style=\"font-size: x-small\">PS&gt; <span style=\"color: #0000ff\">Invoke-Command<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #000080\">-cn<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #8a2be2\">srv123<\/span><span style=\"color: #000000\"> { <\/span><span style=\"color: #00008b\">param<\/span><span style=\"color: #000000\">(<\/span><span style=\"color: #ff4500\">$localVar<\/span><span style=\"color: #000000\">) <\/span><span style=\"color: #0000ff\">echo<\/span><span style=\"color: #000000\"> <\/span><span style=\"color: #ff4500\">$localVar<\/span><span style=\"color: #000000\"> } <\/span><span style=\"color: #000080\">&ndash;ArgumentList<\/span><span style=\"color: #000000\"> <\/span><\/span><\/span><span style=\"font-family: Lucida Console\"><span style=\"color: #ff4500\"><span style=\"font-size: x-small\">$localVar <br \/><span style=\"color: #000000\">42<\/span><\/span><\/span><\/span><\/p>\n<p>In PowerShell 3.0, variables prefixed with $using: are automatically recognized as local variables and are sent to the remote machine:<\/p>\n<p><span style=\"font-family: Lucida Console\"><span style=\"font-size: x-small\">PS&gt; <\/span><span style=\"color: #0000ff;font-size: x-small\">Invoke-Command<\/span><span style=\"color: #000000;font-size: x-small\"> <\/span><span style=\"color: #000080;font-size: x-small\">&ndash;cn<\/span><span style=\"color: #000000;font-size: x-small\"> <\/span><span style=\"color: #8a2be2;font-size: x-small\">srv123<\/span><span style=\"color: #000000;font-size: x-small\"> { <\/span><span style=\"color: #0000ff;font-size: x-small\">echo<\/span><span style=\"color: #000000;font-size: x-small\"> <\/span><span style=\"color: #ff4500;font-size: x-small\">$using:localVar<\/span><\/span><span style=\"font-family: Lucida Console\"><span style=\"font-size: x-small\"><span style=\"color: #000000\"> } <br \/><\/span><span style=\"color: #000000\">42<\/span><\/span><\/span><\/p>\n<p>&nbsp;&nbsp;<\/p>\n<p><span style=\"color: #4f81bd;font-size: medium\">PSItem<\/span><\/p>\n<p>We sometimes receive feedback that $_ is cryptic and confusing to people who are new to PowerShell and scripting.&nbsp; Some people see $_ as a magic symbol.&nbsp; To help those people, we introduced an alias for $_.&nbsp; You can use $PSItem anywhere you would have used $_.&nbsp; For example, instead of writing:<\/p>\n<p align=\"left\">\n<p><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"><span style=\"color: #0000ff;font-family: Lucida Console;font-size: x-small\"><span style=\"color: #000000\"><\/span>dir<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">|<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #0000ff;font-family: Lucida Console;font-size: x-small\">%<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> { <\/span><span style=\"color: #ff4500;font-family: Lucida Console;font-size: x-small\">$_<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">.<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">FullName }<\/span><\/span><\/p>\n<p>You can write:<\/p>\n<p align=\"left\">\n<p><span style=\"color: #0000ff;font-family: Lucida Console;font-size: x-small\"><span style=\"color: #000000\"><\/span>dir<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">|<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #0000ff;font-family: Lucida Console;font-size: x-small\">%<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> { <\/span><span style=\"color: #ff4500;font-family: Lucida Console;font-size: x-small\">$PSItem<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">.<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">FullName }<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #4f81bd;font-size: medium\">More Flexible Script Formatting<\/span><\/p>\n<p>We reviewed many places where newlines were previously required and relaxed those restrictions whenever it didn&rsquo;t introduce any ambiguities or break existing scripts.<\/p>\n<p>One of the more interesting places you might find this useful is in using a fluent API.&nbsp; You can now have whitespace\/newlines after the &lsquo;.&rsquo; or &lsquo;::&rsquo; tokens in expression mode.<\/p>\n<p align=\"left\">\n<p><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">[<\/span><span style=\"color: #008080;font-family: Lucida Console;font-size: x-small\">PowerShell<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">]::<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">Create()<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">. <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">AddCommand(<\/span><span style=\"color: #8b0000;font-family: Lucida Console;font-size: x-small\">&#8220;echo&#8221;<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">)<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">. <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">AddParameter(<\/span><span style=\"color: #8b0000;font-family: Lucida Console;font-size: x-small\">&#8220;InputObject&#8221;<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">,<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #800080;font-family: Lucida Console;font-size: x-small\">42<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">)<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">. <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">Invoke()<\/span><\/span><\/span><\/p>\n<p align=\"left\">\n<p class=\"MsoNormal\">In PowerShell 2.0, this needs to be all on one line, or broken into multiple statements.&nbsp; For example, the following probably doesn&rsquo;t do what you think it should.<\/p>\n<p align=\"left\">\n<p><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"><span style=\"color: #0000ff;font-family: Lucida Console;font-size: x-small\">Write-Output<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> (<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">[<\/span><span style=\"color: #008080;font-family: Lucida Console;font-size: x-small\">int<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">]::<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">MaxValue)<\/span><span style=\"color: #8a2be2;font-family: Lucida Console;font-size: x-small\">.<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #8a2be2;font-family: Lucida Console;font-size: x-small\">GetType<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">() <br \/><\/span><span style=\"color: #0000ff;font-family: Lucida Console;font-size: x-small\">Write-Output<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> (<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">[<\/span><span style=\"color: #008080;font-family: Lucida Console;font-size: x-small\">int<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">]::<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">MaxValue)<\/span><span style=\"color: #8a2be2;font-family: Lucida Console;font-size: x-small\">. <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #0000ff;font-family: Lucida Console;font-size: x-small\">GetType<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">()<\/span><\/span><\/span><\/p>\n<p align=\"left\">\n<p class=\"MsoNormal\">The same expressions work when they don&rsquo;t begin with a command:<\/p>\n<p align=\"left\">(<span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">[<\/span><span style=\"color: #008080;font-family: Lucida Console;font-size: x-small\">int<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">]::<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">MaxValue)<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">.<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> GetType() <br \/>(<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">[<\/span><span style=\"color: #008080;font-family: Lucida Console;font-size: x-small\">int<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">]::<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">MaxValue)<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">. <br \/>&nbsp;&nbsp;&nbsp; <\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">GetType()<\/span><\/p>\n<p align=\"left\">&nbsp;<\/p>\n<\/p>\n<p><span style=\"color: #4f81bd;font-size: medium\">Attributes on Variables<\/span><\/p>\n<p>Validation attributes and argument transformation attributes are familiar to anyone who writes advanced functions.&nbsp; In PowerShell V2.0, these attributes can be used only on parameters.&nbsp; In PowerShell V3.0, you can place an attribute on any variable.<\/p>\n<p class=\"Code\"><span style=\"font-family: Lucida Console\"><span style=\"font-size: x-small\">PS&gt; <span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">[<\/span><span style=\"color: #00bfff;font-family: Lucida Console;font-size: x-small\">ValidateRange<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">(<\/span><span style=\"color: #800080;font-family: Lucida Console;font-size: x-small\">1<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">,<\/span><span style=\"color: #800080;font-family: Lucida Console;font-size: x-small\">10<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">)<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">][<\/span><span style=\"color: #008080;font-family: Lucida Console;font-size: x-small\">int<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">]<\/span><span style=\"color: #ff4500;font-family: Lucida Console;font-size: x-small\">$x<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">=<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #800080;font-family: Lucida Console;font-size: x-small\">1<\/span> <br \/>PS&gt; <span style=\"color: #ff4500;font-family: Lucida Console;font-size: x-small\">$x<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">=<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #800080;font-family: Lucida Console;font-size: x-small\">11<\/span> <br \/>The variable cannot be validated because the value 11 is not a valid value for the x variable. <br \/>At line:1 char:1 <br \/>+ $x = 11 <br \/>+ ~~~~~~~ <br \/>&nbsp;&nbsp;&nbsp; + CategoryInfo&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : MetadataError: (:) [], ValidationMetadataException <br \/>&nbsp;&nbsp;&nbsp; + FullyQualifiedErrorId : ValidateSetFailure<\/span><\/span><\/p>\n<p class=\"Code\">&nbsp;&nbsp;<\/p>\n<p><span style=\"color: #4f81bd;font-size: medium\">Attribute Arguments Don&rsquo;t Need = $true<\/span><\/p>\n<p class=\"MsoNormal\">In PowerShell V2.0, you write:<\/p>\n<p class=\"MsoNormal\"><span style=\"font-family: 'Lucida Console';color: darkblue;font-size: 9pt\">param<\/span><span style=\"font-family: 'Lucida Console';font-size: 9pt\">(<span style=\"color: darkgray\">[<\/span><span style=\"color: deepskyblue\">Parameter<\/span>(Mandatory<span style=\"color: darkgray\">=<\/span><span style=\"color: orangered\">$true<\/span>)<span style=\"color: darkgray\">]<\/span><span style=\"color: orangered\">$p<\/span>)<\/span><\/p>\n<p class=\"MsoNormal\">In PowerShell V3.0, you can write:<\/p>\n<p class=\"MsoNormal\"><span style=\"font-family: 'Lucida Console';color: darkblue;font-size: 9pt\">param<\/span><span style=\"font-family: 'Lucida Console';font-size: 9pt\">(<span style=\"color: darkgray\">[<\/span><span style=\"color: deepskyblue\">Parameter<\/span>(Mandatory)<span style=\"color: darkgray\">]<\/span><span style=\"color: orangered\">$p<\/span>)<\/span><\/p>\n<p class=\"MsoNormal\">\n<p>If you omit the argument, there is an implied argument value of $true.<\/p>\n<p>&nbsp;<\/p>\n<\/p>\n<p><span style=\"color: #4f81bd;font-size: medium\">Smarter Parsing of Command Names<\/span><\/p>\n<p>In PowerShell V2.0, if you are running 7z or another command that starts with a number, you have to use the command invocation operator:<\/p>\n<p><span style=\"color: #0000ff;font-family: Lucida Console;font-size: x-small\"><span style=\"color: #000000\">PS&gt; <span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">&amp;<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #0000ff;font-family: Lucida Console;font-size: x-small\">7z <\/span><\/span><\/span><\/p>\n<p>In PowerShell V3.0, you don&rsquo;t need the &lsquo;&amp;&rsquo; anymore.<\/p>\n<p>&nbsp;<\/p>\n<\/p>\n<p><span style=\"color: #4f81bd;font-size: medium\">Easier Reuse of Command Lines From Cmd.exe<\/span><\/p>\n<p>The web is full of command lines written for Cmd.exe.&nbsp; These commands lines work often enough in PowerShell, but when they include certain characters, e.g. a semicolon (;) a dollar sign ($), or curly braces, you have to make some changes, probably adding some quotes.&nbsp; This seemed to be the source of many minor headaches.<\/p>\n<p>To help address this scenario, we added a new way to &ldquo;escape&rdquo; the parsing of command lines.&nbsp; If you use a magic parameter &#8211;%, we stop our normal parsing of your command line and switch to something much simpler.&nbsp; We don&rsquo;t match quotes.&nbsp; We don&rsquo;t stop at semicolon.&nbsp; We don&rsquo;t expand PowerShell variables.&nbsp; We do expand environment variables if you use Cmd.exe syntax (e.g. %TEMP%).&nbsp; Other than that, the arguments up to the end of the line (or pipe, if you are piping) are passed as is.&nbsp; Here is an example:<\/p>\n<p><span style=\"color: #0000ff;font-family: Lucida Console;font-size: x-small\"><span style=\"color: #000000\">PS&gt; <\/span>echoargs.exe<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #8a2be2;font-family: Lucida Console;font-size: x-small\">&#8211;%<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #8a2be2;font-family: Lucida Console;font-size: x-small\">%USERNAME%,this=$something{weird}<\/span> <br \/><span style=\"font-family: Lucida Console;font-size: x-small\">Arg 0 is &lt;jason,this=$something{weird}&gt;<\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #4f81bd;font-size: medium\">Better Splatting of Arrays<\/span><\/p>\n<p class=\"MsoNormal\">Sometimes you want to write a quick wrapper for a script or cmdlet, but you don&rsquo;t want to write a full-on proxy cmdlet.&nbsp; For example:<\/p>\n<p class=\"MsoNormal\"><span style=\"font-family: 'Lucida Console';color: darkblue;font-size: 9pt\"><span style=\"font-size: x-small\">function<\/span><\/span><span style=\"font-family: 'Lucida Console';font-size: 9pt\"><span style=\"font-size: x-small\"> <span style=\"color: blueviolet\">mkdir<\/span>(<span style=\"color: orangered\">$path<\/span>) <br \/><\/span><\/span><span style=\"font-family: 'Lucida Console';font-size: 9pt\"><span style=\"font-size: x-small\">{ <br \/><\/span><\/span><span style=\"font-family: 'Lucida Console';font-size: 9pt\"><span style=\"font-size: x-small\">&nbsp;&nbsp;&nbsp; <span style=\"color: blue\">New-Item<\/span> <span style=\"color: navy\">-Path<\/span> <span style=\"color: orangered\">$path<\/span> <span style=\"color: navy\">-ItemType<\/span> <span style=\"color: blueviolet\">Directory<\/span> <\/span><span style=\"color: orangered\"><span style=\"font-size: x-small\">@args <br \/><\/span><\/span><\/span><span style=\"font-family: 'Lucida Console';font-size: 9pt\"><span style=\"font-size: x-small\">} <\/span><\/span><\/p>\n<p class=\"MsoNormal\">Now if I pass -Force or whatever to mkdir, it will be passed on correctly, but I didn&rsquo;t need to specify any of the parameters to New-Item.<\/p>\n<p class=\"MsoNormal\">&nbsp;<\/p>\n<p class=\"MsoNormal\"><span style=\"color: #4f81bd;font-size: medium\">New Operators<\/span><\/p>\n<p>We added a few operators:<\/p>\n<table style=\"width: 523px\" border=\"1\" cellspacing=\"0\" cellpadding=\"2\">\n<tbody>\n<tr>\n<td width=\"138\" valign=\"top\">-shl<\/td>\n<td width=\"383\" valign=\"top\">Shift bits left<\/td>\n<\/tr>\n<tr>\n<td width=\"140\" valign=\"top\">-shr<\/td>\n<td width=\"381\" valign=\"top\">Shift bits right &ndash; preserves sign for signed values<\/td>\n<\/tr>\n<tr>\n<td width=\"142\" valign=\"top\">-in<\/td>\n<td width=\"380\" valign=\"top\">Like &ndash;contains, but with the operands reversed<\/td>\n<\/tr>\n<tr>\n<td width=\"143\" valign=\"top\">-notin<\/td>\n<td width=\"379\" valign=\"top\">Like &ndash;notcontains, but with the operands reversed<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>-in\/-notin were added to complement the &ldquo;simplified foreach&rdquo; feature.&nbsp; We couldn&rsquo;t support the &ndash;contains\/-notcontains operators in simplified foreach, but by reversing the operands, we could have ForEach-Object support and operator support.<\/p>\n<p>&nbsp;&nbsp;<\/p>\n<p><span style=\"color: #4f81bd;font-size: medium\">New Conversions<\/span><\/p>\n<p>Sometimes you want the keys of a hash literal to be ordered.&nbsp; You can now cast to [ordered] and we create an OrderedDictionary instead of HashTable.&nbsp; This only works with literals &ndash; if you try it on a variable, the ordering is no longer available.<\/p>\n<p align=\"left\">\n<p><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">[<\/span><span style=\"color: #008080;font-family: Lucida Console;font-size: x-small\">ordered<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">]<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">@{a<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">=<\/span><span style=\"color: #800080;font-family: Lucida Console;font-size: x-small\">1<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">; b<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">=<\/span><span style=\"color: #800080;font-family: Lucida Console;font-size: x-small\">2<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">} <\/span><\/span><\/p>\n<p>In a similar manner, you can create custom objects with a simple cast:<\/p>\n<p align=\"left\">\n<p><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">[<\/span><span style=\"color: #008080;font-family: Lucida Console;font-size: x-small\">pscustomobject<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">]<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">@{x<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">=<\/span><span style=\"color: #800080;font-family: Lucida Console;font-size: x-small\">1<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">; y<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">=<\/span><span style=\"color: #800080;font-family: Lucida Console;font-size: x-small\">2<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">} <\/span><\/span><\/p>\n<p>This does not create a HashTable; it creates a PSObject with note properties.&nbsp; If you are casting a literal, the note properties are added in the order they appear in the literal.&nbsp; If you are casting anything else, the ordering is determined by the IDictionary iterator.<\/p>\n<p>If a type has a default constructor and settable properties, you can also use a hash table to case an object to that type:<\/p>\n<\/p>\n<p align=\"left\">\n<p><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">[<\/span><span style=\"color: #008080;font-family: Lucida Console;font-size: x-small\">System.Drawing.Point<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">]<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">@{X<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">=<\/span><span style=\"color: #800080;font-family: Lucida Console;font-size: x-small\">1<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">; Y<\/span><span style=\"color: #a9a9a9;font-family: Lucida Console;font-size: x-small\">=<\/span><span style=\"color: #800080;font-family: Lucida Console;font-size: x-small\">2<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">}<\/span><\/p>\n<p align=\"left\">This will call the default constructor and set the properties named in the hash table.<\/p>\n<p>In a similar manner, deserialized objects can be reconstructed if the properties are all settable.<\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #4f81bd;font-size: medium\">ForEach statement does not iterate over $null<\/span><\/p>\n<p>In PowerShell V2.0, people were often surprised by:<\/p>\n<p><span style=\"font-family: Lucida Console\"><span style=\"font-size: x-small\">PS&gt; <\/span><span style=\"color: #00008b;font-family: Lucida Console;font-size: x-small\">foreach<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> (<\/span><span style=\"color: #ff4500;font-family: Lucida Console;font-size: x-small\">$i<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #00008b;font-family: Lucida Console;font-size: x-small\">in<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> <\/span><span style=\"color: #ff4500;font-family: Lucida Console;font-size: x-small\">$null<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\">) { <\/span><span style=\"color: #8b0000;font-family: Lucida Console;font-size: x-small\">&#8216;got here&#8217;<\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"> }<\/span> <br \/><span style=\"font-size: x-small\">got here<\/span><\/span><\/p>\n<p>This situation often comes up when a cmdlet doesn&rsquo;t return any objects.&nbsp; In PowerShell V3.0, you don&rsquo;t need to add an if statement to avoid iterating over $null.&nbsp; We take care of that for you.<\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #4f81bd;font-size: medium\">Comment Based Help Improvements<\/span><\/p>\n<p>PowerShell V2.0 comment based help supports most of the features available in xml based help, but there were a couple of holes that we&rsquo;ve addressed in V3, both related to parameter help.&nbsp; If you use Get-Help &ndash;full, you see a bunch of parameter descriptions that include text like the following:<\/p>\n<p>Required?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; true <br \/>Position?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; named <br \/><span style=\"background-color: #ffff00\">Default value&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; False <br \/><\/span>Accept pipeline input?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; false <br \/><span style=\"background-color: #ffff00\">Accept wildcard characters?&nbsp; false <br \/><\/span><\/p>\n<p>PowerShell V2.0 didn&rsquo;t provide any way to specify what help gets displayed for the highlighted fields above.&nbsp; In PowerShell V2.0, we&rsquo;ve fixed that.<\/p>\n<p>For default values, if you&rsquo;ve specified a default value, we include that.&nbsp; If you want finer control over what gets displayed, say to provide some context about the default value, you can use the attribute PSDefaultValue.<\/p>\n<p>If your parameter supports wildcards, you can add the SupportsWildCards attribute.<\/p>\n<p>Note that these 2 attributes are only used for help.&nbsp; PowerShell doesn&rsquo;t use these attributes for anything else.<\/p>\n<p>Here is an example:<\/p>\n<p><span style=\"font-family: 'Lucida Console';color: darkblue;font-size: 9pt\"><span style=\"font-size: x-small\">function<\/span><\/span><span style=\"font-family: 'Lucida Console';font-size: 9pt\"><span style=\"font-size: x-small\"> <span style=\"color: blueviolet\">Test-Something<\/span>(<span style=\"color: orangered\">$path<\/span>) <br \/><\/span><\/span><span style=\"font-family: 'Lucida Console';font-size: 9pt\"><span style=\"font-size: x-small\">{ <br \/><\/span><\/span><span style=\"font-family: 'Lucida Console';color: darkblue;font-size: 9pt\">&nbsp;&nbsp;&nbsp; param<\/span><span style=\"font-family: 'Lucida Console';font-size: 9pt\">(<span style=\"color: darkgray\">[<\/span><span style=\"color: deepskyblue\">PSDefaultValue<\/span>(Help = <span style=\"color: #8b0000;font-family: Lucida Console;font-size: x-small\">&#8216;A random number.&#8217;<\/span>)<span style=\"color: darkgray\">]<\/span><span style=\"color: orangered\">$p<\/span> = $(<span style=\"color: #0000ff;font-family: Lucida Console;font-size: x-small\">Get-Random<\/span>), <br \/><span style=\"font-family: 'Lucida Console';font-size: 9pt\"><span style=\"color: darkgray\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [<\/span><span style=\"color: deepskyblue\">SupportsWildcards<\/span>()<span style=\"color: darkgray\">]<\/span><span style=\"color: orangered\">$q<\/span>)<\/span><\/span><span style=\"font-family: 'Lucida Console';font-size: 9pt\"><span style=\"font-size: x-small\"> <br \/><\/span><\/span><span style=\"font-family: 'Lucida Console';font-size: 9pt\"><span style=\"font-size: x-small\">} <\/span><\/span><span style=\"color: #000000;font-family: Lucida Console;font-size: x-small\"><\/span><\/p>\n<p>&nbsp;<\/p>\n<p><span style=\"color: #4f81bd;font-size: medium\">Conclusion<\/span><\/p>\n<p>We hope these new language features make scripting easier and more fun.&nbsp; In an upcoming post, we&rsquo;ll cover other ways that we&rsquo;ve made scripting easier.<\/p>\n<p>&nbsp;<\/p>\n<p>Jason Shirk <br \/>Software Design Engineer &ndash; Windows PowerShell <br \/>Microsoft Corporation<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We&rsquo;ve already discussed the biggest new PowerShell language feature &ndash; workflows &ndash; in a previous post.&nbsp; In this post, I&rsquo;m going to describe a number of small changes we&rsquo;ve made to the language.&nbsp; Most of the changes described here don&rsquo;t introduce any new syntax, but I think you&rsquo;ll agree that most of these changes make [&hellip;]<\/p>\n","protected":false},"author":600,"featured_media":13641,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[33,352],"class_list":["post-2341","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell","tag-language","tag-windows-server-2012"],"acf":[],"blog_post_summary":"<p>We&rsquo;ve already discussed the biggest new PowerShell language feature &ndash; workflows &ndash; in a previous post.&nbsp; In this post, I&rsquo;m going to describe a number of small changes we&rsquo;ve made to the language.&nbsp; Most of the changes described here don&rsquo;t introduce any new syntax, but I think you&rsquo;ll agree that most of these changes make [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/2341","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/users\/600"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/comments?post=2341"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/posts\/2341\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media\/13641"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/media?parent=2341"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/categories?post=2341"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/powershell\/wp-json\/wp\/v2\/tags?post=2341"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}