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
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.
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.
The part of the foreach statement enclosed in parenthesis represents a variable and a collection to iterate.
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.
# 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")
{
...
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With