200 votes

Comment forcer Powershell à renvoyer un tableau lorsqu'un appel ne renvoie qu'un seul objet ?

J'utilise Powershell pour configurer les liaisons IIS sur un serveur web, et j'ai un problème avec le code suivant :

$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]

S'il y a plus de 2 IP sur le serveur, très bien - Powershell renvoie un tableau, et je peux interroger la longueur du tableau et extraire les première et deuxième adresses sans problème.

Le problème est que s'il n'y a qu'une seule adresse IP, Powershell ne renvoie pas un tableau à un élément, mais l'adresse IP (sous forme de chaîne, comme "192.168.0.100"). .length le résultat est supérieur à 1. Le test passe donc, et je me retrouve avec les deux premiers caractères de la chaîne, au lieu des deux premières adresses IP de la collection.

Comment puis-je forcer Powershell à renvoyer une collection à un seul élément ou déterminer si la "chose" renvoyée est un objet plutôt qu'une collection ?

224voto

JNK Points 32743

Définissez la variable comme un tableau de l'une des deux façons suivantes...

Mettez vos commandes pipées entre parenthèses avec un @ au début :

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

Spécifiez le type de données de la variable en tant que tableau :

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

Ou bien, vérifiez le type de données de la variable...

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

21voto

Luckybug Points 26

Vous pouvez soit ajouter une virgule ( , ) avant la liste de retour comme return ,$list ou le lancer [Array] o [YourType[]] à l'endroit où vous avez l'habitude d'utiliser la liste.

18voto

Shay Levy Points 41404

Forcer le résultat dans un tableau afin d'avoir une propriété Count. Les objets simples (scalaires) n'ont pas de propriété Count. Les chaînes de caractères ont une propriété "length", vous pourriez donc obtenir des résultats erronés, utilisez la propriété "Count" :

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

D'ailleurs, au lieu d'utiliser un joker qui peut également correspondre à des chaînes de caractères, utilisez l'opérateur -as :

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

10voto

Kyle Neier Points 31

Si vous déclarez la variable comme un tableau à l'avance, vous pouvez y ajouter des éléments, même s'il ne s'agit que d'un seul...

Cela devrait fonctionner...

$serverIps = @()

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

3voto

Patrick Points 128

Vous pouvez utiliser Measure-Object pour obtenir le nombre réel d'objets, sans avoir recours à la fonction Count propriété.

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

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X