How do you stop Get-FileHash from truncating the hash string?

Get-FileHash example
Get-FileHash example

Yun Ji (lit. trace of cloud) wants to know how to stop Get-FileHash from truncating the hash string. For example, if you Get-FileHash .\FileHashFormat.ps1xml, you might see

Algorithm       Hash
---------       ----
SHA256          8DE318E911C6873FB3661306A8AFBF9BFE0CC02CCAA74960886B5D50DC41...

Recall that PowerShell is object-oriented, the hash string is always there in the output object, and it is in the conversion from the object to its string string representation that truncates the result. So formatting it in a different way will put the full string to the host:

Get-FileHash .\FileHashFormat.ps1xml | Format-List
Get-FileHash .\FileHashFormat.ps1xml | Format-Table -Wrap
Get-FileHash .\FileHashFormat.ps1xml | Format-Custom

The next question: How do you make a specific formatting the default? I didn’t know this either, so I looked up the help and documentation.

Get-Help *format*
# Among the results, you see "about_Format.ps1xml".

Get-Help about_Format.ps1xml -ShowWindow

According to the documentation, you can use XML files to specify formatting options for any type. Now type Get-FileHash .\FileHashFormat.ps1xml | Get-Member, you’ll see the type name is Microsoft.Powershell.Utility.FileHash, so you can write the following formatting file (which I saved as FileHashFormat.ps1xml):

<?xml version="1.0" encoding="utf-8" ?>
<Configuration><ViewDefinitions>
<View>
    <Name>Microsoft.Powershell.Utility.FileHash</Name>
    <ViewSelectedBy><TypeName>Microsoft.Powershell.Utility.FileHash</TypeName></ViewSelectedBy>
    <GroupBy><PropertyName>Algorithm</PropertyName></GroupBy>
    <ListControl><ListEntries><ListEntry><ListItems>
        <ListItem><PropertyName>Path</PropertyName></ListItem>
        <ListItem><PropertyName>Hash</PropertyName></ListItem>
    </ListItems></ListEntry></ListEntries></ListControl>
</View>
</ViewDefinitions></Configuration>

Note that it’s not possible to make the table wrap by default, so we use the list style. Moreover, in a single invocation of Get-FileHash, you can only specify one Algorithm, so there’s no point repeating that information for every file — put that as the group header. Now let’s try that out:

# Allow unsigned formatting files.
Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope Process -Force

# FileHash is a built-in type, so you must prepend the
# format file to override the default formatting options.
Update-FormatData -PrependPath .\FileHashFormat.ps1xml

Get-FileHash .\FileHashFormat.ps1xml, .\FileHashFormat.ps1xml -Algorithm SHA512

Tada! You get this:

   Algorithm: SHA512


Path : C:\Users\GL\Documents\FileHashFormat.ps1xml
Hash : AB34E27D043D539B9CBBF6FCF3367CD3076474FA349A45EBE5398A37AC97040568C7893A
       60F39B4E7C91B3DE37604FE70C471FC21725C8107F0A8C51F42A5DBC

Path : C:\Users\GL\Documents\FileHashFormat.ps1xml
Hash : AB34E27D043D539B9CBBF6FCF3367CD3076474FA349A45EBE5398A37AC97040568C7893A
       60F39B4E7C91B3DE37604FE70C471FC21725C8107F0A8C51F42A5DBC

Now that a specific formatting will be the default if you use Update-FormatData to add it (or override it), all you need to do is to make the call in your $PROFILE for it to become your default (for usual interactive sessions). Of course, you always have to abide by the execution policy. Personally, I am a trusted root authority of my own computer, I issue a code-signing certificate for myself, and I use the AllSigned execution policy. You could have your own options.

Please enable JavaScript to view the comments powered by Disqus.