Trying to use ForEach() method and confused what I'm doing wrong


I have List of Objects returned from AzureRM cmdlet and I’m trying just to output them to output stream and it’s not working for some reason.

It appears that you cannot do that on a generic list…

$a = [System.Collections.Generic.List[int]]::new()


void ForEach(System.Action[int] action)

This is the native .NET method, and it returns nothing. It gets called like this:

$a.ForEach({ Write-Host ("Value: {0}" -f $args[0]) })

Value: 1
Value: 4
Value: 7
Value: 10

A couple of ways to make it behave…

$a.GetEnumerator().ForEach({ $_ })

foreach($x in $a) {

This should work as well:

$nicInfo.IpConfigurations | ForEach{$_}

I’m fairly certain the .foreach{} method doesn’t support $_, only $PSItem. Can’t explain why but that’s my experience.

Nope, it supports $_ and $PSItem. In the PowerShell code that handles those things, there is a difference, but they’re handled the same when parsing script blocks, so there aren’t any situations where you can use one and not the other.

However, there are situations where they aren’t used by themselves. Some of the methods on the List class (including its ForEach() method, which differs from the usual PowerShell ETS method that can be used on almost anything that doesn’t have it’s own ForEach()-named method) can’t, for example, and you have to either use $args or define a param() block for them. For example:

using namespace System.Collections.Generic
$List = [List[int]]::new()
$List.AddRange( @(1, 2, 3, 4, 5) )

        $Item -gt 3

# output

PSItem gets resolved to _ internally, so with other words: it’s an alias.

Well, sort of. The code itself does distinguish clearly between them as different tokens, but in terms of how the function they’re treated identically from what I’ve seen.

They have this in the source code for Core:

internal static string GetUnaliasedVariableName(string varName)
	return varName.Equals(SpecialVariables.PSItem, StringComparison.OrdinalIgnoreCase)
			   ? SpecialVariables.Underbar
			   : varName;

internal static class SpecialVariables
	internal static bool IsUnderbar(string name) { return name.Length == 1 && name[0] == '_'; }
	internal const string PSItem = "PSItem";  // simple alias for $_
	internal const string Underbar = "_";

So if varName == “PSItem” then return “_”

So is there any difference between $_ and $psitem?

There is a difference in the amount of characters you have to write. In functionality, no.

Would you know why ‘-and’ and ‘-or’ have the same precedence?