powershellsyntaxpipehelp-system

PowerShell $_ syntax


In this answer the author proposed the following snippet:

dir -Path C:\FolderName -Filter *.fileExtension -Recurse | %{$_.FullName}

I can understand the majority of it, but I'm unable to search documentation for the last part. The output of the search is piped | and used in %{} and as $_.

I have experimented around it, %{} is a for-each statement I believe, bing search was not effective. $_ is also somewhat magic: it is a variable, with no name and thus immediately consumed? I don't care much for the .FullName, that part I sorted out. Again, bing search was not effective, nor searching for those char sequences in PowerShell docs.

Can anybody explain it to me?


Solution

  • %{} is not "a thing" - it's two things: % and {}

    % is an alias for the ForEach-Object cmdlet:

    PS ~> Get-Alias '%'
    CommandType     Name                                               Version    Source
    -----------     ----                                               -------    ------
    Alias           % -> ForEach-Object
    

    ... so it resolves to:

    ... |ForEach-Object { $_.FullName }
    

    ForEach-Object is basically PowerShell's map function - it takes input via the pipeline and applies the operation described in the {} block to each one of them.

    $_ is an automatic reference to the current pipeline input item being processed

    You can think of it a bit like a foreach($thing in $collection){} loop:

    1..10 |ForEach-Object { $_ * 10 }
    # produces the same output as
    foreach($n in 1..10){
        $n * 10
    }
    

    Except we can now stick our loop in the middle of a pipeline and have it produce output for immediate consumption:

    1..10 |ForEach-Object { $_ * 10 } |Do-SomethingElse
    

    ForEach-Object is not the only thing that makes use of the $_ automatic variable in PowerShell - it's also used for pipeline-binding expressions:

    mkdir NewDirectory |cd -Path { $_.FullName }
    

    ... as well as property expressions, a type of dynamic property definition supported by a number of cmdlets like Sort-Object:

    1..10 |Sort-Object { -$_ } # sort in descending order without specifying -Descending
    

    ... Group-Object:

    1..10 |Group-Object { $_ % 3 } # group terms by modulo congruence
    

    ... and Select-Object:

    1..10 |Select-Object @{Name='TimesTen';Expression={$_ * 10}} # Create synthetic properties based on dynamic value calculation over input