Reputation: 247
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:
encasing the whole thing in single quotes
replacing each /" (forward slash + double quote) with `" (backtick + double quote)
adding all the arguments to a here-string variable
variations of above
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
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
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
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