Saturday 10 January 2009

Get-Hash2.ps1

  1. <# 
  2. .SYNOPSIS 
  3.    Creates a Hash of a file and returns the hash   
  4. .DESCRIPTION 
  5.     Uses System.Security.Cryptography.HashAlgorithm and members to create
  6.     the hash. This script improves on:
  7.     http://pshscripts.blogspot.com/2009/01/get-hashpsm1.html by using 
  8. .NOTES 
  9.     File Name  : Get-Hash1.PSM1 
  10.     Author     : Thomas Lee - tfl@psp.co.uk 
  11.     Requires   : PowerShell V2 CTP3 
  12.     Thanks to the #PowerShell Twitter Posse (PTP) for help figuring out
  13.     the –verbose parameter. And thanks to the PTP for comments on the
  14.     earlier version of this script, which now uses a file stream as 
  15.     input to the hash alghorithm. 
  16. .LINK 
  17.     Posted to         :  http://pshscripts.blogspot.com/2009/01/get-hash2ps1.html
  18.     Based on          :  http://tinyurl.com/aycszb written by Bart De Smet 
  19.     An improvement of :  http://pshscripts.blogspot.com/2009/01/get-hashpsm1.html 
  20. .PARAMETER Algorithm 
  21.     The name of one of the hash Algorithms defined at 
  22.     http://msdn.microsoft.com/en-us/library/system.security.cryptography.hashalgorithm.aspx 
  23. .PARAMETER File 
  24.     The name of a file to provide a hash for
  25. .PARAMETER Verbose 
  26.     if specified, this script will produce chattier output. 
  27. .EXAMPLE 
  28.     PS C:\foo> ls *.txt | where {!$_.psiscontainer}| c:\foo\Get-Hash2.ps1 sha1 -verbose 
  29.     OK, I'll be chatty 
  30.     The sha1 hash of file C:\foo\asciifile.txt is: "55055a5c8eeb3af7fa6d426314578ee1d56df016" 
  31.  
  32.     The sha1 hash of file C:\foo\log.txt is: "575f4b35e3cadb9b273095fc463bd43e9a3f5774" 
  33.  
  34.     The sha1 hash of file C:\foo\sites.txt is: "8ce6663cd2b64a513cf18a831843afd98e190764" 
  35.  
  36.     The sha1 hash of file C:\foo\test.txt is: "a2f26abbeeb4e6846e159ba506e07cae5496d458" 
  37.  
  38.     The sha1 hash of file C:\foo\test2.txt is: "9b1baaa9077a3691f8e2685d81ffa24cdd73f71d" 
  39.  
  40.     The sha1 hash of file C:\foo\unicodefile.txt is: "094ef2696d9eb3374e657eb7c227ff4c36cd0cb9" 
  41. .EXAMPLE 
  42.     PS C:\foo> ls *.txt | where {!$_.psiscontainer}| c:\foo\Get-Hash2.ps1 sha1 
  43.     55055a5c8eeb3af7fa6d426314578ee1d56df016 
  44.     575f4b35e3cadb9b273095fc463bd43e9a3f5774 
  45.     8ce6663cd2b64a513cf18a831843afd98e190764 
  46.     a2f26abbeeb4e6846e159ba506e07cae5496d458 
  47.     9b1baaa9077a3691f8e2685d81ffa24cdd73f71d 
  48.     094ef2696d9eb3374e657eb7c227ff4c36cd0cb9 
  49. .EXAMPLE 
  50.     PS C:\foo> Get-Hash  md5 asciifile.txt -verbose 
  51.     OK, I'll be chatty 
  52.     The md5 hash of file c:\foo\asciifile.txt is: "06f51e7bfced5c0623eec5f72e0999d6" 
  53. .EXAMPLE 
  54.     PS C:\foo> .\get-hash2 md5 c:\foo\asciifile.txt 
  55.     06f51e7bfced5c0623eec5f72e0999d6 
  56. #> 
  57. #[CmdletBinding()] 
  58. param ( 
  59. [Parameter(Position=0, mandatory=$true)] 
  60. [string] $Algorithm, 
  61. [Parameter(Position=1, mandatory=$true, valuefrompipeline=$true)] 
  62. [string] $File 
  63.  
  64. Begin {  
  65. if ($VerbosePreference.Value__ -eq 0) {$verbose=$false} else {$verbose=$true
  66. if ($Verbose) {"OK, I'll be chatty"
  67.  
  68. Process { 
  69.  
  70. if ($VerbosePreference.Value__ -eq 0) {$verbose=$false} else {$verbose=$true
  71.  
  72.     # Get the alghorthm object 
  73.     $Algo=[System.Security.Cryptography.HashAlgorithm]::Create($algorithm) 
  74.     if ($Algo){ 
  75.         # Open the file 
  76.         $Filemode = [System.IO.FileMode]::Open 
  77.         $Fs = New-Object System.Io.Filestream $File, $Filemode 
  78.         if ($fs.length -gt 0) { 
  79.             # Now compute hash 
  80.             $Hash = $Algo.ComputeHash($Fs)    
  81.             $Hashstring ="" 
  82.             foreach ($byte in $hash) {$hashstring += $byte.tostring("x2")} 
  83.             # pass hash string on 
  84.             if ($verbose){ 
  85.               "The {0} hash of file {1} is: `"{2}`"" -f $algorithm, $file, $hashstring 
  86.               "" 
  87.             } 
  88.             else
  89.              $Hashstring 
  90.             } 
  91.         } 
  92.         else
  93.              if ($verbose) {"File {0} can not be hashed" -f $file ; ""}      
  94.         } 
  95.         $fs.close() 
  96.         } 
  97.     else {"Algorithm {0} not found" -f $algorithm} 

Share this post :

1 comment:

Keith Dahlby said...

Nice script! Two suggestions:

1) Rather than specify $File as [string], leaving it untyped lets you take advantage of the FileInfo you get from GCI. Furthermore, if you don't get a FileInfo you can rely on Get-Item to resolve relative file paths:

if($File -isnot [System.IO.FileInfo])
{ $File = Get-Item $File }
$Fs = $File.OpenRead()

2) foreach isn't particularly PoSh:
$Hash = $Algo.ComputeHash($Fs) | %{$_.ToString('x2')}
$HashString = [string]::Concat($Hash)

Cheers ~
Keith