2016-08-12 1 views
0

Je travaille sur un script qui effectue un appel API et renvoie un résultat JSON et est géré comme un tableau d'objets personnalisés dans Powershell. L'une des propriétés de l'objet personnalisé est Statut, donc pour chaque statut unique, je voulais obtenir le compte de l'objet avec ce statut. J'ai été surpris quand mon code pour certains statuts retournerait un nombre de 0 parce que s'il n'existait pas pour commencer, mon script ne chercherait pas ce statut.Where-Object ne trouve pas une seule instance d'un objet personnalisé mais en trouve plusieurs instances. Bug possible?

J'ai alors remarqué que le code fonctionnait quand il y a plus d'un objet avec l'état mais quand il y a seulement un objet avec cet état, mon code ne le trouverait pas avec Where-Object. Si je parcours le tableau d'objets personnalisés, et que je fais une déclaration if(), il trouve tous les statuts, y compris ceux qui n'ont qu'un seul objet.

Ai-je raté quelque chose ici ou est-ce un bug? Mon portable fonctionne sous PS 5.1 et je l'ai également essayé sur un serveur W2K12 sous PS 4.0 et j'ai la même chose.

J'ai aussi été en mesure de simuler ce (suppression de l'API et les parties JSON) dans le code ci-dessous:

$testArray = @() 
$testObject = New-Object -TypeName PSObject 
$testObject | Add-Member -type NoteProperty -name Name -value 'Name1' -Force 
$testObject | Add-Member -type NoteProperty -name Status -value 'Status1' -Force 
$testArray += $testObject 
$testObject = New-Object -TypeName PSObject 
$testObject | Add-Member -type NoteProperty -name Name -value 'Name2' -Force 
$testObject | Add-Member -type NoteProperty -name Status -value 'Status2' -Force 
$testArray += $testObject 
$testObject = New-Object -TypeName PSObject 
$testObject | Add-Member -type NoteProperty -name Name -value 'Name3' -Force 
$testObject | Add-Member -type NoteProperty -name Status -value 'Status3' -Force 
$testArray += $testObject 

$testObject = New-Object -TypeName PSObject 
$testObject | Add-Member -type NoteProperty -name Name -value 'Name4' -Force 
$testObject | Add-Member -type NoteProperty -name Status -value 'Status1' -Force 
$testArray += $testObject 
$testObject = New-Object -TypeName PSObject 
$testObject | Add-Member -type NoteProperty -name Name -value 'Name5' -Force 
$testObject | Add-Member -type NoteProperty -name Status -value 'Status1' -Force 
$testArray += $testObject 
$testObject = New-Object -TypeName PSObject 
$testObject | Add-Member -type NoteProperty -name Name -value 'Name6' -Force 
$testObject | Add-Member -type NoteProperty -name Status -value 'Status1' -Force 
$testArray += $testObject 

$testObject = New-Object -TypeName PSObject 
$testObject | Add-Member -type NoteProperty -name Name -value 'Name7' -Force 
$testObject | Add-Member -type NoteProperty -name Status -value 'Status3' -Force 
$testArray += $testObject 
$testObject = New-Object -TypeName PSObject 
$testObject | Add-Member -type NoteProperty -name Name -value 'Name8' -Force 
$testObject | Add-Member -type NoteProperty -name Status -value 'Status3' -Force 
$testArray += $testObject 
$testObject = New-Object -TypeName PSObject 
$testObject | Add-Member -type NoteProperty -name Name -value 'Name9' -Force 
$testObject | Add-Member -type NoteProperty -name Status -value 'Status3' -Force 
$testArray += $testObject 

$testObject = New-Object -TypeName PSObject 
$testObject | Add-Member -type NoteProperty -name Name -value 'Name10' -Force 
$testObject | Add-Member -type NoteProperty -name Status -value 'Status1' -Force 
$testArray += $testObject 

$testObject = New-Object -TypeName PSObject 
$testObject | Add-Member -type NoteProperty -name Name -value 'Name11' -Force 
$testObject | Add-Member -type NoteProperty -name Status -value 'Status1' -Force 
$testArray += $testObject 
$testObject = New-Object -TypeName PSObject 
$testObject | Add-Member -type NoteProperty -name Name -value 'Name12' -Force 
$testObject | Add-Member -type NoteProperty -name Status -value 'Status1' -Force 
$testArray += $testObject 
$testObject = New-Object -TypeName PSObject 
$testObject | Add-Member -type NoteProperty -name Name -value 'Name13' -Force 
$testObject | Add-Member -type NoteProperty -name Status -value 'Status1' -Force 
$testArray += $testObject 

$testObject = New-Object -TypeName PSObject 
$testObject | Add-Member -type NoteProperty -name Name -value 'Name14' -Force 
$testObject | Add-Member -type NoteProperty -name Status -value 'Status3' -Force 
$testArray += $testObject 
$testObject = New-Object -TypeName PSObject 
$testObject | Add-Member -type NoteProperty -name Name -value 'Name15' -Force 
$testObject | Add-Member -type NoteProperty -name Status -value 'Status3' -Force 
$testArray += $testObject 
$testObject = New-Object -TypeName PSObject 
$testObject | Add-Member -type NoteProperty -name Name -value 'Name16' -Force 
$testObject | Add-Member -type NoteProperty -name Status -value 'Status3' -Force 
$testArray += $testObject 


Write-Host "`n`nPowerShell version:" 
$PSVersionTable.PSVersion 


Write-Host "`n`nUsing Where-Object on the array" 
$uniqueStatuses = ($testArray.Status | sort | Get-Unique) 
foreach ($status in $uniqueStatuses) 
{ 
    $status 
    ($testArray | Select-Object | Where-Object { $_.Status -eq $status }).Count 

} 


Write-Host "`n`nLooping through the array" 
foreach ($status in $uniqueStatuses) 
{ 
    $status 
    [int]$count = 0 
    foreach ($object in $testArray) 
    { 
     if ($object.Status -eq $status) 
     { 
      $count++ 
     } 
    } 
    $count 
} 

Dans le code exemple ci-dessus, l'état Status2 apparaît uniquement dans l'un des objets personnalisés et Where-Object ne le trouve pas pour une raison quelconque mais en utilisant foreach.

Quand je lance le code ci-dessus, je reçois:

Version PowerShell:

Major Minor Créer Révision


Utilisation de Where-Object sur le tableau

Status1

Status2

status3

en boucle à travers le réseau

Status1

Status2

status3

Répondre

4

Dans le premier exemple (en utilisant Where-Object), il n'y a aucune garantie que les résultats de pipeline dans une collection - avec Status2 il retourne seulement objet unique, ce qui explique pourquoi Count ne renvoie rien.

Utilisez l'opérateur sous-expression de tableau @() et vous verrez le nombre correct:

$uniqueStatuses = ($testArray.Status | sort | Get-Unique) 
foreach ($status in $uniqueStatuses) 
{ 
    $status 
    @($testArray | Select-Object | Where-Object { $_.Status -eq $status }).Count 

} 
+0

Un peu mal, cependant, étant donné que * implicitement * chaque objet obtient une propriété Count ajouté lors de l'accès et il retourne 1, par exemple ''1'.count' (depuis PSv3 ou plus). Apparemment, cela ne tient pas dans tous les cas. Dans ce cas, je vais probablement réécrire le code en groupe par statut, ce qui vous donne aussi le nombre, je suppose. – Joey

+0

Marqué ceci comme réponse. Merci pour l'explication claire! – Rim