Pipeline input into Powershell Scripts (not functions)

I've been trying to make my PowerShell script—not function— accept pipeline input, and I was surprised to see so much guidance on functions but not scripts. I figured it out but would be surprised if this is the best way.

Short answer: the magic word $input must be the name of the script's pipeline parmeter. That's it.

To illustrate, here is a simple script that generates objects (in the form of PSCustomObject) to be used by the script that consumes it.

# create_input.ps1 - produce test object values for Process-Favorites.ps1

$DATA = @(
@( "Steve", "Orange" ),
@( "Ben", "Blue" ),
@( "Jaimee", "Green" ),
@( "Kevin", "Pink" ),
@( "Bob", "Purple" )
)

$DATA | Foreach-Object {
[PSCustomObject] @{
Name = $_[0]
FavColor = $_[1]
}
}

Now I want my real script to accept these in the input stream, and I tried all kinds of combinations of things to get the stream to bind to my input parameter.

# Process-Favorites.ps1 - INCORRECT VERSION

Param(
[Parameter(Mandatory = $True, ValueFromPipeline = $True)]
[PSCustomObject] $Favorites
)

foreach ($item in $Favorites)
{
Write-Output ( "{0}'s favorite color is {1}" -f $item.Name, $item.FavColor )
}

... but it only processed the last item from the input:

PS> .\create_input.ps1 | .\Process-Favorites.ps1
Bob's favorite color is Purple

Hmm. Changing the $Favorites variable to an array (as [PSCustomObject[]]) made no difference, nor did adding Position = 0 to the Parameter section. I turned a lot of knobs.

Finally I hit upon it: by changing $Favorites to the actual magic word $input, it all started working:

# Process-Favorites.ps1 - WORKING VERSION!

Param(
[Parameter(Mandatory = $True, ValueFromPipeline = $True)]
[PSCustomObject] $input
)

foreach ($item in $input)
{
Write-Output ( "{0}'s favorite color is {1}" -f $item.Name, $item.FavColor )
}

Poof: now it works. Does not require Position = 0, nor does the type need to be an array type.

Moral of the story: $input is a magic word in PowerShell.