From fe11148a31f0f4d28bd68cc66341e3e7255e5820 Mon Sep 17 00:00:00 2001 From: iSazonov Date: Wed, 22 Mar 2017 14:37:57 +0300 Subject: [PATCH 1/5] Implement Get-Hash cmdlet --- .../commands/utility/GetHash.cs | 140 ++++++++++++++++-- .../Microsoft.PowerShell.Utility.psd1 | 2 +- .../Microsoft.PowerShell.Utility.psd1 | 2 +- .../Microsoft.PowerShell.Utility.psd1 | 2 +- .../engine/InitialSessionState.cs | 1 + .../Get-Hash.Tests.ps1 | 100 +++++++++++++ 6 files changed, 230 insertions(+), 17 deletions(-) create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Utility/Get-Hash.Tests.ps1 diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetHash.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetHash.cs index 336c4829d42..68149a4a670 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetHash.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetHash.cs @@ -8,10 +8,14 @@ namespace Microsoft.PowerShell.Commands { /// - /// This class implements Get-FileHash + /// This class implements Get-Hash /// - [Cmdlet(VerbsCommon.Get, "FileHash", DefaultParameterSetName = PathParameterSet, HelpUri = "https://go.microsoft.com/fwlink/?LinkId=517145")] - [OutputType(typeof(FileHashInfo))] + [Cmdlet(VerbsCommon.Get, "Hash", DefaultParameterSetName = PathParameterSet, HelpUri = "https://go.microsoft.com/fwlink/?LinkId=517145")] + [OutputType(typeof(FileHashInfo), ParameterSetName = new[] { PathParameterSet, + LiteralPathParameterSet, + StreamParameterSet + })] + [OutputType(typeof(StringHashInfo), ParameterSetName = new[] { StringHashParameterSet })] public class GetFileHashCommand : HashCmdletBase { /// @@ -20,8 +24,8 @@ public class GetFileHashCommand : HashCmdletBase /// Resolved wildcards /// /// - [Parameter(Mandatory = true, ParameterSetName = PathParameterSet, Position = 0, ValueFromPipeline = true, ValueFromPipelineByPropertyName = true)] - public String[] Path + [Parameter(Mandatory = true, ParameterSetName = PathParameterSet, Position = 0, ValueFromPipelineByPropertyName = true)] + public string[] Path { get { @@ -41,7 +45,7 @@ public String[] Path /// [Parameter(Mandatory = true, ParameterSetName = LiteralPathParameterSet, Position = 0, ValueFromPipelineByPropertyName = true)] [Alias("PSPath")] - public String[] LiteralPath + public string[] LiteralPath { get { @@ -53,7 +57,7 @@ public String[] LiteralPath } } - private String[] _paths; + private string[] _paths; /// /// InputStream parameter @@ -63,6 +67,38 @@ public String[] LiteralPath [Parameter(Mandatory = true, ParameterSetName = StreamParameterSet, Position = 0)] public Stream InputStream { get; set; } + /// + /// InputString parameter + /// The strings to calculate a hash + /// We allow `null` and `empty` strings because we can get it from pipeline. + /// + /// + [Parameter(Mandatory = true, ParameterSetName = StringHashParameterSet, Position = 0, ValueFromPipeline = true)] + [AllowNull()] + [AllowEmptyString()] + public string[] InputString { get; set; } + + /// + /// Encoding parameter + /// The Encoding of the 'InputString' + /// + /// + [Parameter(Mandatory = false, ParameterSetName = StringHashParameterSet, Position = 2)] + [ValidateSetAttribute(new string[] { + EncodingConversion.Unknown, + EncodingConversion.String, + EncodingConversion.Unicode, + EncodingConversion.BigEndianUnicode, + EncodingConversion.Utf8, + EncodingConversion.Utf7, + EncodingConversion.Utf32, + EncodingConversion.Ascii, + EncodingConversion.Default, + EncodingConversion.OEM })] + public string Encoding { get; set; } = EncodingConversion.Default; + + + /// /// BeginProcessing() override /// This is for hash function init @@ -78,6 +114,43 @@ protected override void BeginProcessing() /// protected override void ProcessRecord() { + if ( ParameterSetName == StringHashParameterSet) + { + if (InputString == null) + { + WriteStringHashInfo(Algorithm, null, null, Encoding); + } + else + { + foreach (string str in InputString) + { + try + { + //if (str == null) + //{ + // WriteStringHashInfo(Algorithm, string.Empty, string.Empty, Encoding); + // Exception exception = new Exception("Hash for 'null' string is 'null'", ex); + // WriteError(new ErrorRecord(exception, "GetHashInvalidData", ErrorCategory.InvalidData, null)); + //} + //else + //{ + byte[] bytehash = hasher.ComputeHash(EncodingConversion.Convert(this, Encoding).GetBytes(str)); + string hash = BitConverter.ToString(bytehash).Replace("-",""); + WriteStringHashInfo(Algorithm, hash, str, Encoding); + //} + } + catch (Exception ex) + { + WriteStringHashInfo(Algorithm, string.Empty, string.Empty, Encoding); + Exception exception = new Exception("Hash for 'null' string is 'null'", ex); + WriteError(new ErrorRecord(exception, "GetHashInvalidData", ErrorCategory.InvalidData, null)); + } + } + } + + return; + } + List pathsToProcess = new List(); ProviderInfo provider = null; @@ -119,17 +192,15 @@ protected override void ProcessRecord() foreach (string path in pathsToProcess) { - byte[] bytehash = null; - String hash = null; Stream openfilestream = null; try { openfilestream = File.OpenRead(path); - bytehash = hasher.ComputeHash(openfilestream); + byte[] bytehash = hasher.ComputeHash(openfilestream); - hash = BitConverter.ToString(bytehash).Replace("-",""); - WriteHashResult(Algorithm, hash, path); + String hash = BitConverter.ToString(bytehash).Replace("-",""); + WriteFileHashInfo(Algorithm, hash, path); } catch (FileNotFoundException ex) { @@ -160,14 +231,14 @@ protected override void EndProcessing() bytehash = hasher.ComputeHash(InputStream); hash = BitConverter.ToString(bytehash).Replace("-",""); - WriteHashResult(Algorithm, hash, ""); + WriteFileHashInfo(Algorithm, hash, ""); } } /// /// Create FileHashInfo object and output it /// - private void WriteHashResult(string Algorithm, string hash, string path) + private void WriteFileHashInfo(string Algorithm, string hash, string path) { FileHashInfo result = new FileHashInfo(); result.Algorithm = Algorithm; @@ -176,12 +247,26 @@ private void WriteHashResult(string Algorithm, string hash, string path) WriteObject(result); } + /// + /// Create StringHashInfo object and output it + /// + private void WriteStringHashInfo(string Algorithm, string hash, string HashedString, string Encoding) + { + StringHashInfo result = new StringHashInfo(); + result.Algorithm = Algorithm; + result.Hash = hash; + result.HashedString = HashedString; + result.Encoding = Encoding; + WriteObject(result); + } + /// /// Parameter set names /// private const string PathParameterSet = "Path"; private const string LiteralPathParameterSet = "LiteralPath"; private const string StreamParameterSet = "StreamParameterSet"; + private const string StringHashParameterSet = "StringHashParameterSet"; } @@ -289,4 +374,31 @@ public class FileHashInfo /// public string Path { get; set;} } + + /// + /// StringHashInfo class contains information about a String hash + /// + public class StringHashInfo + { + /// + /// Hash algorithm name + /// + public string Algorithm { get; set;} + + /// + /// Hash value of the 'HashedString' string + /// + public string Hash { get; set;} + + /// + /// Encoding of the 'HashedString' string + /// + public string Encoding { get; set;} + + /// + /// HashedString value which 'Hash' calculated for + /// + public string HashedString { get; set;} + } + } diff --git a/src/Modules/Unix/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 b/src/Modules/Unix/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 index 65f4c80fc5b..edeae0d53d3 100644 --- a/src/Modules/Unix/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 +++ b/src/Modules/Unix/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 @@ -20,7 +20,7 @@ CmdletsToExport= "Format-List", "Format-Custom", "Format-Table", "Format-Wide", "Clear-Variable", "Export-Clixml", "Import-Clixml", "Import-PowerShellDataFile", "ConvertTo-Xml", "Select-Xml", "Write-Debug", "Write-Verbose", "Write-Warning", "Write-Error", "Write-Information", "Write-Output", "Set-PSBreakpoint", "Get-PSBreakpoint", "Remove-PSBreakpoint", "Enable-PSBreakpoint", "Disable-PSBreakpoint", "Get-PSCallStack", - "Send-MailMessage", "Get-TraceSource", "Set-TraceSource", "Trace-Command", "Get-FileHash", + "Send-MailMessage", "Get-TraceSource", "Set-TraceSource", "Trace-Command", "Get-Hash", "Get-Runspace", "Debug-Runspace", "Enable-RunspaceDebug", "Disable-RunspaceDebug", "Get-RunspaceDebug", "Wait-Debugger" , "Get-Uptime", "New-TemporaryFile", "Get-Verb", "Format-Hex", "Remove-Alias" FunctionsToExport= "Import-PowerShellDataFile" diff --git a/src/Modules/Windows-Core/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 b/src/Modules/Windows-Core/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 index 6aa5b03d76a..2fe7376fe66 100644 --- a/src/Modules/Windows-Core/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 +++ b/src/Modules/Windows-Core/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 @@ -20,7 +20,7 @@ CmdletsToExport= "Format-List", "Format-Custom", "Format-Table", "Format-Wide", "Clear-Variable", "Export-Clixml", "Import-Clixml", "Import-PowerShellDataFile","ConvertTo-Xml", "Select-Xml", "Write-Debug", "Write-Verbose", "Write-Warning", "Write-Error", "Write-Information", "Write-Output", "Set-PSBreakpoint", "Get-PSBreakpoint", "Remove-PSBreakpoint", "New-TemporaryFile", "Enable-PSBreakpoint", "Disable-PSBreakpoint", "Get-PSCallStack", - "Send-MailMessage", "Get-TraceSource", "Set-TraceSource", "Trace-Command", "Get-FileHash", + "Send-MailMessage", "Get-TraceSource", "Set-TraceSource", "Trace-Command", "Get-Hash", "Unblock-File", "Get-Runspace", "Debug-Runspace", "Enable-RunspaceDebug", "Disable-RunspaceDebug", "Get-RunspaceDebug", "Wait-Debugger" , "Get-Uptime", "Get-Verb", "Format-Hex", "Remove-Alias" FunctionsToExport= "ConvertFrom-SddlString" diff --git a/src/Modules/Windows-Full/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 b/src/Modules/Windows-Full/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 index 4a48f4ec1e7..0b50ffce5f2 100644 --- a/src/Modules/Windows-Full/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 +++ b/src/Modules/Windows-Full/Microsoft.PowerShell.Utility/Microsoft.PowerShell.Utility.psd1 @@ -22,7 +22,7 @@ CmdletsToExport= "Format-List", "Format-Custom", "Format-Table", "Format-Wide", "Clear-Variable", "Export-Clixml", "Import-Clixml", "Import-PowerShellDataFile", "ConvertTo-Xml", "Select-Xml", "Write-Debug", "Write-Verbose", "Write-Warning", "Write-Error", "Write-Information", "Write-Output", "Set-PSBreakpoint", "Get-PSBreakpoint", "Remove-PSBreakpoint", "Enable-PSBreakpoint", "Disable-PSBreakpoint", "Get-PSCallStack", - "Send-MailMessage", "Get-TraceSource", "Set-TraceSource", "Trace-Command", "Show-Command", "Unblock-File", "Get-FileHash", + "Send-MailMessage", "Get-TraceSource", "Set-TraceSource", "Trace-Command", "Show-Command", "Unblock-File", "Get-Hash", "Get-Runspace", "Debug-Runspace", "Enable-RunspaceDebug", "Disable-RunspaceDebug", "Get-RunspaceDebug", "Wait-Debugger", "ConvertFrom-String", "Convert-String" , "Get-Uptime", "New-TemporaryFile", "Get-Verb", "Format-Hex" FunctionsToExport= "ConvertFrom-SddlString" diff --git a/src/System.Management.Automation/engine/InitialSessionState.cs b/src/System.Management.Automation/engine/InitialSessionState.cs index f39ed212529..574af75692b 100644 --- a/src/System.Management.Automation/engine/InitialSessionState.cs +++ b/src/System.Management.Automation/engine/InitialSessionState.cs @@ -4605,6 +4605,7 @@ internal static SessionStateAliasEntry[] BuiltInAliases new SessionStateAliasEntry("ghy", "Get-History", "", ReadOnly), new SessionStateAliasEntry("gi", "Get-Item", "", ReadOnly), new SessionStateAliasEntry("gl", "Get-Location", "", ReadOnly), + new SessionStateAliasEntry("Get-FileHash", "Get-Hash", "", ReadOnly), new SessionStateAliasEntry("gm", "Get-Member", "", ReadOnly), new SessionStateAliasEntry("gmo", "Get-Module", "", ReadOnly), new SessionStateAliasEntry("gp", "Get-ItemProperty", "", ReadOnly), diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Get-Hash.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Get-Hash.Tests.ps1 new file mode 100644 index 00000000000..1a12ab8241c --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Get-Hash.Tests.ps1 @@ -0,0 +1,100 @@ +Import-Module $PSScriptRoot\..\..\Common\Test.Helpers.psm1 +Describe "Get-Hash tests for files" -Tags "CI" { + + BeforeAll { + $testDocument = Join-Path -Path $PSScriptRoot -ChildPath assets testablescript.ps1 + Write-Host $testDocument + } + + Context "Default result tests" { + It "Should default to correct algorithm, hash and path" { + $result = Get-Hash $testDocument + + $result | Should BeOfType 'Microsoft.PowerShell.Commands.FileHashInfo' + $result.Algorithm | Should Be "SHA256" + $result.Hash | Should Be "4A6DA9F1C0827143BB19FC4B0F2A8057BC1DF55F6D1F62FA3B917BA458E8F570" + $result.Path | Should Be $testDocument + } + } + + Context "Algorithm tests" { + BeforeAll { + # Keep "sHA1" below! It is for testing that the cmdlet accept a hash algorithm name in any case! + $testcases = + @{ algorithm = "sHA1"; hash = "01B865D143E07ECC875AB0EFC0A4429387FD0CF7" }, + @{ algorithm = "SHA256"; hash = "4A6DA9F1C0827143BB19FC4B0F2A8057BC1DF55F6D1F62FA3B917BA458E8F570" }, + @{ algorithm = "SHA384"; hash = "656215B6A07011E625206F43E57873F49AD7B36DFCABB70F6CDCE2303D7A603E55D052774D26F339A6D80A264340CB8C" }, + @{ algorithm = "SHA512"; hash = "C688C33027D89ACAC920545471C8053D8F64A54E21D0415F1E03766DDCDA215420E74FAFD1DC399864C6B6B5723A3358BD337339906797A39090B02229BF31FE" }, + @{ algorithm = "MD5"; hash = "7B09811D1631C9FD46B39D1D35522F0A" } + } + + It "Should be able to get the correct hash by Path from algorithm" -TestCases $testCases { + param($algorithm, $hash) + $algorithmResult = Get-Hash -Path $testDocument -Algorithm $algorithm + + $algorithmResult | Should BeOfType 'Microsoft.PowerShell.Commands.FileHashInfo' + $algorithmResult.Algorithm | Should Be $algorithm + $algorithmResult.Hash | Should Be $hash + $algorithmResult.Path | Should Be $testDocument + } + + It "Should be able to get the correct hash by InputStream from algorithm" -TestCases $testCases { + param($algorithm, $hash) + $testFileStream = [System.IO.File]::OpenRead($testDocument) + $algorithmResult = Get-Hash -InputStream $testFileStream -Algorithm $algorithm + + $algorithmResult | Should BeOfType 'Microsoft.PowerShell.Commands.FileHashInfo' + $algorithmResult.Algorithm | Should Be $algorithm + $algorithmResult.Hash | Should Be $hash + } + + It "Should be able to get the correct hash by String from algorithm" -TestCases $testCases { + param($algorithm, $hash) + # Simple trick needed to get a test string from byte sequence because the test file contains BOM. + # It allows to reuse the file hashes. + $testBytes = Get-Content $testDocument -Raw -Encoding Byte + $testString = [System.Text.Encoding]::UTF8.GetString($testBytes) + $algorithmResult = Get-Hash -InputString $testString -Algorithm $algorithm -Encoding UTF8 + + $algorithmResult | Should BeOfType 'Microsoft.PowerShell.Commands.StringHashInfo' + $algorithmResult.Algorithm | Should Be $algorithm + $algorithmResult.Hash | Should Be $hash + $algorithmResult.Encoding | Should Be 'UTF8' + $algorithmResult.HashedString | Should Be $testString + } + + It "Should be able to get the correct hash for 'null' String" { + $result = Get-Hash -InputString $null + + $result | Should BeOfType 'Microsoft.PowerShell.Commands.StringHashInfo' + $result.Algorithm | Should Be 'SHA256' + $result.Hash | Should Be $null + $result.Encoding | Should Be 'Default' + $result.HashedString | Should Be $null + } + + It "Should be throw for wrong algorithm name" { + { Get-Hash Get-Hash $testDocument -Algorithm wrongAlgorithm } | ShouldBeErrorId "ParameterArgumentValidationError,Microsoft.PowerShell.Commands.GetFileHashCommand" + } + } + + Context "Paths tests" { + It "With '-Path': no file exist" { + { Get-Hash -Path nofileexist.ttt -ErrorAction Stop } | ShouldBeErrorId "FileNotFound,Microsoft.PowerShell.Commands.GetFileHashCommand" + } + + It "With '-LiteralPath': no file exist" { + { Get-Hash -LiteralPath nofileexist.ttt -ErrorAction Stop } | ShouldBeErrorId "FileNotFound,Microsoft.PowerShell.Commands.GetFileHashCommand" + } + + It "With '-Path': file exist" { + $result = Get-Hash -Path $testDocument + $result.Path | Should Be $testDocument + } + + It "With '-LiteralPath': file exist" { + $result = Get-Hash -LiteralPath $testDocument + $result.Path | Should Be $testDocument + } + } +} From f09a80b4eba66357e280ba2bed574844075551f6 Mon Sep 17 00:00:00 2001 From: iSazonov Date: Mon, 24 Jul 2017 14:50:16 +0300 Subject: [PATCH 2/5] Cleanup tests --- .../Get-Hash.Tests.ps1 | 19 ++++++++++++++++--- .../engine/Basic/DefaultCommands.Tests.ps1 | 3 ++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Get-Hash.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Get-Hash.Tests.ps1 index 1a12ab8241c..34790826c6a 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Get-Hash.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Get-Hash.Tests.ps1 @@ -1,9 +1,7 @@ -Import-Module $PSScriptRoot\..\..\Common\Test.Helpers.psm1 Describe "Get-Hash tests for files" -Tags "CI" { BeforeAll { $testDocument = Join-Path -Path $PSScriptRoot -ChildPath assets testablescript.ps1 - Write-Host $testDocument } Context "Default result tests" { @@ -55,12 +53,19 @@ Describe "Get-Hash tests for files" -Tags "CI" { $testBytes = Get-Content $testDocument -Raw -Encoding Byte $testString = [System.Text.Encoding]::UTF8.GetString($testBytes) $algorithmResult = Get-Hash -InputString $testString -Algorithm $algorithm -Encoding UTF8 + $algorithmResultFromPipe = $testString | Get-Hash -Algorithm $algorithm -Encoding UTF8 $algorithmResult | Should BeOfType 'Microsoft.PowerShell.Commands.StringHashInfo' $algorithmResult.Algorithm | Should Be $algorithm $algorithmResult.Hash | Should Be $hash $algorithmResult.Encoding | Should Be 'UTF8' $algorithmResult.HashedString | Should Be $testString + + $algorithmResultFromPipe | Should BeOfType 'Microsoft.PowerShell.Commands.StringHashInfo' + $algorithmResultFromPipe.Algorithm | Should Be $algorithm + $algorithmResultFromPipe.Hash | Should Be $hash + $algorithmResultFromPipe.Encoding | Should Be 'UTF8' + $algorithmResultFromPipe.HashedString | Should Be $testString } It "Should be able to get the correct hash for 'null' String" { @@ -74,7 +79,7 @@ Describe "Get-Hash tests for files" -Tags "CI" { } It "Should be throw for wrong algorithm name" { - { Get-Hash Get-Hash $testDocument -Algorithm wrongAlgorithm } | ShouldBeErrorId "ParameterArgumentValidationError,Microsoft.PowerShell.Commands.GetFileHashCommand" + { Get-Hash $testDocument -Algorithm wrongAlgorithm } | ShouldBeErrorId "ParameterArgumentValidationError,Microsoft.PowerShell.Commands.GetFileHashCommand" } } @@ -89,11 +94,19 @@ Describe "Get-Hash tests for files" -Tags "CI" { It "With '-Path': file exist" { $result = Get-Hash -Path $testDocument + + $result | Should BeOfType 'Microsoft.PowerShell.Commands.FileHashInfo' + $result.Algorithm | Should Be "SHA256" + $result.Hash | Should Be "4A6DA9F1C0827143BB19FC4B0F2A8057BC1DF55F6D1F62FA3B917BA458E8F570" $result.Path | Should Be $testDocument } It "With '-LiteralPath': file exist" { $result = Get-Hash -LiteralPath $testDocument + + $result | Should BeOfType 'Microsoft.PowerShell.Commands.FileHashInfo' + $result.Algorithm | Should Be "SHA256" + $result.Hash | Should Be "4A6DA9F1C0827143BB19FC4B0F2A8057BC1DF55F6D1F62FA3B917BA458E8F570" $result.Path | Should Be $testDocument } } diff --git a/test/powershell/engine/Basic/DefaultCommands.Tests.ps1 b/test/powershell/engine/Basic/DefaultCommands.Tests.ps1 index e2584780e70..d40a70b24ff 100644 --- a/test/powershell/engine/Basic/DefaultCommands.Tests.ps1 +++ b/test/powershell/engine/Basic/DefaultCommands.Tests.ps1 @@ -60,6 +60,7 @@ Describe "Verify approved aliases list" -Tags "CI" { "Alias", "gcm", "Get-Command", $($FullCLR -or $CoreWindows -or $CoreUnix), "ReadOnly", "" "Alias", "gcs", "Get-PSCallStack", $($FullCLR -or $CoreWindows -or $CoreUnix), "ReadOnly", "" "Alias", "gdr", "Get-PSDrive", $($FullCLR -or $CoreWindows -or $CoreUnix), "ReadOnly", "" +"Alias", "Get-FileHash", "Get-Hash", $( $CoreWindows -or $CoreUnix), "ReadOnly", "AllScope" "Alias", "ghy", "Get-History", $($FullCLR -or $CoreWindows -or $CoreUnix), "ReadOnly", "" "Alias", "gi", "Get-Item", $($FullCLR -or $CoreWindows -or $CoreUnix), "ReadOnly", "" "Alias", "gin", "Get-ComputerInfo", $($FullCLR -or $CoreWindows ), "", "" @@ -256,7 +257,7 @@ Describe "Verify approved aliases list" -Tags "CI" { "Cmdlet", "Get-EventLog", , $($FullCLR ) "Cmdlet", "Get-EventSubscriber", , $($FullCLR -or $CoreWindows -or $CoreUnix) "Cmdlet", "Get-ExecutionPolicy", , $($FullCLR -or $CoreWindows -or $CoreUnix) -"Cmdlet", "Get-FileHash", , $( $CoreWindows -or $CoreUnix) +"Cmdlet", "Get-Hash", , $( $CoreWindows -or $CoreUnix) "Cmdlet", "Get-FormatData", , $($FullCLR -or $CoreWindows -or $CoreUnix) "Cmdlet", "Get-Help", , $($FullCLR -or $CoreWindows -or $CoreUnix) "Cmdlet", "Get-History", , $($FullCLR -or $CoreWindows -or $CoreUnix) From 94a4c98e3d9bc0aad6a5ec2810acd762cdfec149 Mon Sep 17 00:00:00 2001 From: iSazonov Date: Tue, 25 Jul 2017 12:18:26 +0300 Subject: [PATCH 3/5] Add test for piping a path --- .../Microsoft.PowerShell.Utility/Get-Hash.Tests.ps1 | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Get-Hash.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Get-Hash.Tests.ps1 index 34790826c6a..9e16b04bce1 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Get-Hash.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Get-Hash.Tests.ps1 @@ -109,5 +109,14 @@ Describe "Get-Hash tests for files" -Tags "CI" { $result.Hash | Should Be "4A6DA9F1C0827143BB19FC4B0F2A8057BC1DF55F6D1F62FA3B917BA458E8F570" $result.Path | Should Be $testDocument } + + It "With '-Path': using a pipe" { + $result = Get-ChildItem $testDocument | Get-Hash + + $result | Should BeOfType 'Microsoft.PowerShell.Commands.FileHashInfo' + $result.Algorithm | Should Be "SHA256" + $result.Hash | Should Be "4A6DA9F1C0827143BB19FC4B0F2A8057BC1DF55F6D1F62FA3B917BA458E8F570" + $result.Path | Should Be $testDocument + } } } From e9a5583a0b379abbbf6265ca4110cab029d9642e Mon Sep 17 00:00:00 2001 From: Ilya Date: Sun, 13 Aug 2017 00:36:02 +0500 Subject: [PATCH 4/5] Address code review 1. Replace GetFileHashCommand with GetHashCommand 2. Exclude an exception 3. Fix tests. --- .../commands/utility/GetHash.cs | 35 +++++++------------ .../Get-Hash.Tests.ps1 | 6 ++-- 2 files changed, 16 insertions(+), 25 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetHash.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetHash.cs index 68149a4a670..0880b77ed4c 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetHash.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetHash.cs @@ -16,7 +16,7 @@ namespace Microsoft.PowerShell.Commands StreamParameterSet })] [OutputType(typeof(StringHashInfo), ParameterSetName = new[] { StringHashParameterSet })] - public class GetFileHashCommand : HashCmdletBase + public class GetHashCommand : HashCmdletBase { /// /// Path parameter @@ -124,27 +124,18 @@ protected override void ProcessRecord() { foreach (string str in InputString) { - try - { - //if (str == null) - //{ - // WriteStringHashInfo(Algorithm, string.Empty, string.Empty, Encoding); - // Exception exception = new Exception("Hash for 'null' string is 'null'", ex); - // WriteError(new ErrorRecord(exception, "GetHashInvalidData", ErrorCategory.InvalidData, null)); - //} - //else - //{ - byte[] bytehash = hasher.ComputeHash(EncodingConversion.Convert(this, Encoding).GetBytes(str)); - string hash = BitConverter.ToString(bytehash).Replace("-",""); - WriteStringHashInfo(Algorithm, hash, str, Encoding); - //} - } - catch (Exception ex) - { - WriteStringHashInfo(Algorithm, string.Empty, string.Empty, Encoding); - Exception exception = new Exception("Hash for 'null' string is 'null'", ex); - WriteError(new ErrorRecord(exception, "GetHashInvalidData", ErrorCategory.InvalidData, null)); - } + if (str == null) + { + WriteStringHashInfo(Algorithm, string.Empty, string.Empty, Encoding); + Exception exception = new Exception("Hash for 'null' string is 'null'"); + WriteError(new ErrorRecord(exception, "GetHashInvalidData", ErrorCategory.InvalidData, null)); + } + else + { + byte[] bytehash = hasher.ComputeHash(EncodingConversion.Convert(this, Encoding).GetBytes(str)); + string hash = BitConverter.ToString(bytehash).Replace("-",""); + WriteStringHashInfo(Algorithm, hash, str, Encoding); + } } } diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/Get-Hash.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/Get-Hash.Tests.ps1 index 9e16b04bce1..bff646605e0 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Utility/Get-Hash.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/Get-Hash.Tests.ps1 @@ -79,17 +79,17 @@ Describe "Get-Hash tests for files" -Tags "CI" { } It "Should be throw for wrong algorithm name" { - { Get-Hash $testDocument -Algorithm wrongAlgorithm } | ShouldBeErrorId "ParameterArgumentValidationError,Microsoft.PowerShell.Commands.GetFileHashCommand" + { Get-Hash $testDocument -Algorithm wrongAlgorithm } | ShouldBeErrorId "ParameterArgumentValidationError,Microsoft.PowerShell.Commands.GetHashCommand" } } Context "Paths tests" { It "With '-Path': no file exist" { - { Get-Hash -Path nofileexist.ttt -ErrorAction Stop } | ShouldBeErrorId "FileNotFound,Microsoft.PowerShell.Commands.GetFileHashCommand" + { Get-Hash -Path nofileexist.ttt -ErrorAction Stop } | ShouldBeErrorId "FileNotFound,Microsoft.PowerShell.Commands.GetHashCommand" } It "With '-LiteralPath': no file exist" { - { Get-Hash -LiteralPath nofileexist.ttt -ErrorAction Stop } | ShouldBeErrorId "FileNotFound,Microsoft.PowerShell.Commands.GetFileHashCommand" + { Get-Hash -LiteralPath nofileexist.ttt -ErrorAction Stop } | ShouldBeErrorId "FileNotFound,Microsoft.PowerShell.Commands.GetHashCommand" } It "With '-Path': file exist" { From 59c99961cdaefac419e5575ab8d07f8b38b000c7 Mon Sep 17 00:00:00 2001 From: Jason Shirk Date: Sun, 13 Aug 2017 08:55:27 -0700 Subject: [PATCH 5/5] Tabs to spaces --- .../commands/utility/GetHash.cs | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetHash.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetHash.cs index 0880b77ed4c..88f2f694486 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetHash.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/GetHash.cs @@ -124,18 +124,18 @@ protected override void ProcessRecord() { foreach (string str in InputString) { - if (str == null) - { - WriteStringHashInfo(Algorithm, string.Empty, string.Empty, Encoding); - Exception exception = new Exception("Hash for 'null' string is 'null'"); - WriteError(new ErrorRecord(exception, "GetHashInvalidData", ErrorCategory.InvalidData, null)); - } - else - { - byte[] bytehash = hasher.ComputeHash(EncodingConversion.Convert(this, Encoding).GetBytes(str)); - string hash = BitConverter.ToString(bytehash).Replace("-",""); - WriteStringHashInfo(Algorithm, hash, str, Encoding); - } + if (str == null) + { + WriteStringHashInfo(Algorithm, string.Empty, string.Empty, Encoding); + Exception exception = new Exception("Hash for 'null' string is 'null'"); + WriteError(new ErrorRecord(exception, "GetHashInvalidData", ErrorCategory.InvalidData, null)); + } + else + { + byte[] bytehash = hasher.ComputeHash(EncodingConversion.Convert(this, Encoding).GetBytes(str)); + string hash = BitConverter.ToString(bytehash).Replace("-",""); + WriteStringHashInfo(Algorithm, hash, str, Encoding); + } } }