Jon
Jon

Reputation: 247

calls to cmd from powershell not parsing correctly?

I am trying to run cURL.exe from powershell as part of a larger script to create various user accounts as new individuals are onboarded. (I cannot use invoke-method or invoke-webrequest because the header parameter wont accept a string)

The issue is that I can run it from a cmd window perfectly but I cannot seem to make the same thing run from powershell:

curl.exe -H "Authorization: {\"apiKey\":\"ResetAPIKey,\"username\":\"admin\"}"  -d "username=someUserName&email=somebody@domain.com&firstName=Joe&lastName=Friday"  "http://URL:8080/v1/users/create"

This runs just fine from cmd but when attempting to run from powershell, I get errors like 'url not found' or 'That path/method is not supported'

Additional format attempts:

I would assume I can write it to a .bat file and then run that from powershell but I'd rather not be forced to do that if possible

Upvotes: 1

Views: 1431

Answers (3)

user4003407
user4003407

Reputation: 22132

Passing complex command line to native application from PowerShell can be tricky. PowerShell can add extra quotes in some cases. Although, rules for this are not that complex, but them are not well (if at all) documented, and also there is some substantial changes in that rules in v2-v4 vs v5. IMHO, using stop parsing operator --%, as @Matt offered, is the best approach, in case you targeting on v3+.

Stop parsing operator does not limit you to use literal strings only. You still can use variables with it. That operator expand environment variables in CMD syntax: %VariableName%. So you can assign required values to some environment variables and use them in command line:

$Env:Env_UserName='someUserName'
$Env:Env_Email='somebody@domain.com'
$Env:Env_FirstName='Joe'
$Env:Env_LastName='Friday'
curl.exe --% -H "Authorization: {\"apiKey\":\"ResetAPIKey,\"username\":\"admin\"}"  -d "username=%Env_UserName%&email=%Env_Email%&firstName=%Env_FirstName%&lastName=%Env_LastName%"  "http://URL:8080/v1/users/create"

Other variant will be to generate full arguments line, you want to pass to native application, and than pass it in single environment variable:

$Arguments=...
$Env:Env_Arguments=$Arguments
curl.exe --% %Env_Arguments%

Upvotes: 2

E.Z. Hart
E.Z. Hart

Reputation: 5757

Matt's answer with the call operator looks like it should work, but if it's not there's a similar alternative I've had good luck with before. Instead of passing your arguments as a string, you can pass them as an array and PowerShell will handle them correctly. In your case, it'd look something like this:

$arguments = @("-H", 'Authorization: {\"apiKey\":\"ResetAPIKey,\"username\":\"admin\"}', "-d", '"username=someUserName&email=somebody@domain.com&firstName=Joe&lastName=Friday"', 'http://URL:8080/v1/users/create')

& "curl.exe" $arguments

Upvotes: 1

Matt
Matt

Reputation: 46730

The stop parsing parameter is a good choice for this type of thing.

The stop-parsing symbol (--%), introduced in Windows PowerShell 3.0, directs Windows PowerShell to refrain from interpreting input as Windows PowerShell commands or expressions.

In your case though you need something a little different as you want variables in the mix that need to be resolved.

I figured there would be a dupe for this. Most of those answer are about converting curl.exe to something like Invoke-WebRequest which is something you should look into. In this case, if you have dynamic content use the call operator like this.

$arguments = "-H ""Authorization: {\""apiKey\"":\""ResetAPIKey,\""username\"":\""admin\""}""  -d ""username=someUserName&email=somebody@domain.com&firstName=Joe&lastName=Friday""  ""http://URL:8080/v1/users/create"""
&"curl.exe" $arguments

Noticed I doubled up the inner quotes on the string. If you look at the variable after it would display properly. Now you should be able to make changes.

Upvotes: 2

Related Questions