As @mklement0 pointed out in the comments, Write-Host
is not the right tool for this, as its only used for displaying purposes.
Here is a simple alternative that doesn't change too much of your original code:
function Get-FileHashInfo
{
Param($mydir)
& {
foreach ($item in Get-ChildItem -recurse -file $mydir -force)
{
$mypath = [string]$item.directory + "\" + [string]$item.name
$myhash = Get-FileHash -Path $mypath
"$($myhash.hash) $($item.name) $($item.directory)"
}
} | Out-File -FilePath ".\output.txt"
}
Which wraps your code in a script block and redirects the output to Out-File
. This Cmdlet is the PowerShell way of doing the standard output redirection >
operator. It also saves for-display representations of its input objects, given that it uses the same formatting as in the console. You could also have a look at Out-File: Using PowerShell to Redirect Output to File for a nice explanation on what Out-File
does as well.
You also don't need to use Write-Output
here, since supplying the string by itself is already good enough for passing it down the pipeline to Out-File
. You could test this out by using Write-Output "$($myhash.hash) $($item.name) $($item.directory)"
in the above snippet, and notice that it does the same thing.
Additionally, to call the script block you need to use the Call operator &
, which goes into more detail in About Operators. If you don't use this, you will end up writing the foreach
loop code block to the file.
Update
As @mklement0 helpfully suggested in the comments, Removing Out-File
from the function and instead passing it down the pipeline to Get-FileHashInfo
is a better idea. I wrote the earlier example just for quick demo purposes, but the snippet below is a better way of doing it. It also doesn't need to use a script block anymore, but demonstrating how to use it in conjunction with pipelines is good for learning purposes anyways :).
function Get-FileHashInfo
{
Param($mydir)
foreach ($item in Get-ChildItem -recurse -file $mydir -force)
{
$mypath = [string]$item.directory + "\" + [string]$item.name
$myhash = Get-FileHash -Path $mypath
"$($myhash.hash) $($item.name) $($item.directory)"
}
}
Get-FileHashInfo -mydir "C:\test" | Out-File -FilePath ".\output.txt"