Shell – PowerShell “.count” method causing incorrect processing

powershellpowershell-2.0

I am creating an array in PowerShell that doesn’t always contain data (sometimes it is empty). I need to verify that the array contains data before trying to do anything to the array objects. When I use the following code, everything works as expected:

$Array = @(“This”,”is”,”a”,”test”)
$Array | ForEach-Object {
If ($Array.Count -ge 1)
    {
    [string]$A = $_
    Write-Host $A
    }
}

Using the above code, I get the following output:

This
is
a
test

The above checks the .Count of the array each time it processes an object in the array (so it might check the count of the array a thousand times or more depending on the number of objects in the array). What I want to do is to check the count of the array only once and before it starts processing the array objects. However, the following code doesn’t provide the proper output:

$Array = @(“This”,”is”,”a”,”test”)
If ($Array.Count -ge 1)
{
$Array | ForEach-Object {
    {
    [string]$A = $_
    Write-Host $A
    }
}
}

I get the following output when I run the above code:

    [string]$A = $_
    Write-Host $A

    [string]$A = $_
    Write-Host $A

    [string]$A = $_
    Write-Host $A

    [string]$A = $_
    Write-Host $A

It doesn’t Write-Host the value of the $A variable like the previous code did but instead it prints out the actual PowerShell code itself. All I did was move the .Count check so that it checks the count prior to the start of processing objects in the array. Why do I get the above output when I move the array count check before the ForEach-Object statement? Do I have to check the array count each time I process an object from the array?

Thanks

Best Answer

I'm guessing the reason why Powershell prints this for your second example

[string]$A = $_
Write-Host $A

[string]$A = $_
Write-Host $A

is because Powershell takes the double brace {{}} as a string literal.

As for how to make this work, you should test the $Array before doing the for loop.

Here's what the code should look like :

$Array = @(“This”,”is”,”a”,”test”)
if($Array.Count -ge 1){
    foreach($A in $Array){
        Write-Host $A
    }
}

And as a one-liner(ish)

$Array = @(“This”,”is”,”a”,”test”) 
if($Array.Count -ge 1){ $Array| %{Write-Host $_}}
Related Question