1

I am trying to figure out how to print a list of filepaths in a folder, along with their accompanying checksum, and the date last modified.

I can get a list of filepaths and checksums:

Get-ChildItem -Recurse | Get-FileHash | Export-Csv -Path C:\Temp\ListOfHashes.csv

I can also get a list of filepaths, checksums and date last-modified:

Get-ChildItem -File -Recurse |
Select DirectoryName,Name,@{N='Version';E={$_.VersionInfo.ProductVersion}},LastWriteTime,Length,@{N='FileHash';E={(Get-FileHash $_).Hash}} | Export-Csv -Path c:\temp\test11.csv

But the weird thing is that the first script (that just prints the hash) has a hash for every file. The second script prints the filepath, date-last modified and hash, but doesn't always include the hash. Does anyone know why?

enter image description here

I figured out what the problem is: it can't write the hash if the file is open. This script, as well as the ones below, all work.

Edit: Philip Fourie's addition is crucial:

Get-ChildItem -File -Recurse |
Select DirectoryName,Name,@{N='Version';E={$_.VersionInfo.ProductVersion}},LastWriteTime,Length,@{N='FileHash'; E={(Get-FileHash -LiteralPath $_.FullName).Hash}} | Export-Csv -Path c:\temp \test789.csv`
oymonk
  • 427
  • 9
  • 27
  • Glad to know you got it to work. Thanks for the feedback about it not working when the file is open, good to know for future reference. – Philip Fourie Mar 06 '20 at 00:38

2 Answers2

1

Replace Get-FileHash $_ with Get-FileHash -LiteralPath $_.FullName

$_ contains only the filename, for Get-FileHash to work for the recursively child items it need to have the full path and filename.

-LiteralPath might the second part to the solution. The [te] in your files might be interpreted as a regular expression. More info here: Unable to get output from get-filehash

Philip Fourie
  • 111,587
  • 10
  • 63
  • 83
  • Thank you for your suggestion. I tried, `Get-ChildItem -File -Recurse | Select DirectoryName,Name,@{N='Version';E={$_.VersionInfo.ProductVersion}},LastWriteTime,Length,@{N='FileHash';E={(Get-FileHash $_.FullName).Hash}} | Export-Csv -Path c:\temp\test12.csv` but am still getting gaps. Included a picture above. – oymonk Mar 06 '20 at 00:15
  • That is puzzling, I am not seeing the same behavior on my side. – Philip Fourie Mar 06 '20 at 00:24
  • Good pointers, but note that with the (implied) `-Path` parameter, arguments are interpreted as [wildcard expressions](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Wildcards), not regular expressions. Also, in PowerShell [Core] 6+ the `$_.FullName` workaround is no longer necessary - see [this answer](https://stackoverflow.com/a/53400031/45375). – mklement0 Mar 06 '20 at 02:57
1

Is this what you are after?

Clear-Host
Get-ChildItem -Path 'D:\temp' -File | 
Select-Object -Property * -First 3 | 
ForEach{
    [PSCustomObject]@{
        'BaseName'                    = $PSItem.BaseName
        'FullName'                    = $PSItem.FullName
        'Length'                      = $PSItem.Length
        'LastWriteTime'               = $PSItem.LastWriteTime
        'HashCode Based on Name'      = $PSItem.GetHashCode()
        'HashCode Based on FullName'  = $PSItem.FullName.GetHashCode()
        'File Hash Only'              = (Get-FileHash -Path $PSItem.FullName).Hash
        'File Hash'                   = Get-FileHash -Path $PSItem.FullName
    }
} 

<#
# Results

BaseName                   : 23694d1213305764-revision-number-in-excel-book1
FullName                   : D:\temp\23694d1213305764-revision-number-in-excel-book1.xls
Length                     : 28817
LastWriteTime              : 06-Feb-20 14:02:47
HashCode Based on Name     : 62001128
HashCode Based on FullName : -1676880214
File Hash Only             : A3CB4415D3FAAAB38A6F7A8D959F9BE08C2E06B9A21DFC8DFEA7F0387D6F231A
File Hash                  : @{Algorithm=SHA256; Hash=A3CB4415D3FAAAB38A6F7A8D959F9BE08C2E06B9A21DFC8DFEA7F0387D6F231A; 
                             Path=D:\temp\23694d1213305764-revision-number-in-excel-book1.xls}

BaseName                   : 5 Free Software You'll Wish You Knew Earlier! 2019 - YouTube
FullName                   : D:\temp\5 Free Software You'll Wish You Knew Earlier! 2019 - YouTube.url
Length                     : 69
LastWriteTime              : 29-Dec-19 21:50:56
HashCode Based on Name     : 62001128
HashCode Based on FullName : -1214175701
File Hash Only             : 3427AD8DC44986F90F22FCCAEB108E32214A01F4917BC4F7AA159E547169BB2F
File Hash                  : @{Algorithm=SHA256; Hash=3427AD8DC44986F90F22FCCAEB108E32214A01F4917BC4F7AA159E547169BB2F; Path=D:\temp\5 Free Software You'll Wish You Knew Earlier! 
                             2019 - YouTube.url}

BaseName                   : abc
FullName                   : D:\temp\abc.txt
Length                     : 70
LastWriteTime              : 05-Mar-20 16:05:56
HashCode Based on Name     : 62001128
HashCode Based on FullName : -808200336
File Hash Only             : 63231FC845361CF6AD167D63782778DDB0528F39A188893AE6E2D8CA1F3362A6
File Hash                  : @{Algorithm=SHA256; Hash=63231FC845361CF6AD167D63782778DDB0528F39A188893AE6E2D8CA1F3362A6; Path=D:\temp\abc.txt}
#>
postanote
  • 15,138
  • 2
  • 14
  • 25
  • Thanks for the information. It's what I'm after, but I'm surprised the hash code is so small in length. I thought that checksums were supposed to be 64 characters long? – oymonk Mar 06 '20 at 00:23
  • See my update for you as it depends on which object you call/use and how. – postanote Mar 06 '20 at 00:26
  • Thank you for the information. As it turns out, the problem was me (I had files open, which prevents the hash from being calculated). Thank you for working with me on this problem – oymonk Mar 06 '20 at 00:35
  • No worries, glad you found your catch22. – postanote Mar 06 '20 at 00:36