Recently I responded to an email from a student seeking clarification about the difference between ByValue and ByProperty when it comes to parameter binding. This is what makes pipelined expressions work in Windows PowerShell. When you look at cmdlet help, you'll see that some parameters accept pipeline binding, which is what you are looking for. Often this means you don't need to resort to a ForEach-Object construct. Here's an example.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
ByValue means if I see something I'll use it. ByProperty means I'm looking for a specific object property. For example, Get-Service uses the Name property to find a service.
PS S:\> help get-service -Parameter Name -Name <string[]> Specifies the service names of services to be retrieved. Wildcards are permitted. By default, Get-Service gets all of the services on the computer. Required? false Position? 1 Default value Accept pipeline input? true (ByValue, ByPropertyName) Accept wildcard characters? true
This parameter accepts both types of binding. This means you can do this:
PS S:\> "wuauserv" | get-service Status Name DisplayName ------ ---- ----------- Running wuauserv Windows Update
This is an example of byValue. Get-Service sees something in the pipeline and assumes it is a service name. However, for Get-Service this would also work.
PS S:\> $all=get-service PS S:\> $all[0] | get-service Status Name DisplayName ------ ---- ----------- Stopped AeLookupSvc Application Experience
$all[0] is a service object with name property which when piped to Get-Service, finds the property and binds to it. Here's another example that shows binding by property name can be from any object, not just a service object.
PS S:\> new-object psobject -Property @{Name="wuauserv";Date=Get-date;computername=$env:computername} | get-service Status Name DisplayName ------ ---- ----------- Running wuauserv Windows Update >/pre> This is a custom object with a name property that happens to be valid service name. If you try it with a non-valid name, you'll get an error which proves it is binding on the property name. The other properties in my New-Object example are just to have something. Let me wrap this discussion with one more example that leverages parameter binding:PS C:\work> get-content servers.txt | where {$_ -AND (Test-Connection $_ -quiet -count 2) } | Select @{Name="Computername";Expression={$_.Trim()}} | get-service wuauserv | select Name,status,Machinename Name Status MachineName ---- ------ ----------- wuauserv Running CHI-DC01 wuauserv Running CHI-DC02 wuauserv Stopped CHI-FP01 wuauserv Running CHI-DB01 wuauserv Running CHI-EX01This is a one line expression that leverages the pipeline and uses some helpful (I hope) techniques. The first part using Get-Content retrieves the list of computer names from the text file. Because the text file might have blank lines and some computers might be offline, each name is piped to Where-Object which will only pass on names that exist (skipping blanks) and that can be pinged. To speed things up I'm only sending 2 pings. Now the fun part. I could use ForEach-Object and pass $_ as the value for -Computername. But according to help, this parameter accepts binding by property name.
PS S:\> help get-service -Parameter Computername -ComputerNameGets the services running on the specified computers. The default is the local computer. Type the NetBIOS name, an IP address, or a fully qualified domain name of a remote computer. To specify the local c omputer, type the computer name, a dot (.), or "localhost". This parameter does not rely on Windows PowerShell remoting. You can use the ComputerName parameter of Get-Service even if your computer is not configured to run remote commands. Required? false Position? named Default value Localhost Accept pipeline input? true (ByPropertyName) Accept wildcard characters? false So I'll take the computername value coming from Where-Object and use a hash table with Select-Object to define a new "property" name, called Computername. I also take the liberty of trimming off any leading or trailing spaces, just in case. Now I have an object with a property called Computername that is piped to Get-Service which binds on the computername property. The rest is merely formatting.
Look for opportunities to bind by parameter, which means reading cmdlet help which is a good habit to have regardless.
Jeff,
Explaining the above, is critical to each IT staff persons awareness (and more importantly) their ability to confidently execute a series of PowerShell tasks through the ‘PowerShell pipeline’ technology and Cmdlets. Being a former OpenVMS developer, I can’t say enough about it and thoroughly believe in it and know it works.
The ability to pass parameters by value or property makes or breaks whether they can leap ahead and excelerate the use of PS, or fall back to less complex methods to accomplish their IT needs, especially when push comes to shove.
Is explaining to this level of detail your niche, because their is a market and you will increase your readership by doing so.
–
What I’m trying to say, is that to really get your point across to readers and make it stick, you’ve got to add an addendum onto this page. Then site at least a half dozen broadly differing and distinct working uses of how the parameters by value or property operation works and how to distinquish between them – in black and white terms, from the start of the task to the finish.
Really bring out what you’ve learned over the past years about PS parameter passing.
Do this and you’ll get people to not only saying ‘Gee, I didn’t know PS could do that’, or ‘oh – that’s what they really mean, now I get it’, but have them comng back time and time again, as sound references of working complex examples of how to chain Cmdlets (and Functions) together.
PowerShell addresses a considerable amount of ground and there is more than enough left for the network admin to assume in this area that will leave them still puzzled and stuck in the middle of building a task, if a working end can’t be within sight and explained.
Regards, good luck and keep writing!
-dpc-