I'm trying to create a text file with file names and their MD5 hash next to them. Doesn't really make sense, but it's for learning purposes.
This is how I calculate the hash:
$hash = Get-FileHash -Algorithm MD5 -Path $file | Select-Object Hash
Then I Out-File everything into a text file:
$file.Name + "`t`t" + $hash | Out-File -Append -FilePath ($destination + "inventory$i.txt")
Now every $hash value will look something like this:
@{Hash=2A396C91CB1DE5D7C7843970954CC1D4}
How can I get the "raw" Hash value from that string? Or is it even a string?
In my text file, I want it to look like this:
Name MD5 Hash
helloworld.txt 2A396C91CB1DE5D7C7843970954CC1D4
(By chance, does someone have a better idea for formatting this instead of using `t for tabulators?)
Select-Object Hash
creates a new object with a single property Hash
copied from the input object(s).
To get just the raw value of the Hash
property from each input objcet, use ForEach-Object
instead:
$hash = Get-FileHash -Algorithm MD5 -Path $file | ForEach-Object -MemberName Hash
That being said, instead of grabbing just the hash string from the result, you might want to use the result itself to create the output you need - this way you can easily adapt your script to hash multiple files in the future:
[CmdletBinding(DefaultParameterSetName = 'ByPath')]
param(
[Parameter(Mandatory = $true, ParameterSetName = 'ByPath')]
[string[]]$Path,
[Parameter(Mandatory = $true, ParameterSetName = 'ByPSPath', ValueFromPipelineByPropertyName = $true)]
[Alias('PSPath')]
[string[]]$LiteralPath
)
process {
Get-FileHash @PSBoundParameters |ForEach-Object {
$fileName = Get-ItemPropertyValue -LiteralPath $_.Path -Name Name
"${fileName}`t`t$($_.Hash)"
}
}
Now you can do:
Get-ChildItem -Filter *.ext |.\yourScript.ps1 |Out-File -Append -Path path\to\output.txt