当一个调用只返回一个对象时,如何强制Powershell返回一个数组呢?

Dyl*_*tie 105 powershell

我正在使用Powershell在Web服务器上设置IIS绑定,并且遇到以下代码的问题:

$serverIps = gwmi Win32_NetworkAdapterConfiguration 
    | Where { $_.IPAddress } 
    | Select -Expand IPAddress 
    | Where { $_ -like '*.*.*.*' } 
    | Sort

if ($serverIps.length -le 1) {
    Write-Host "You need at least 2 IP addresses for this to work!"
    exit
}

$primaryIp = $serverIps[0]
$secondaryIp = $serverIps[1]
Run Code Online (Sandbox Code Playgroud)

如果服务器上有2个以上的IP,那么很好 - Powershell返回一个数组,我可以查询数组长度并提取第一个和第二个地址就好了.

问题是 - 如果只有一个IP,Powershell不返回单元素数组,它返回IP地址(作为字符串,如"192.168.0.100") - 字符串有一个.length属性,它大于1,所以测试通过,我最后得到字符串中的前两个字符,而不是集合中的前两个IP地址.

如何强制Powershell返回单元素集合,或者确定返回的"thing"是对象而不是集合?

JNK*_*JNK 123

使用以下两种方式之一将变量定义为数组...

用一个@开头的括号中的管道命令包装:

$serverIps = @(gwmi Win32_NetworkAdapterConfiguration 
    | Where { $_.IPAddress } 
    | Select -Expand IPAddress 
    | Where { $_ -like '*.*.*.*' } 
    | Sort)
Run Code Online (Sandbox Code Playgroud)

将变量的数据类型指定为数组:

[array]$serverIps = gwmi Win32_NetworkAdapterConfiguration 
    | Where { $_.IPAddress } 
    | Select -Expand IPAddress 
    | Where { $_ -like '*.*.*.*' } 
    | Sort
Run Code Online (Sandbox Code Playgroud)

或者,检查变量的数据类型......

IF ($ServerIps -isnot [array])
{ <error message> }
ELSE
{ <proceed> }
Run Code Online (Sandbox Code Playgroud)

  • 在`@(...)`中包装命令将返回一个数组,即使零对象也是如此.而如果没有对象,将结果赋值给`[Array]`-typed变量仍将返回$ null. (22认同)
  • 有趣的是你如何最终回到同样的问题。我有(并且再次有)一个稍微不同的问题,是的,因为在问题中这很好用,但是当从函数返回时,这是一个不同的故事。如果有一个元素,则忽略该数组并仅返回该元素。如果你在变量前加一个逗号,它会强制它变成一个数组,但一个多元素数组将返回一个二维数组。很乏味。 (3认同)
  • Gah,这也是上次发生的事情,现在我无法复制它。无论如何,我通过使用 `Return ,$out` 解决了我最近的问题,这似乎总是有效。如果我再次遇到这个问题,我会发布一个例子。 (3认同)
  • 请注意,如果返回的对象是 PSObject(可能是其他对象),则这些解决方案都不起作用。 (2认同)
  • @ Deadly-Bagel可以举个例子吗?对我来说,@@ ...对于任何类型的对象都可以正常工作(产生预期会产生的结果)。 (2认同)

Luc*_*bug 19

,您可以在返回列表之前添加逗号( ),例如return ,$list或将其强制转换[Array][YourType[]]在您倾向于使用列表的位置。


Sha*_*evy 11

将结果强制为数组,以便您可以拥有Count属性.单个对象(标量)没有Count属性.字符串具有length属性,因此您可能会得到错误的结果,使用Count属性:

if (@($serverIps).Count -le 1)...
Run Code Online (Sandbox Code Playgroud)

顺便说一句,使用-as运算符,而不是使用也可以匹配字符串的通配符:

[array]$serverIps = gwmi Win32_NetworkAdapterConfiguration -filter "IPEnabled=TRUE" | Select-Object -ExpandProperty IPAddress | Where-Object {($_ -as [ipaddress]).AddressFamily -eq 'InterNetwork'}
Run Code Online (Sandbox Code Playgroud)


小智 5

如果您提前将变量声明为数组,则可以向其中添加元素 - 即使它只是一个...

这应该工作......

$serverIps = @()

gwmi Win32_NetworkAdapterConfiguration 
    | Where { $_.IPAddress } 
    | Select -Expand IPAddress 
    | Where { $_ -like '*.*.*.*' } 
    | Sort | ForEach-Object{$serverIps += $_}
Run Code Online (Sandbox Code Playgroud)