1

I'm new with Powershell can someone explaine to me why Parentheses and point are used for :

(get-cluster).PreferredSite="SiteA"

why not just :

get-cluster | set-preferredSite -Name SiteA
  • 6
    `just` is a deceptive word; Why put a bed and a desk and a wardrobe in the same room when you could `just` build a dedicated walk-in wardrobe and a dedicated study room and a dedicated bedroom and a dedicated walkway between them? The object/property syntax comes from the .Net framework and C# and is common over many languages (Java/Python/Ruby/etc). Building dedicated cmdlets for every property of every type of object would be a lot more effort, and would fail as soon as you had a dynamic object with unknown properties like from `Import-Csv`. – TessellatingHeckler Jul 30 '17 at 22:49
  • 2
    Be aware that the first syntax only works because `Get-Cluster` returns a single "live" object, changes to which will immediately be reflected by the cluster configuration. This is a quite clumsy (and possibly dangerous) design, don't expect many other cmdlets to let you do this – Mathias R. Jessen Jul 30 '17 at 23:20

1 Answers1

5

Set-preferredSite looks like the (hypothetical) name of a cmdlet, and, as TessellatingHeckler points out, it would be practically impossible to build a cmdlet for each and every property name (leaving aside the fact that there can be dynamically created properties whose names you cannot predict).

Therefore, you have no choice but to use PowerShell's syntax for assigning a value to an object's property, which generally requires the use of an expression, which is not CLI-like (argument mode) but programming-language-like (expression mode).

PowerShell v3+ does offer a less "noisy" syntax with its so-called operation statement; e.g.:

Get-Cluster | % PreferredSite

which is the equivalent of the more verbose:

Get-Cluster | % { $_.PreferredSite }

However, operation statements do not support assignments, so the following does NOT work:

Get-Cluster | % PreferredSite = 'SiteA' # !! Does NOT work.

My guess as to why that is not supported is that it's rare to want to use the pipeline to set the property of each item in a potentially large input set to the same value.

For a smallish collection, (Get-Cluster).PreferredSite="SiteA" will do just fine, even though the output from Get-Cluster is collected in memory as a whole first (if Get-Cluster outputs more than 1 object, .PreferredSite is accessed on each item in the collection in PSv3+, a feature called member-access enumeration).

For large collections, use % (ForEach-Object) with a custom script block:

Get-Cluster | % { $_.PreferredSite = 'SiteA' }

Note how:

  • the statement inside { ... } is an assignment expression.
  • $_ is the automatic variable that refers to the input object at hand in each iteration.
mklement0
  • 382,024
  • 64
  • 607
  • 775