'.Count' not working when array only contains 1 entry, simple arrays work

Welcome Forums General PowerShell Q&A '.Count' not working when array only contains 1 entry, simple arrays work

This topic contains 4 replies, has 4 voices, and was last updated by

js
 
Participant
1 week, 2 days ago.

  • Author
    Posts
  • #182217

    Participant
    Topics: 1
    Replies: 1
    Points: 34
    Rank: Member

    I had logic in my script to display specific messages when the array count was zero or 1.
    1 was never working so I investigated further.
    Whenever my array had a size of 1, the '.Count' value was always Null.
    I found this to be the case with arrays created by commands: Get-DistributionGroupMember, Get-AzureADGroupOwner, Get-AzureADGroupMember, and Get-MailboxPermission

    $PSSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri 'https://outlook.office365.com/PowerShell-LiveId/' -Credential XXXXXXXXXXXXXXX -Authentication Basic -AllowRedirection
    Import-PSSession $PSSession -DisableNameChecking -AllowClobber
    $DistributionList = Get-DistributionGroup | Select DisplayName, Identity | Sort DisplayName
    ForEach ($D in $DistributionList) {
    Write-Output $D.DisplayName
    $Members = Get-DistributionGroupMember -Identity $D.Identity | Select DisplayName, Id | Sort DisplayName
    Write-Output $Members.Count
    [Int]$Count = 0
    ForEach ($M in $Members) {
    $Count++
    }
    Write-Output "ForEach count: $Count"
    }
    Remove-PSSession $PSSession

    Results showing 0, 1, and 27 Members (notice there is no '.Count' displayed for 'A':

    A
    ForEach count: 1
    B
    0
    ForEach count: 0
    C
    27
    ForEach count: 27

    Oddly enough, the count works for 1 when the array is simple:

    $myArray = @()
    Write-Output $myArray.Count
    $myArray = @('A')
    Write-Output $myArray.Count
    $myArray = @('A', 'B', 'C')
    Write-Output $myArray.Count

    Results:

    0
    1
    3

    My PS Version Info
    $psversiontable
    Name Value
    —- —–
    PSVersion 5.1.18362.145
    PSEdition Desktop
    PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
    BuildVersion 10.0.18362.145
    CLRVersion 4.0.30319.42000
    WSManStackVersion 3.0
    PSRemotingProtocolVersion 2.3
    SerializationVersion 1.1.0.1

  • #182235

    Participant
    Topics: 6
    Replies: 97
    Points: 239
    Helping Hand
    Rank: Participant

    When more than 1 object is returned from the cmdlet, an array is created, as expected. When only 1 is returned, though, the variable storing the results is actually the type of object of results.

    PS /Users/cmdowning/Scripts> $arr = gci -File | ForEach-Object { $_.Name }
    PS /Users/cmdowning/Scripts> $arr.GetType()                                                                                                           
    
    IsPublic IsSerial Name                                     BaseType                                                                                  
    -------- -------- ----                                     --------                                                                                  
    True     True     String                                   System.Object 
    PS /Users/cmdowning/Scripts> $arr2 = gci -File -Path ../Downloads/ | ForEach-Object { $_.Name }
    PS /Users/cmdowning/Scripts> $arr2.gettype()                                                                                                          
    
    IsPublic IsSerial Name                                     BaseType                                                                                  
    -------- -------- ----                                     --------                                                                                  
    True     True     Object[]                                 System.Array 
    
  • #182256

    Participant
    Topics: 10
    Replies: 84
    Points: 273
    Helping Hand
    Rank: Contributor

    To elaborate on what Charles D posted, you can 'force' the output type to System.Array even if there is just one object being returned:

    $DistributionList = @(Get-DistributionGroup | Select-Object -Property DisplayName, Identity | Sort-Object -Property DisplayName)
    ...

     

    • #182346
      js

      Participant
      Topics: 25
      Replies: 692
      Points: 1,721
      Helping Hand
      Rank: Community Hero

      That's right. @() forces the result to always be an array. People often initialize an array like this:

      $a = @(1,2,3)
      

      But the @() is unnecessary in that case. The comma is an operator.

      $a = 1,2,3
      
  • #182343

    Participant
    Topics: 1
    Replies: 1
    Points: 34
    Rank: Member

    Thanks Charles D and Aaron Hardy! Useful information and will begin forcing an array when I expect an array!

You must be logged in to reply to this topic.