Estoy usando Powershell para configurar enlaces IIS en un servidor web y tengo un problema con el siguiente código:
$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]
Si hay más de 2 direcciones IP en el servidor, está bien: Powershell devuelve una matriz y puedo consultar la longitud de la matriz y extraer la primera y la segunda direcciones sin problemas.
El problema es que, si solo hay una IP, Powershell no devuelve una matriz de un elemento, devuelve la dirección IP (como una cadena, como "192.168.0.100"), la cadena tiene una .length
propiedad, es mayor que 1, entonces la prueba pasa y termino con los dos primeros caracteres de la cadena, en lugar de las dos primeras direcciones IP de la colección.
¿Cómo puedo forzar a Powershell a que devuelva una colección de un elemento o, alternativamente, determinar si la "cosa" devuelta es un objeto en lugar de una colección?
fuente
Respuestas:
Defina la variable como una matriz de una de estas dos formas ...
Envuelva sus comandos canalizados entre paréntesis con un
@
al principio:Especifique el tipo de datos de la variable como una matriz:
O verifique el tipo de datos de la variable ...
fuente
@(...)
se devolverá una matriz incluso si no hay objetos. Mientras que la asignación del resultado a una[Array]
variable con tipo todavía devolverá $ null si hay cero objetos.@(...)
funciona correctamente (produce el resultado que espero que produzca) para cualquier tipo de objeto.Return ,$out
que parece funcionar siempre. Si vuelvo a encontrar el problema, publicaré un ejemplo.Forzar el resultado a una matriz para que pueda tener una propiedad Count. Los objetos individuales (escalares) no tienen una propiedad Count. Las cadenas tienen una propiedad de longitud, por lo que puede obtener resultados falsos, use la propiedad Count:
Por cierto, en lugar de usar un comodín que también puede coincidir con cadenas, use el operador -as:
fuente
-is
?Si declara la variable como una matriz antes de tiempo, puede agregarle elementos, incluso si es solo uno ...
Esto debería funcionar...
fuente
Puede usar
Measure-Object
para obtener el recuento real de objetos, sin recurrir a laCount
propiedad de un objeto .fuente
Puede agregar una coma (
,
) antes de devolver la lista comoreturn ,$list
o enviarla[Array]
o[YourType[]]
en el lugar donde tiende a usar la lista.fuente
Tuve este problema al pasar una matriz a una plantilla de implementación de Azure. Si había un objeto, PowerShell lo "convertía" en una cadena. En el ejemplo siguiente,
$a
se devuelve desde una función que hace que la VM se objete según el valor de una etiqueta. Paso el$a
alNew-AzureRmResourceGroupDeployment
cmdlet envolviéndolo@()
. Al igual que:VMObject
es uno de los parámetros de la plantilla.Puede que no sea la forma más técnica / sólida de hacerlo, pero es suficiente para Azure.
Actualizar
Bueno, lo anterior funcionó. Probé todo lo anterior y algunos, pero la única forma en que logré pasar
$vmObject
como una matriz, compatible con la plantilla de implementación, con un elemento es la siguiente (espero que MS haya estado reproduciendo nuevamente (esto fue un informe y arreglado error en 2015)):$vmObjects
es el resultado de Get-AzureRmVM.paso
$DeserializedJson
al parámetro de la plantilla de implementación (de tipo matriz).Como referencia, el encantador error
New-AzureRmResourceGroupDeployment
arroja esfuente
Regrese como un objeto referenciado, por lo que nunca se convirtió al pasar.
fuente