我正在使用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]
如果服务器上有2个以上的IP,那就好了-- PowerShell返回一个数组,我可以查询数组长度并提取第一个和第二个地址。
问题是-如果只有一个IP,PowerShell不会返回一个单元素数组,它返回IP地址(作为字符串,如“192.168.0.100”)-字符串具有.length
属性,它大于1,因此测试通过,我最终得到字符串中的前两个字符,而不是集合中的前两个IP地址。
如何强制Powershell返回一个单元素集合,或者确定返回的“事物”是否是对象而不是集合?
9条答案
按热度按时间gxwragnw1#
通过以下两种方式之一将变量定义为数组...
将管道命令用括号括起来,并在开头加上
@
:将变量的数据类型指定为数组:
或者,检查变量的数据类型...
e5nqia272#
将结果强制为Array,以便您可以拥有Count属性。单个对象(标量)没有“计数”特性。字符串有一个length属性,所以你可能会得到错误的结果,使用Count属性:
顺便说一下,不要使用也可以匹配字符串的通配符,而是使用-as运算符:
2ledvvac3#
你可以在return list前加上一个逗号(
,
),比如return ,$list
,或者在你倾向于使用列表的地方将其转换为[Array]
或[YourType[]]
。iugsix8n4#
如果你提前将变量声明为一个数组,你可以向它添加元素--即使它只是一个数组。
这应该可以。。
bxpogfeg5#
您可以使用
Measure-Object
来获取实际的对象计数,而无需求助于对象的Count
属性。11dmarpk6#
我在向Azure部署模板传递数组时遇到此问题。如果有一个对象,PowerShell会将其“转换”为字符串。在下面的示例中,
$a
是从一个函数返回的,该函数根据标记的值获取VM对象。我通过将$a
Package 在@()
中将其传递给New-AzureRmResourceGroupDeployment
cmdlet。就像这样:VMObject
是模板的参数之一。可能不是最技术/最健壮的方法,但对于Azure来说已经足够了。
更新
上面的工作。我已经尝试了以上所有方法和一些方法,但我设法将
$vmObject
作为一个数组传递的唯一方法,与部署模板兼容,其中一个元素如下(我希望MS再次播放(这是2015年的报告和修复的错误)):$vmObjects
是Get-AzureRmVM的输出。我将
$DeserializedJson
传递给部署模板的参数(类型为array)。作为参考,
New-AzureRmResourceGroupDeployment
抛出的可爱错误是swvgeqrz7#
作为被引用对象返回,因此在传递时从不进行转换。
bq8i3lrv8#
有一种方法可以处理你的情况。让大部分代码保持原样,只需更改处理
$serverIps
对象的方式。这段代码可以处理$null
,只有一个项目,和许多项目。在PowerShell Core中,每个对象都有一个
.Count
属性。在Windows PowerShell中,“几乎”每个对象都有一个.Count
属性。kd3sttzy9#
以下是在PowerShell中使用流水线与数组时发生的情况。
举个例子:
结果将简单地是:
首先,上面的代码看起来很傻,但是,假设你查询了一些数据,结果是一个单元素数组,其元素可能由空格组成,也可能是
$null
,你想确保值折叠为''
,因此是"$_".Trim()
。好了,这样一来,生成的JSON可能不是人们所期望的来自其他编程语言(如C#)的JSON。正如其他答案所描述的那样,由于该表达式流经管道,因此适用与其他答案所描述的相同的规则,并且结果对象是“未 Package 的”。
通常,函数实现流水线如下:
要使用上述内容:
在这样的函数中,使用管道,值被 * 串行 * 处理。
$Stuff
中的每个值都通过管道传递到函数中。如果函数有一个Begin
块,在处理通过管道传入的参数的任何值之前运行一次,即在Begin
块中可获得其它非管线化参数值。然后,Process
块对每个流水线输入的值执行 * 一次 *。最后,如果函数有一个End
块,则在处理完所有输入的值后,在最后运行。那么,为什么要在
Process
块中使用foreach
语句呢?当函数被这样调用时处理:在这个调用中,
$Stuff
的整个数组通过参数传递给函数。因此,为了正确处理数据,在Process
块中使用foreach
循环。现在,这应该为您提供了所需的信息,以了解如何规避我第一个示例中的问题。为了使该示例正确运行,需要按以下方式执行:这将导致预期的JSON:
有了这些知识,要修复代码以使其按预期工作,您应该执行以下操作:
希望这有助于澄清问题。