Fix PowerShell Error: PSCustomObject Does Not Contain a Method Named 'ForEach'
If you have encountered the error Method invocation failed because [System.Management.Automation.PSCustomObject] does not contain a method named 'ForEach', you are not alone. This is a common point of confusion when experimenting with PowerShell's intrinsic methods on custom objects.
Why PSCustomObject Fails with .ForEach()
PowerShell 4.0 introduced intrinsic methods like .ForEach() and .Where(). These methods provide a high-performance, fluent syntax for iterating over items without routing data through the pipeline.
While intrinsic methods are automatically attached to collection types and most standard scalar (single value) types, [pscustomobject] is a special exception.
Because a PSCustomObject relies on dynamic member resolution to handle custom properties and methods, the PowerShell engine does not inject the intrinsic collection methods into it. When you execute $myObject.ForEach('singleValue'), PowerShell attempts to look up a literal method named ForEach on the object, fails to find it, and throws an error.
Which PowerShell Objects Support .ForEach()?
The .ForEach() intrinsic method is available on:
- Arrays and Collections: Any object implementing
ICollectionorIEnumerable, such as standard arrays (@()),[System.Collections.Generic.List[T]], orArrayList. - Standard Primitive/Scalar Types: Primitive types like
[int],[string], or[datetime]automatically get boxed into a collection context when calling intrinsic methods (e.g.,(42).ForEach({ $_ * 2 })works).
How to Fix the Error
Solution 1: Wrap the Object in an Array
If you want to use the .ForEach() method on a single PSCustomObject, force PowerShell to treat it as an array by wrapping it in the array subexpression operator @():
$myObject = [pscustomobject]@{
singleValue = 'Hello'
arrayValue = @(0..10)
}
# Force array context
@($myObject).ForEach('singleValue')Solution 2: Call .ForEach() Directly on the Property
If you want to iterate over an array stored inside a property of your custom object, invoke .ForEach() on that property directly:
# arrayValue is an array, so .ForEach() works directly on it
$myObject.arrayValue.ForEach({ $_ * 2 })Solution 3: Use the Pipeline or standard foreach loop
Alternatively, use the standard pipeline operator ForEach-Object or a standard foreach loop, both of which accept PSCustomObject without issue:
# Pipeline approach
$myObject | ForEach-Object { $_.singleValue }
# Direct property access
$myObject.singleValueSummary
A PSCustomObject does not natively contain the intrinsic .ForEach() method due to how custom member resolution works in PowerShell. To resolve the issue, either wrap the object in an array using @($myObject).ForEach(...) or access the property directly.