Home > OS >  what is the scope of $_ in a foreach-object loop in Powershell
what is the scope of $_ in a foreach-object loop in Powershell

Time:11-29

Here's a simplified version of the script I'm trying to write:

$i = 0
Get-ChildItem -Filter *.bat|
ForEach-Object {
    Write-Host $_.Name
    switch ($i) {
        0 { Write-Host $_.Name}
        1 { Write-Host $_.Name }
        2 { Write-Host $_.Name }
        Default {Write-Host "nothing here"}
    }
}

So the first Write-Host command works as expected, but once I get inside the switch statement Write-Host prints out nothing, which is mystifying to me. I assume the problem has something to do with the scope of $_ but I don't know. I'm a total Powershell amateur. Isn't the switch statement inside the foreach loop so the scope shouldn't be an issue?

If I do this then everything works like I expected, the filenames get printed from inside and outside the switch statement:

$i = 0
Get-ChildItem -Filter *.bat |
ForEach-Object {
    Write-Host $_.Name
    $temp = $_.Name
    switch ($i) {
        0 { Write-Host $temp }
        1 { Write-Host $temp }
        2 { Write-Host $temp }
        Default {Write-Host "nothing here"}
    }
}

Can someone explain what is going on here?

CodePudding user response:

$_ is getting a different value inside your switch statement - it's actually getting the value of $i and it therefore is an Int32 and doesn't have a Name property. When you assign to $temp and use that inside the switch it works because you assign the (string) value you want to a new variable.

If you were to use $_ again after the switch you would be able to access all the properties as before.

By using the code below, you're able to see what type $_ is taking as it is used in the different scopes/pipelines

Get-ChildItem -Filter *.bat |
ForEach-Object {
    Write-Host $_.gettype()
    switch ($i) {
        Default {
          Write-Host $_.gettype()
        }
    }
}

CodePudding user response:

As written here:

about_Switch

The thing is that The $_ automatic variable contains the value of the expression passed to the switch statement. That means that it does not contain the same value as it had before you entered into the switch statement.

Move over, if you would like to read more about $_ you can also refer to this article:

What Does $_ Mean in PowerShell

Good luck :)

  • Related