BunnyGuy
BunnyGuy

Reputation: 41

Why $ _ does not return the complete object

I'm a beginner in powershell, I've been using it for just a few weeks, I was thinking about $_ when I saw this:

Get-ChildItem should return the files on a directory

PS C:\Users\Edu-mat\Powershell> Get-ChildItem


    Diretório: C:\Users\Edu-mat\Powershell


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       10/08/2018     13:38              7 Test0.txt
-a----       10/08/2018     13:42              5 Test1.txt
-a----       10/08/2018     13:42              7 Test2.txt
-a----       10/08/2018     13:43              8 Test3.txt

$_ Means current object in the pipeline.

but when i did Get-ChildItem | %{write-host $_} the output was not as expected

PS C:\Users\Edu-mat\Powershell> Get-ChildItem | %{write-host $_}
Test0.txt
Test1.txt
Test2.txt
Test3.txt

WHY $_ is not returning the entire object, it just printing the name of the file ?

can someone please explain me.

Upvotes: 3

Views: 155

Answers (2)

briantist
briantist

Reputation: 47792

Write-Host is for writing information out to the console, so objects are formatted as strings, similar to if you had done gci | % { "$_" } (except the latter writes to the output stream not directly to the host).

If you want to write directly to the console but the same formatting you would see if sent to the console implicitly, use Out-Host as recommended by mklement0:

Get-ChildItem | Out-Host

His comment in full:

I suggest using Out-Host directly; also, perhaps surprisingly, Write-Host "$_" is not always the same as Write-Host $_, because the latter results in .ToString() getting called, which defaults to a culture-sensitive representation (where available), whereas PowerShell's string interpolation by design always uses the invariant culture

Upvotes: 4

Andy
Andy

Reputation: 8562

$_ is returning the entire object, however Write-Host expects a string, and so the .ToString() method is called on the object. In the case of System.IO.FileInfo its ToString() is overridden to output the name of the file.

Try this and see for yourself:

Get-ChildItem | %{Write-Host $_.ToString()}

Get-ChildItem | %{Write-Host $_.GetType()}

Get-ChildItem | %{Write-Host $_.Mode}

Upvotes: 7

Related Questions