PowerShell .NET and GUI Interfaces
I’ve been grabbing a bit of software from Technet (you know, that thing that Microsoft are shutting down! <_<) and with their download links, they provide SHA1 hashes of the ISOs. I had a quick look around the web for something that allowed you to get SHA1 hashes of files and while I found a few, I didn’t find any that would allow you to provide a hash and compare the resultant hash with the one you’re given by the provider so I decided to write one myself and as with any opportunity, I decided to use PowerShell and .NET with Windows Forms to create a GUI interface as opposed to it all being text based. Sacrilege to those PowerShell purists but it’s a limited feature tool and I wanted to learn something new so here’s the code.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
Function Get-FileName($initialDirectory) { [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog $OpenFileDialog.initialDirectory = $initialDirectory $OpenFileDialog.filter = "All files (*.*)| *.*" $OpenFileDialog.ShowDialog() | Out-Null $OpenFileDialog.filename } #end function Get-FileName #We're going to draw a form. [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null #Open a GUI for the user to select the file. $Filename = Get-FileName -initialDirectory "C:\" # Check that the path is correct If (!(Test-Path $Filename)) { Exit } # Create Input Data (Read the file) $File = [System.IO.File]::Open($Filename, "open", "read") # Create a New SHA1 Crypto Provider $Sha1 = New-Object System.Security.Cryptography.SHA1CryptoServiceProvider # Output the hash (converted to Hex) $Hash = [String]::Concat(($Sha1.ComputeHash($File) | % { $_.ToString("x2") })) #[System.Windows.Forms.MessageBox]::Show("$Hash", "SHA1 Hash", 0) # Create a GUI Form $objForm = New-Object System.Windows.Forms.Form $objForm.Text = "SHA1 Hash Calculator/Comparison Tool" $objForm.MaximumSize = $objForm.MinimumSize = $objForm.Size = New-Object System.Drawing.Size(400,250) $objForm.MaximizeBox = $objForm.MinimizeBox = $false $objForm.StartPosition = "CenterScreen" # Add a label $oTitle = New-Object System.Windows.Forms.Label $oTitle.Location = New-Object System.Drawing.Size(5,5) $oTitle.Size = New-Object System.Drawing.Size(385,40) $oTitle.Text = "The calculated hash for your selected file is shown below. You can paste a known hash and compare the two by clicking the compare button." $objForm.Controls.Add($oTitle) #File Label $oFileLabel = New-Object System.Windows.Forms.Label $oFileLabel.Location = New-Object System.Drawing.Size(5,(53)) $oFileLabel.Size = New-Object System.Drawing.Size(105,20) $oFileLabel.Text = "File:" $objForm.Controls.Add($oFileLabel) # Add a Textbox $oFileTB = New-Object System.Windows.Forms.TextBox $oFileTB.Location = New-Object System.Drawing.Size(($oFileLabel.Left + $oFileLabel.Width + 5),($oFileLabel.Top -3)) $oFileTB.Size = New-Object System.Drawing.Size(265,20) $oFileTB.Text = $Filename.ToString() $oFileTB.ReadOnly = $true $objForm.Controls.Add($oFileTB) # Add a Richtextbox #$oTitle = New-Object System.Windows.Forms.RichTextBox #$oTitle.Location = New-Object System.Drawing.Size(0,0) #$oTitle.Size = New-Object System.Drawing.Size(385,45) #$oTitle.Rtf = "{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang2057{\fonttbl{\f0\fnil\fcharset0 Microsoft Sans Serif;}{\f1\fnil\fcharset0 Calibri;}} #{\*\generator Riched20 6.3.9600}\viewkind4\uc1 #\pard\sa200\sl276\slmult1\f0\fs16\lang9 The calculated hash for your selected file \b ("+$Filename.Replace("\", "\\")+")\b0 is shown below. You can paste a known hash and compare the two by clicking the compare button.\f1\fs22\par #}" #$oTitle.ScrollBars = "None" #$oTitle.ReadOnly = $True #$objForm.Controls.Add($oTitle) # Add a label $objLabel = New-Object System.Windows.Forms.Label $objLabel.Location = New-Object System.Drawing.Size(5,(53+50)) # Everything elses location is calculated in reference to this. $objLabel.Size = New-Object System.Drawing.Size(105,20) $objLabel.Text = "Calculated SHA1:" #$objLabel.TextAlign = "MiddleRight" $objForm.Controls.Add($objLabel) # Add another label $objLabel2 = New-Object System.Windows.Forms.Label $objLabel2.Text = "Comparison SHA1:" #$objLabel2.TextAlign = "MiddleRight" $objLabel2.Location = New-Object System.Drawing.Point ($objLabel.Left, ($objLabel.Height + $objLabel.Top + 10)) $objLabel2.Size = New-Object System.Drawing.Size(105,20) $objForm.Controls.Add($objLabel2) # Add a Textbox $objTextBox = New-Object System.Windows.Forms.TextBox $objTextBox.Location = New-Object System.Drawing.Size(($objLabel.Left + $objLabel.Width + 5),($objLabel.Top -3)) $objTextBox.Size = New-Object System.Drawing.Size(265,20) $objTextBox.Text = $Hash $objTextBox.ReadOnly = $true $objForm.Controls.Add($objTextBox) # Add comparison box $objSuppliedVal = New-Object System.Windows.Forms.TextBox $objSuppliedVal.Location = New-Object System.Drawing.Point ($ObjTextBox.Left, ($objTextBox.Height + $objTextBox.Top + 10)) $objSuppliedVal.Size = New-Object System.Drawing.Size(265,20) $objForm.Controls.Add($objSuppliedVal) # Add an Exit button $ExitButton = New-Object System.Windows.Forms.Button #$ExitButton.Location = New-Object System.Drawing.Size(300,100) $ExitButton.Location = New-Object System.Drawing.Point (($ObjTextBox.Right - 75), ($objSuppliedVal.Height + $objSuppliedVal.Top + 10)) $ExitButton.Size = New-Object System.Drawing.Size(75,23) $ExitButton.Text = "Exit" #$ExitButton.Add_Click({$objForm.Close()}) $objForm.CancelButton = $ExitButton $objForm.Controls.Add($ExitButton) # Add compare button $CompareButton = New-Object System.Windows.Forms.Button $CompareButton.Location = New-Object System.Drawing.Point (($ExitButton.Left - $ExitButton.Width - 10), ($objSuppliedVal.Height + $objSuppliedVal.Top + 10)) #$CompareButton.Location = New-Object System.Drawing.Size($ExitButton.Left - $ExitButton.Width - 10,100) $CompareButton.Size = New-Object System.Drawing.Size(75,23) $CompareButton.Text = "Compare" $CompareButton.Add_Click({ $SuppliedValue = $objSuppliedVal.Text.ToLower() $CalculatedValue = $objTextBox.Text.ToLower() $MsgBoxButtons = New-Object System.Windows.Forms.MessageBoxButtons $MsgBoxIcon = New-Object System.Windows.Forms.MessageBoxIcon If ($SuppliedValue -eq $CalculatedValue) { $MsgBoxButtons = "OK" $MsgBoxIcon = "Information" [System.Windows.Forms.MessageBox]::Show("Matched successfully.", "Success", $MsgBoxButtons, $MsgBoxIcon) } Else { $MsgBoxButtons = "OK" $MsgBoxIcon = "Warning" [System.Windows.Forms.MessageBox]::Show("Not matched.", "Not matched", $MsgBoxButtons, $MsgBoxIcon) } }) $objForm.Controls.Add($CompareButton) $objForm.Topmost = $true $objForm.ShowDialog() # Clear up $File.Dispose() |
All that lot should give you:
A prompt to select the file you want to calculate the hash of
The hash result
And then, if you supply a hash and click the Compare button, it’ll say either
Now I’m sure there are PowerShell gurus out there that could have all this done in 4 lines of code but it was a learning experience so the code is always likely to be a little more verbose than is absolutely necessary.
Feel free to use the code but plug me as a source if you’re going to use the code on your own blog if you wouldn’t mind.
-Lewis