24

This curl command works as desired:

curl -H "X-Api-Key:j65k423lj4k2l3fds" `
     -X PUT `
     -d "alerts_enabled=true" `
        https://some/working/file.xml

How can I recreate this natively in PS with Invoke-WebRequest? I've tried

Invoke-WebRequest -Headers @{"X-Api-Key" = "j65k423lj4k2l3fds"} `
                  -Method PUT `
                  -Body "alerts_enabled=true" `
                  -Uri https://some/working/file.xml

I've also tried making objects for all the params (e.g. $headers = @{"X-Api-Key" = "Key:j65k423lj4k2l3fds"} and passing -Headers $headers).

Thanks

0

4 Answers 4

26

Try adding the parameter -ContentType e.g.:

Invoke-WebRequest -Headers @{"X-Api-Key" = "j65k423lj4k2l3fds"} -Method PUT `
                  -Body "alerts_enabled=true" -Uri https://some/working/file.xml `
                  -ContentType application/x-www-form-urlencoded

That results in a request that looks like this (from Fiddler):

PUT http://some/working/file.xml HTTP/1.1
X-Api-Key: j65k423lj4k2l3fds
User-Agent: Mozilla/5.0 (Windows NT; Windows NT 6.2; en-US) WindowsPowerShell/5.0.9701.0
Content-Type: application/x-www-form-urlencoded
Host: some
Content-Length: 19
Expect: 100-continue

alerts_enabled=true

For testing, I changed the URL from https to http. If that doesn't work, go download Fiddler and inspect the RAW request when curl is used to see what is different.

Sign up to request clarification or add additional context in comments.

1 Comment

When are quotes needed - as in the body and when not as in -uri? My curl I want to convert to ps starts with curl -s -k -m 5 so I have to find out the flag names as methods in ps. As body - -d - I have a xml file, maybe I can put that in another file to have it well formatted.
12

got it to work natively using invoke-webrequest. powershell guru here at work helped me out. Switched to the New Relic API version 2 (available at https://rpm.newrelic.com/api/explore), which uses JSON instead of xml, and made some sytax tweaks.

$json = @"{"alert_policy":[{"enabled":"true"}]"@

$headers = @{}
$headers["X-Api-Key"] = "j65k423lj4k2l3fds"

Invoke-WebRequest -Uri "https://some/working/file.json" -Body $json -ContentType "application/json" -Headers $headers -Method Post

1 Comment

although the code above was producing a 200, and some response json, it was not toggling the setting in New Relic. I was POSTing instead of PUTing...so pay attention to that.
4

This works for me in Powershell using the curl alias to Invoke-WebRequest...

 curl -H @{"X-Api-Key" = "j65k423lj4k2l3fds"} -Method PUT 'https://some/working/file.xml'

Comments

0

The following was developed to capture the HTTP Response (if you use the CuRL argument, -w "%{http_code}") , STD Out, STD Err and the Curl Exit Code. It will also detect the received response text encoding and convert it to UTF-8.

#region CuRL
#region Default_Values
    $CurlPath = "C:\Windows\System32"; ## Where CuRL.exe is installed; by default it uses the built-in Windows version
#endregion Default_Values
function Convert-StringEncoding {
    [CmdletBinding()]
    param(
         [Parameter(Mandatory=$true)][AllowNull()][AllowEmptyString()][String]$string,
         [Parameter(Mandatory=$true)][System.Text.Encoding]$inputEncoding,
         [System.Text.Encoding]$outputEncoding = [System.Text.Encoding]::UTF8
    )    

    [string]$ret = $string;
    if (![string]::IsNullOrWhiteSpace($string)) {
        if ($inputEncoding -ne $outputEncoding) {
            $bytesArr = $inputEncoding.getbytes($string);
            $ret = $outputEncoding.GetString($bytesArr);
        }
    }
    return $ret;
}

function Invoke-CuRL {
    PARAM (
        [Parameter(Mandatory=$TRUE,ValuefromPipeline=$True)][string]$Arguments,
        [switch]$ShowAll,
        [switch]$NoConvertStdOutFromJSON,
        [switch]$UseInvokeExpression,
        [switch]$HideExitCodeError
    )
    Process {
        $out = @{}
        $out = [hashtable]::Synchronized($out);

        if ($UseInvokeExpression.IsPresent -and !$ShowAll.IsPresent) {
            ### The less informative way; equivalent to just STDOUT.  Note: not setup for using parameter, -w '%{http_code}'
            $JSON = Invoke-Expression "&`"$CurlPath\curl.exe`" $Arguments ";
            if (![string]::IsNullOrWhiteSpace($JSON) -and !$NoConvertStdOutFromJSON.IsPresent) {
                $ret = $JSON | ConvertFrom-Json -ErrorAction SilentlyContinue -WarningAction SilentlyContinue;
            }
        } else {
            [System.Diagnostics.ProcessStartInfo]$pinfo = [System.Diagnostics.ProcessStartInfo]::new("$CurlPath\curl.exe");
            $pinfo.Arguments = $Arguments -replace "'", '"'; ##ProcessInfo hates single quotes##
            $pinfo.RedirectStandardError = $true;
            $pinfo.RedirectStandardOutput = $true;
            $pinfo.UseShellExecute = $tru;
            $pinfo.CreateNoWindow = $true;
            $pinfo.Verb = "open";
            $pinfo.LoadUserProfile = $true;
            [System.Diagnostics.Process]$p = [System.Diagnostics.Process]::new();
            $p.StartInfo = $pinfo;          
            try {
                if ($p.Start()) { 
                    $soe = $p.StandardOutput.CurrentEncoding;
                    $so = $p.StandardOutput.ReadToEnd();
                    $see = $p.StandardError.CurrentEncoding;
                    $se = $p.StandardError.ReadToEnd();
                    $out["exitcode"] = $p.ExitCode;
                    $p.WaitForExit();
                    $out["stdout"] = Convert-StringEncoding -string $so -inputEncoding $soe; #convert to UTF-8
                    $out["stderr"] = Convert-StringEncoding -string $se -inputEncoding $see; #convert to UTF-8
                }
                if ($Arguments -match 'http_code') { #REST API Exit Code from parameter, -w `"%{http_code}`"
                    if ($out["stdout"] -match '\d{1,3}$') {
                        $out["http_code"] = $Matches[0];
                        $out["stdout"] = $out["stdout"].Substring(0, $out["stdout"].Length - $Matches[0].Length)
                    }
                } 
                if (![string]::IsNullOrWhiteSpace($out["stdout"]) -and !$NoConvertStdOutFromJSON.IsPresent -and $out["stdout"] -match '\{.*\}' ) {
                    $out["stdout"] = $out["stdout"]  | ConvertFrom-Json -ErrorAction SilentlyContinue -WarningAction SilentlyContinue;
                }
                if ($ShowAll.IsPresent) {
                    $ret = [pscustomobject]$out;
                } else {
                    $ret = $out["stdout"];
                }
                if ($out["exitcode"] -ne 0 -and !$HideExitCodeError.IsPresent) {
                    Write-Host "`nWARNING: CuRL Exit Code $($out["exitcode"])`n" -ForegroundColor DarkYellow;
                }
                if ($out["http_code"]) {
                    switch -Regex ($out["http_code"]) {
                        "200|201|204|302|401|404" {} #OK or nothing bad
                        400 { #Bad Request
                            $RepErr = $TRUE;
                            $ret = [pscustomobject]$out;
                            if ($ret.stdout) { if ($ret.stdout.meta) { if ($ret.stdout.meta.message -match 'already been restored') { #Friendlier message
                                Write-Host "`n Info $_`: $($ret.stdout.meta.message) `n" -ForegroundColor Cyan; 
                                $RepErr = $false;
                            }}}
                            if ($RepErr) {
                                Write-Host "`n ERROR $_`: Bad Request; check your REST API syntax. `n" -ForegroundColor Red;
                            } 
                        } 
                        405 { Write-Host "`n ERROR $_`: Method not allowed. `n CuRL Arguments: $Arguments `n" -ForegroundColor Red; $ret = [pscustomobject]$out;} #Method not allowed
                        429 { #Too many requests; try again
                            Write-Host "`n INFO $_`: Too many REST API requests; waiting 2 seconds and trying again. `n" -ForegroundColor Cyan; 
                            Start-Sleep -Seconds 2;
                            $ret = Invoke-CuRL -Arguments $Arguments -ShowAll:$ShowAll -NoConvertStdOutFromJSON:$NoConvertStdOutFromJSON -UseInvokeExpression:$UseInvokeExpression -HideExitCodeError:$HideExitCodeError;
                        } 
                        default {Write-Host "`n ERROR $_`: Uncommon REST API Status Code: $Code. `n See https://restfulapi.net/http-status-codes/ for more information. `n" -ForegroundColor Red; $ret = [pscustomobject]$out;}
                    }
                }
            } catch {
                Write-Host "`nERROR: Invoke-CuRL: `n $_ `n $($_.ScriptStackTrace)`n" -ForegroundColor Red;
                $ret = $null;
            }
        } 
        return $ret;
    }
}
#endregion CuRL

Comments

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.