0

The following curl command works fine in cmd:

curl -L -c ./cookie -b ./cookie -X POST -H "Accept: application/json" -s -d "{\"accountId\":\"123456789\",\"partition\":\"abc\",\"duration\":1234}" https://testabc.com

When I try to run the same from PowerShell, I get the -c is ambiguous error. I tried replacing -c with SessionVariable, but then I start getting the following error:

Invoke-WebRequest : Missing an argument for parameter 'SessionVariable'. Specify a parameter of type 'System.String' and try again.

8
  • So you would like everyone to guess on the powershell code you used? Commented Apr 12, 2021 at 2:25
  • I used the same script in powershell Commented Apr 12, 2021 at 2:34
  • PowerShell converted it to Invoke-WebRequest. Commented Apr 12, 2021 at 2:34
  • 1
    Yep. Curl is an alias of Invoke-WebRequest. So you use curl.exe. Commented Apr 12, 2021 at 2:36
  • Shouldn't it work as it is in PowerShell then? Do I need to make any modifications? Commented Apr 12, 2021 at 2:49

1 Answer 1

1

You have several solutions to execute the correct curl binary:

  • Run curl.exe instead of curl. This is similar to why where works in cmd but in PowerShell you must run where.exe because where is an alias to Where-Object
  • Remove the curl alias by running Remove-Alias curl. You can put this in the profile to remove it by default
  • Install PowerShell Core and use it instead

That's because in the past curl was an alias of Invoke-WebRequest along with wget

PS C:\> Get-Alias -Definition Invoke-WebRequest

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           curl -> Invoke-WebRequest
Alias           iwr -> Invoke-WebRequest
Alias           wget -> Invoke-WebRequest

When MS added tar.exe and curl.exe to Windows 10 that causes some confusion since now running curl will invoke the alias instead of the executable (that's easy to understand since an alias will have higher priority just like in bash). In PowerShell core (i.e. version 6.0+) those aliases have been removed. See remove curl and wget aliases

PS C:\> Get-Alias -Definition Invoke-WebRequest

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           iwr -> Invoke-WebRequest

Update:

You must also modify your quotes because PowerShell has different quoting rules which is more similar to bash and is more standardized and much better than the messy one in cmd:

curl -L -c ./cookie -b ./cookie -X POST -H "Accept: application/json" -s -d '{"accountId":"123456789","partition":"abc","duration":1234}' https://testabc.com

Update 2:

I tried capturing the command line passed to curl.exe with sysmon and in cmd it's like this

"C:\WINDOWS\system32\curl.exe" -L -c ./cookie -b ./cookie -X POST -H "Accept: application/json" -s -d "{\"accountId\":\"123456789\",\"partition\":\"abc\",\"duration\":1234}" https://testabc.com

while in PowerShell it's like this

"C:\WINDOWS\system32\curl.exe" -L -c ./cookie -b ./cookie -X POST -H "Accept: application/json" -s -d {"accountId":"123456789","partition":"abc","duration":1234} https://testabc.com

Notice the difference in the json string. So it seems that curl.exe splits arguments itself and expects the raw \ escape characters in the parameters to tokenize the arguments properly. To do that you can wrap the whole json string into 'single quotes' like this

curl -L -c ./cookie -b ./cookie -X POST -H "Accept: application/json" -s -d '"{\"accountId\":\"123456789\",\"partition\":\"abc\",\"duration\":1234}"' https://testabc.com

or just pass verbatim arguments by adding the stop-parsing symbol --% after curl.exe to force PowerShell to not use its parsing rules and pass the whole string to the executable

curl.exe --% -L -c ./cookie -b ./cookie -X POST -H "Accept: application/json" -s -d "{\"accountId\":\"123456789\",\"partition\":\"abc\",\"duration\":1234}" https://testabc.com
Sign up to request clarification or add additional context in comments.

4 Comments

I installed PowerShell core and tried Remove-Alias curl. I got this error: Remove-Alias: This command cannot find a matching alias because an alias with the name 'curl' does not exist. This is expected as per your comments. Then I tried executed the same my original curl command with curl.exe and got null again.
@PKJ you must also change the command because backslash isn't an escape character in powershell. See my edit
I just tried with your suggestion and its still giving me null. curl.exe -L -c ./cookie -b ./cookie -X POST -H "Accept: application/json" -s -d '{"accountId":"123456789","part":"test","duration":1234}' https://testabc.com/abc
@PKJ see my latest update. You need to pass the backslashes to curl.exe

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.