How are the parentheses around powershell command different from others?
I am using Get-NetIPAddress. ALL I want is an actual address without ANY formatting or tables or whatever.
If i use
(Get-NetIPAddress).IPAddres
I get a list of addresses for all ports. I only want one port, so I tried to execute it but it gave nothing:
(Get-NetIPAddress).IPv4Address | Where-Object InterfaceAlias -eq "MyPortName"
But if I do this:
Get-NetIPAddress.IPv4Address | Where-Object InterfaceAlias -eq "MyPortName"
It says that this is an invalid command.
If I use this:
Get-NetIPAddress | Where-Object InterfaceAlias -eq "MyPortName" | Where-Object AddressFamily -eq IPv4 | Select-Object IPAddress
I get:
IPAddress
---------
10.45.22.100
So what happens when I put parentheses around Get-NetIPAddress and how can I JUST get the Darn worm number for a specific port?
source to share
Brackets work the same way as in math, they set the order of precedence, so the parentheses do something inside the parentheses first.
To get just the IP address value from your last command, do this instead:
(Get-NetIPAddress | Where-Object InterfaceAlias -eq "MyPortName" | Where-Object AddressFamily -eq IPv4).IPAddress
This command:
(Get-NetIPAddress).IPv4Address
Returns the value of a property IPv4Address
(possibly as a string), so this command doesn't work:
(Get-NetIPAddress).IPv4Address | Where-Object InterfaceAlias -eq "MyPortName"
As you pass a string object containing the IP address to the cmdlet Where-Object
and then try to filter for a property InterfaceAlias
that does not exist in that object.
When you access a property through a note .
, you get its value. When you access a property using a cmdlet Select-Object
, you return an object (of the same type as the original object) that is filtered to that single property alone (unless you use a switch -ExpandProperty
that calls Select-Object
to return the value of a specific property instead of an object as well as using the notation .
).
In short, do whatever filtering you need to do first and then access the properties / properties you want to end up with last.
source to share
By attaching command c ()
, you create a priority order so everything inside ()
is done first and then your other commands are evaluated.
also there is no construct like cmdlet.property
as for the second part, after you do (Get-NetIPAddress).IPv4Address
you probably end up with another object, just compare the output with:
Get-NetIPAddress | Get-Member
and
(Get-NetIPAddress).IPv4Address | Get-Member
source to share
Get-NetIpAddress
is a cmdlet, PowerShell runs it. It outputs one or more objects and I mean one many names, numbers and functions grouped into one block.
Get-NetIpAddress | Select-Object IPv4Address
takes an object and turns it into simpler, smaller objects with one property, IPv4Address.
What is it:
IPAddress
---------
10.45.22.100
it is rendering an object with one property.
Get-NetIpAddress | Select-Object -ExpandProperty IPv4Address
takes objects, takes only IPv4Address and strips off the grouping and leaves only IPv4Address as a string.
This will output:
10.45.22.100
10.45.22.101
They have been expanded to rows, no column header. They were deployed.
This is what you want to do a lot, but it prints a lot. $x = Get-NetIpAddress; $x.IPv4Address
is a quick way to get just the Ipv4Address unwrapped from the object and nothing else.
So you want to do
Get-NetIpAddress.IPv4Address
but it crashes because it looks like the name of another cmdlet and PowerShell tries to run it and can't. This is just a syntax clash - it could be a name, it could be a property lookup, and powershell chooses differently. you need something (parens) to make the distinction.
(Get-NetIpAddress).IPv4Address
makes it clear to the shell that there is a cmdlet, it runs that, then gets the result in parentheses, and then gets the property from them. This clears the collision name. But at this point, you've thrown away the interface name, so pushing that pin to the pipeline doesn't allow you to select based on the interface name.
Follow this and you can see
- If you do
(Get-NetIpAddress).IPv4Address
, the output is a string and you've selected all other data that came out of the cmdlet. - If you want to select one line based on the interface name, you must do so before expanding the IP address and ditching the interface name.
So,
Get-NetIpAddress |
Where-Object { pick the one I want } |
Select-Object -ExpandProperty 'the thing I want'
source to share
Using this syntax you provided:
Get-NetIPAddress | Where-Object InterfaceAlias -eq "MyPortName" | Where-Object AddressFamily -eq IPv4 | Select-Object IPAddress
... obtaining only the IP address (no object designation) can be done in two ways:
Get-NetIPAddress | Where-Object InterfaceAlias -eq "MyPortName" | Where-Object AddressFamily -eq IPv4 | Select-Object -Expand IPAddress
notice the "ExpandProperty" argument, short for "Expand" in the above line ... or:
(Get-NetIPAddress | Where-Object InterfaceAlias -eq "MyPortName" | Where-Object AddressFamily -eq IPv4 | Select-Object IPAddress).IPAddress
... where we return an object and then refer to the IPAddress property on the object.
source to share