I'm writing PowerShell code to get all the local IPv4 addresses, excluding the loopback one. I need something like the LINQ SelectMany method, but I can't figure out how to do this with PS filters. This is the code I have so far, which works using a plain old ArrayList:
function Get-Computer-IP-Address() { $ipAddresses = New-Object System.Collections.ArrayList $networkAdaptersWithIp = Get-WmiObject Win32_NetworkAdapterConfiguration | ? { $_.IPAddress -ne $null } foreach ($networkAdapter in $networkAdaptersWithIp) { foreach ($ipAddress in $networkAdapter.IPAddress) { if ($ipAddress -notlike "127.*" -and $ipAddress -notlike "*::*") { $ipAddresses.Add($ipAddress) } } } if ($ipAddresses.Length -eq 0) { throw "Failed to find any non-loopback IPv4 addresses" } return $ipAddresses }
I'd like to know if there's a cleaner way to do it, with less code.
Just to answer the question from the subject "PowerShell equivalent of LINQ SelectMany method":
collection.SelectMany(el => el.GetChildren()) // SelectMany in C#
is equivalent to
$collection | % { $_ } # SelectMany in PowerShell for array of arrays $collection | % { $_.GetChildren() } # SelectMany in PowerShell for complex object
Example
$a = (1,2,3),('X','F'),'u','y' $a.Length # output is 4 ($a | % { $_ }).Length # output is 7
Another example
$dirs = dir -dir c: $childFiles = $dirs | % { $_.GetFiles() } $dirs.Length # output is 6 $childFiles.Length # output is 119
You can do it if you combine Foreach-Object
and Where-Object
like this:
$ipaddresses = @( Get-WmiObject Win32_NetworkAdapterConfiguration | ? { $_.IPAddress -ne $null } | % { $_.IPAddress } | ? { $_ -notlike "127.*" -and $_ -notlike "*::*" })
Note the @(...)
. This causes that if result of the pipeline inside is nothing, empty array is assigned to $ipaddresses
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With