0

I want to execute a function in PowerShell from Windows CMD. Basically the requirement is to calculate the hash of a string, since Windows batch/cmd does not provide the functionality to generate a hash of a string, I've to use PowerShell.

I don't want to run a PowerShell script or put the function in a ps script as by doing so I have to bypass the Windows PowerShell security policy.

Below is the code which I am running in Hash.cmd. The code, when executed in PowerShell, runs perfectly fine.

@echo off
powershell -Command "& { Function Get-Hash([String] $String) { $StringBuilder = New-Object System.Text.StringBuilder;   [System.Security.Cryptography.HashAlgorithm]::Create("sha1").ComputeHash([System.Text.Encoding]::UTF8.GetBytes($String))|%{  [Void]$StringBuilder.Append($_.ToString("x2")); }; $StringBuilder.ToString(); }; $res=Get-Hash "Hello world"; echo $res; }"

But this is resulting in error on CMD as below:

At line:1 char:153
+ ... lder;   [System.Security.Cryptography.HashAlgorithm]::Create(sha1).Co ...
+                                                                  ~
Missing ')' in method call.
At line:1 char:153
+ ... ;   [System.Security.Cryptography.HashAlgorithm]::Create(sha1).Comput ...
+                                                              ~~~~
Unexpected token 'sha1' in expression or statement.
At line:1 char:41
+ & { Function Get-Hash([String] $String) { $StringBuilder = New-Object ...
+                                         ~
Missing closing '}' in statement block or type definition.
At line:1 char:3
+ & { Function Get-Hash([String] $String) { $StringBuilder = New-Object ...
+   ~
Missing closing '}' in statement block or type definition.
At line:1 char:157
+ ...    [System.Security.Cryptography.HashAlgorithm]::Create(sha1).Compute ...
+                                                                 ~
Unexpected token ')' in expression or statement.
At line:1 char:262
+ ... etBytes($String))|{  [Void]$StringBuilder.Append($_.ToString(x2)); }; ...
+                                                                  ~
Missing ')' in method call.
At line:1 char:262
---- TRUNCATED-----
2
  • 3
    You're having quoting issues - the whole powershell command is wrapped in double quotes, so when you use these within the powershell code it breaks. Change the double quotes "sha1" / "x2" / "Hello world" to single quotes. Commented Feb 6, 2019 at 11:24
  • Do no use double quotes inside a double quoted string. Commented Feb 6, 2019 at 11:26

2 Answers 2

4

You're having quoting issues because you're using double quotes within double quotes which breaks the quoting.

As the strings in your code that are double quoted don't require expansion (see about_quoting_rules), you can just change the double quotes "sha1" / "x2" / "Hello world" to single quotes eg 'sha1'


EDIT: Working code for me:

powershell -command "& { Function Get-Hash([String]$String) { $StringBuilder = New-Object System.Text.StringBuilder;   [System.Security.Cryptography.HashAlgorithm]::Create('sha1').ComputeHash([System.Text.Encoding]::UTF8.GetBytes($String))|%{  [Void]$StringBuilder.Append($_.ToString('X2')); }; $StringBuilder.ToString(); }; $res=Get-Hash 'Hello world'; echo $res; }"
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! I changed the "sha1" / "x2" / "Hello world" to 'sha1' / 'x2' / 'Hello world'. Now i am getting the below error At line:1 char:223 + ... $String)) | { [Void]$StringBuilder.Append($_.ToString('x2')); }; $St ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Expressions are only allowed as the first element of a pipeline. + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException + FullyQualifiedErrorId : ExpressionsMustBeFirstInPipeline
I don't get that error, it works for me and returns the hash - I've included my code but it only the quotes that have changed...
0

The issue was that I was using % in place for Foreach-Object

Below is the correct cmd script

@echo off
powershell -command "& { Function Get-Hash([String] $String) { $StringBuilder =  New-Object System.Text.StringBuilder;   [System.Security.Cryptography.HashAlgorithm]::Create('sha1').ComputeHash([System.Text.Encoding]::UTF8.GetBytes($String)) | Foreach-object {  [Void]$StringBuilder.Append($_.ToString('x2')); }; $StringBuilder.ToString(); }; $hash=Get-Hash 'Hello World'; echo $hash; }"

1 Comment

% is a built-in alias for ForEach-Object, so that can't be the problem. powershell -c "1, 2 | % { $_ + 1 }" works just fine, for instance.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.