Estou usando o Powershell para configurar ligações do IIS em um servidor web e tendo um problema com o seguinte 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]
Se houver mais de 2 IPs no servidor, tudo bem - o Powershell retorna uma matriz, e eu posso consultar o comprimento da matriz e extrair o primeiro e o segundo endereços.
O problema é - se houver apenas um IP, o Powershell não retornará uma matriz de um elemento, ele retornará o endereço IP (como uma string, como "192.168.0.100") - a string possui uma .length
propriedade, é maior que 1, portanto o teste passa e acabo com os dois primeiros caracteres da sequência, em vez dos dois primeiros endereços IP da coleção.
Como forçar o Powershell a retornar uma coleção de um elemento ou, alternativamente, determinar se a "coisa" retornada é um objeto e não uma coleção?
fonte
Respostas:
Defina a variável como uma matriz de uma das duas maneiras ...
Coloque seus comandos canalizados entre parênteses com um
@
no início:Especifique o tipo de dados da variável como uma matriz:
Ou verifique o tipo de dados da variável ...
fonte
@(...)
retornará uma matriz mesmo se houver zero objeto. Enquanto a atribuição do resultado a uma[Array]
variável de tipo ainda retornará $ null se houver zero objeto.@(...)
trabalho corretamente (produza o resultado que espero que produza) para qualquer tipo de objeto.Return ,$out
que parece sempre funcionar. Se eu encontrar o problema novamente, postarei um exemplo.Force o resultado a uma matriz para que você possa ter uma propriedade Count. Objetos únicos (escalares) não têm uma propriedade Count. As strings têm uma propriedade length, para que você possa obter resultados falsos, use a propriedade Count:
A propósito, em vez de usar um curinga que também pode corresponder a cadeias, use o operador -as:
fonte
-is
?Se você declarar a variável como uma matriz antes do tempo, poderá adicionar elementos a ela - mesmo que seja apenas uma ...
Isso deve funcionar ...
fonte
Você pode usar
Measure-Object
para obter a contagem real de objetos, sem recorrer àCount
propriedade de um objeto .fonte
Você pode adicionar uma vírgula (
,
) antes de retornar a lista comoreturn ,$list
ou convertê-la[Array]
ou[YourType[]]
em onde você costuma usar a lista.fonte
Eu tive esse problema ao passar uma matriz para um modelo de implantação do Azure. Se houvesse um objeto, o PowerShell o "converteria" em uma sequência. No exemplo abaixo,
$a
é retornado de uma função que obtém objeção de VM de acordo com o valor de uma tag. Eu passo o$a
para oNew-AzureRmResourceGroupDeployment
cmdlet envolvendo-o@()
. Igual a:VMObject
é um dos parâmetros do modelo.Pode não ser a maneira mais técnica / robusta de fazer isso, mas é suficiente para o Azure.
Atualizar
Bem, o acima funcionou. Eu tentei tudo o que precede e alguns, mas a única maneira de conseguir passar
$vmObject
como uma matriz, compatível com o modelo de implantação, com um elemento é o seguinte (espero que a Microsoft esteja reproduzindo novamente (este foi um relatório e foi corrigido bug em 2015)):$vmObjects
é a saída do Get-AzureRmVM.Eu passo
$DeserializedJson
para o parâmetro do modelo de implantação (do tipo array).Para referência, o adorável erro
New-AzureRmResourceGroupDeployment
éfonte
Retorne como um objeto referenciado, para que nunca seja convertido ao passar.
fonte