Shell – Why does $_.Name include full path when within quotes in Powershell

powershell

When I run this in powershell it outputs the name of my files (in this case just one), without full path:

PS C:\dev\temp> gci test.* | % { $_.Name }
test.txt

When I put the name in quotes for string formatting it includes the full path:

PS C:\dev\temp> gci test.* | % { "Name is: $_.Name" }
Name is: C:\dev\temp\test.txt.Name

What crazy magic is going on here? How can I get the name without full path and use it in quotes for formatting? I could use "blah " + $_.Name + " blah" but that seems uglier.

Best Answer

Powershell automatically expands variables in double quotes. Instead of returning the name propery of your object it returns what it thinks is the value you need.

If you want to select the name attribute you can do it like this:

gci test.* | % { "Name: $($_.Name)" }

This forces Powershell to evaluate the expression in the braces first so that it only concatenates your string and the name property.

A better approach to do this would be this though:

gci test.* | select name

Why do you want to turn it into a string that kills the pipelines's object oriented paramater binding?

Edit:

The better approach is to output stuff to a file like this:

foreach($file in (gci test.*)) 
{
    ("Name: {0} is here {1}" -f $file.name,$file.fullname) | out-file C:\temp\log.txt -Append -Encoding utf8
}
Related Question