Why does "Get-ChildItem -File | Get-FileHash" work?

System.IO.FileInfo / System.IO.DirectoryInfo instances output by PowerShell cmdlets have a .PSPath property[*] that contains the instances' fully qualified path, which is the full file-system path prefixed by the PS provider name (e.g., Microsoft.PowerShell.Core\FileSystem::C:\windows).

File-processing cmdlets such as Get-FileHash have a -LiteralPath parameter which has an alias name of -PSPath.

Because a -LiteralPath parameter (typically) accepts input from the pipeline by property name, input objects that have a .PSPath property automatically bind to it, by virtue of the PSPath parameter alias name.


How to discover this behavior:

  • Via the online help topic:

parameter description

  • Programmatically:

    • Note: Get-Help Get-FileHash -Parameter LiteralPath | Select-Object name, aliases, pipelineinput works too in this case, but this approach is generally restricted to target commands that come with MAML-based help files, and even those that do can have help files that are out of sync with the actual command definition.
PS> & {
        Get-Command $args[0] | % Parameters | % $args[1] |
        Select-Object Name, Aliases, @{
            n = 'Accepts pipeline input';
            e = { $(if ($_.Attributes.ValueFromPipeline) { 'by value' }), $(if ($_.Attributes.ValueFromPipelineByPropertyName) { 'by property name' }) -join ', ' -replace '^, ' }
        }
    } Get-FileHash LiteralPath


Name        Aliases      Accepts pipeline input
----        -------      ----------------------
LiteralPath {PSPath, LP} by property name

[*] It is PowerShell's file-system provider that adds this property, among others. The underlying .NET types do not have it. See this answer for more information.


From the About Functions Advanced Parameters documentation, ValueFromPipelineByPropertyName argument section:

The ValueFromPipelineByPropertyName argument indicates that the parameter accepts input from a property of a pipeline object. The object property must have the same name or alias as the parameter.

For example, if the function has a ComputerName parameter, and the piped object has a ComputerName property, the value of the ComputerName property is assigned to the function's ComputerName parameter.

Update: Originally linked the wrong source code file. The correct Get-FileHash source code is here. As @mklement0 correctly answered the Get-ChildItem cmdlet outputs an object with a PSPath property, which makes this work.

Tags:

Powershell