我正在编写PowerShell代码来获取所有本地IPv4地址,不包括环回地址。我需要类似LINQ SelectMany方法的东西,但我无法弄清楚如何用PS滤镜做到这一点。这是我到目前为止的代码,它使用一个普通的旧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
}
我想知道是否有更简洁的方法,只需更少的代码。
答案 0 :(得分:21)
如果您将Foreach-Object
和Where-Object
组合在一起,就可以这样做:
$ipaddresses = @(
Get-WmiObject Win32_NetworkAdapterConfiguration |
? { $_.IPAddress -ne $null } |
% { $_.IPAddress } |
? { $_ -notlike "127.*" -and $_ -notlike "*::*" })
请注意@(...)
。这导致如果内部管道的结果是 nothing ,则将空数组分配给$ipaddresses
。
答案 1 :(得分:15)
只是回答这个问题 “PowerShell相当于LINQ SelectMany方法”:
collection.SelectMany(el => el.GetChildren()) // SelectMany in C#
相当于
$collection | % { $_ } # SelectMany in PowerShell for array of arrays
$collection | % { $_.GetChildren() } # SelectMany in PowerShell for complex object
实施例
$a = (1,2,3),('X','F'),'u','y'
$a.Length # output is 4
($a | % { $_ }).Length # output is 7
另一个例子
$dirs = dir -dir c:
$childFiles = $dirs | % { $_.GetFiles() }
$dirs.Length # output is 6
$childFiles.Length # output is 119
答案 2 :(得分:8)
我还要提到,SelectMany的PowerShell等价物是Select-Object -ExpandProperty <property name of a collection>
。但是,对于此示例,这不能很好地工作,因为属性IPAddress
是一个字符串数组。将字符串产品数组展平为具有附加其他属性的单个字符串,例如:
Get-WmiObject Win32_NetworkAdapterConfiguration | Where {$_.IPAddress} |
Select Description -Expand IPAddress
不幸的是,PowerShell专门处理System.String
个对象,因此除了字符串的值(本例中为IPAddress)之外,它不希望显示任何内容。让它也显示其他属性(本例中的描述)是不实际的(可能吗?)AFAICT。
答案 3 :(得分:-1)
迟到总比没有好。 我来到了下一个方法(代码是PowerShell 2.0和PowerShell 3.0的混合):
if(-not (test-path variable:psversiontable)){return}
rv -ea silentlycontinue -force *
cls
$major=$psversiontable.psversion.major
$linqenum=[linq.enumerable]
'min:'+$linqenum::min([int[]](170..180))
'max:'+$linqenum::max($linqenum::range(170,170))
$membertypes=[reflection.membertypes]
$bindflags=[reflection.bindingflags]
[reflection.membertypes]$type=$membertypes::method
[reflection.bindingflags]$attr=$bindflags::public,$bindflags::static
$name='Min'
$methods=$linqenum.getmember($name,$type,$attr)|?{$_.isgenericmethod}
$method=$methods[0]
$closed=$method.makegenericmethod((,[int]))
"$name`:"+$closed.Invoke($null,(,[int[]](170..180)))
$name='Max'
$methods=$linqenum.getmember($name,$type,$attr)|?{$_.isgenericmethod}
$method=$methods[0]
$closed=$method.makegenericmethod((,[int]))
"$name`:"+$closed.Invoke($null,(,$linqenum::range(170,170)))
$name='SelectMany'
$methods=$linqenum.getmember($name,$type,$attr)|?{$_.isgenericmethod}
$method=$methods[0]
#$params=[hashtable],[string]
#$closed=$method.makegenericmethod($params)
$closed=$method.makegenericmethod(([hashtable],[string]))
[hashtable[]]$owners=@{name="Sidney";pets=("Scruffy","Sam")},
@{name="Ronen";pets=("Walker","Sugar")},
@{name="Hines";pets=(,"Dusty")},
@{name="Vernette";pets=("Scratches","Diesel")}
if($major -eq 2){
$delegate=[func[hashtable,collections.generic.ienumerable[string]]]
$sb={param([hashtable]$owner) ,[string[]]$owner.pets}
}else{
$delegate=[func[hashtable,string[]]]
$sb={param($owner) $owner.pets}
}
$selector=$sb -as $delegate
$params=$owners,$selector
$pets=$closed.Invoke($null,$params)
"`n$name`n$('-'*$name.length)"
$pets
$method=$methods[3]
$params=[hashtable],[string],[hashtable]
$closed=$method.makegenericmethod($params)
$resultsb={param($owner,$pet)@{owner=$owner.name;pet=$pet}}
#$resultdelegate=[func[hashtable,string,hashtable]]
#$result=$resultsb -as $resultdelegate
$params=$owners,$selector,[func[hashtable,string,hashtable]]$resultsb
$ownerpet=$closed.Invoke($null,$params)
$ownerpet|select values|ft -auto
if($major -gt 2){
$linqenum::selectmany(
$owners,
[func[hashtable,string[]]]`
{param($owner) $owner.pets},
[func[hashtable,string,hashtable]]`
{param($owner,$pet)@{owner=$owner.name;pet=$pet}}
)|select values|ft -auto
$linqenum::selectmany(
[int[]](1..4),
[func[int,int[]]]`
{param($left) 11..(11+$left-1)},
[func[int,int,hashtable]]`
{param($left,$right)@{left=$left;right=$right}}
)|select values|ft -auto
$linqenum::selectmany(
$linqenum::range(1,4),
[func[int,int[]]]`
{param($left) $linqenum::range(11,$left)},
[func[int,int,hashtable]]`
{param($left,$right)@{left=$left;right=$right}}
)|select values|ft -auto
$name='Join'
[hashtable[]]$person=@{id=1;name='ivan'},@{id=2;name='vasilij'},@{id=3;name='pjotr'}
[hashtable[]]$job=@{id=1;job='tokar'},@{id=1;job='pekar'},
@{id=2;job='doctor'},
@{id=3;job='soldat'},@{id=3;job='milicioner'},@{id=3;job='jurist'}
"`n$name`n$('-'*$name.length)"
[linq.enumerable]::join(
$person,$job,
[func[hashtable,int]]{param($p) $p.id},
[func[hashtable,int]]{param($p) $p.id},
[func[hashtable,hashtable,hashtable]]`
{param($p,$j) @{name=$p.name;job=$j.job}}
)|select values|ft -auto
}