Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a better way to check if a collection is empty before a foreach in PowerShell?

I have part of a deploy PowerShell 2.0 script that copy a potential robots.dev.txt to robots.txt, if it doesn't exist don't do anything.

My original code was:

$RobotFilesToOverWrite= Get-ChildItem -Path $tempExtractionDirectory -Recurse -Include "robots.$Environment.txt"
    foreach($file in $RobotFilesToOverWrite)
    {
        $origin=$file
        $destination=$file -replace ".$Environment.","."

        #Copy-Item $origin $destination
    }

But, in a difference with C#, even if $RobotFilesToOverWrite is null, code is entering in the foreach.

So I had to surround everything with:

if($RobotFilesToOverWrite)
{
    ...
}

This is the final code:

$RobotFilesToOverWrite= Get-ChildItem -Path $tempExtractionDirectory -Recurse -Include "robots.$Environment.txt"
if($RobotFilesToOverWrite)
{
    foreach($file in $RobotFilesToOverWrite)
    {
        $origin=$file
        $destination=$file -replace ".$Environment.","."

        #Copy-Item $origin $destination
    }
}

I was wondering if there is a better way to achieve that?

EDIT: This problem seems to be fixed in PowerShell 3.0

like image 574
Oscar Foley Avatar asked Dec 07 '12 17:12

Oscar Foley


People also ask

What is the difference between ForEach and for loop in PowerShell?

The difference between the two is that foreach will load the entire collection in the memory before it starts processing the data, which ForEach-Object will process the data one at a time. This makes ForEach-Object perfect to pipe behind another function.

Why we use for the body of for each loop in PowerShell?

In PowerShell, a For Each loop (sometimes referred to as a ForEach-Object loop) is useful when you need a script to perform an action against multiple items.

What are the two important components of ForEach?

The part of the foreach statement enclosed in parenthesis represents a variable and a collection to iterate.

What is the difference between ForEach and ForEach-Object in PowerShell?

As expected, the ForEach statement, which allocates everything to memory before processing, is the faster of the two methods. ForEach-Object is much slower. Of course, the larger the amount of data, the more risk you have of running out of memory before you are able to process all of the items.


2 Answers

# one way is using @(), it ensures an array always, i.e. empty instead of null
$RobotFilesToOverWrite = @(Get-ChildItem -Path $tempExtractionDirectory -Recurse -Include "robots.$Environment.txt")
foreach($file in $RobotFilesToOverWrite)
{
    ...
}

# another way (if possible) is not to use an intermediate variable
foreach($file in Get-ChildItem -Path $tempExtractionDirectory -Recurse -Include "robots.$Environment.txt")
{
    ...
}
like image 169
Roman Kuzmin Avatar answered Oct 14 '22 02:10

Roman Kuzmin


quote from http://blogs.msdn.com/b/powershell/archive/2012/06/14/new-v3-language-features.aspx

ForEach statement does not iterate over $null

In PowerShell V2.0, people were often surprised by:

PS> foreach ($i in $null) { 'got here' } got here

This situation often comes up when a cmdlet doesn’t return any objects. In PowerShell V3.0, you don’t need to add an if statement to avoid iterating over $null. We take care of that for you.

like image 33
Loïc MICHEL Avatar answered Oct 14 '22 04:10

Loïc MICHEL