usar tutorial script como commands comandos powershell

script - powershell tutorial



¿Cómo puedo forzar a Powershell a devolver una matriz cuando una llamada solo devuelve un objeto? (4)

Fuerza el resultado a una matriz para que puedas tener una propiedad Count. Los objetos individuales (escalares) no tienen una propiedad de Cuenta. Las cadenas tienen una propiedad de longitud para que pueda obtener resultados falsos, use la propiedad Count:

if (@($serverIps).Count -le 1)...

Por cierto, en lugar de usar un comodín que también puede coincidir con cadenas, use el operador -as:

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

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, bien: Powershell devuelve una matriz y puedo consultar la longitud de la matriz y extraer la primera y la segunda direcciones.

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 propiedad .length , es mayor que 1 , por lo que la prueba pasa, y termino con los dos primeros caracteres en la cadena, en lugar de las dos primeras direcciones IP en la colección.

¿Cómo puedo forzar a Powershell a devolver una colección de un elemento o, alternativamente, determinar si la "cosa" devuelta es un objeto en lugar de una colección?


Si declara la variable como una matriz antes de tiempo, puede agregarle elementos, incluso si es solo uno ...

Esto debería funcionar...

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


Tuve este problema pasando una matriz a una plantilla de implementación de Azure. Si había un objeto, PowerShell lo "convirtió" en una cadena. En el siguiente ejemplo, se devuelve $a desde una función que objeta la VM según el valor de una etiqueta. Paso el $a a al cmdlet New-AzureRmResourceGroupDeployment envolviéndolo en @() . Al igual que:

$TemplateParameterObject=@{ VMObject=@($a) } New-AzureRmResourceGroupDeployment -ResourceGroupName $RG -Name "TestVmByRole" -Mode Incremental -DeploymentDebugLogLevel All -TemplateFile $templatePath -TemplateParameterObject $TemplateParameterObject -verbose

VMObject es uno de los parámetros de la plantilla.

Puede que no sea la forma más técnica / robusta de hacerlo, pero es suficiente para Azure.

Actualizar

Bueno, lo anterior funcionó. He intentado todo lo anterior y algunos, pero la única forma en que he logrado pasar $vmObject como una matriz, compatible con la plantilla de implementación, con un elemento es la siguiente (espero que MS haya estado jugando de nuevo (este era un informe) y error solucionado en 2015)):

[void][System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions") foreach($vmObject in $vmObjects) { #$vmTemplateObject = $vmObject $asJson = (ConvertTo-Json -InputObject $vmObject -Depth 10 -Verbose) #-replace ''/s'','''' $DeserializedJson = (New-Object -TypeName System.Web.Script.Serialization.JavaScriptSerializer -Property @{MaxJsonLength=67108864}).DeserializeObject($asJson) }

$vmObjects es el resultado de Get-AzureRmVM.

Paso $DeserializedJson al parámetro ''plantilla de despliegue'' (de tipo array).

Como referencia, el encantador error que arroja New-AzureRmResourceGroupDeployment es

"The template output ''{output_name}'' is not valid: The language expression property ''Microsoft.WindowsAzure.ResourceStack.Frontdoor.Expression.Expressions.JTokenExpression'' can''t be evaluated.."


Defina la variable como una matriz en una de dos formas ...

Ajustar sus comandos canalizados entre paréntesis con un @ al comienzo:

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

Especifique el tipo de datos de la variable como una matriz:

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

O bien, verifique el tipo de datos de la variable ...

IF ($ServerIps -isnot [array]) { <error message> } ELSE { <proceed> }