使用invoke-restmethod发行Powershell POST数据

问题描述 投票:0回答:1

我目前正在尝试使用PowerShell创建POST请求。这是我的初始hashArray

$hashArrayOfStrings = @(
@{
    criteria    = '"platform" = "iOS" AND "connected_at" >= "now-1d" AND "client.connected" >= "now-1d" AND "apns" = true AND ( "version" STARTS WITH "1" OR "version" STARTS WITH "2" )'
    name        = "iOS"
    description = "Description1"
},
@{
    criteria    = '“platform” = “android” AND “connected_at” >= “now-1d” AND ( “client.connected” < “now-1d” OR “apns” = false ) AND ( “version” STARTS WITH “1” OR “version” STARTS WITH “2” )'
    name        = "name2"
    description = "Description2"
})

这是调用API的功能:

function Call-API {
 param ($ID, $criteria, $name, $description)
$url = "$($global:apiURL)?id=1"
$body =@{ criteria = $criteria; name = $name; description = $description; SpaceId = $ID; static = $false }
(($body | ConvertTo-Json) -replace '"', '\"')
    try {
    $results = Invoke-RestMethod -Uri $url -Headers $global:headers -Body $body -Method Post -ContentType "application/json"
        return $results.results
    }
    catch { Show-Error -errorInfo $_ }

然后我使用此代码调用该函数:

$hashArrayOfStrings | ForEach-Object {
                try {
                    Call-API -ID $ID -criteria $_.criteria -name $_.name -description $_.description
                }
                catch { Show-Error -errorInfo $_ }
            }

使用cURL测试有效:

curl -X POST -H 'Authorization: Basic xxxxxxxxxxxx' -H "Content-Type: application/json" 'https://apiurl.com?Id=1' --data-binary '{"name": "test","description": "test description.","SpaceId": 1,"static": false,"criteria": "(\"platform\"=\"Android\") AND \"apns\"=false"}'

并且使用请求对python进行了一些测试,并且也可以使用。

我认为问题在于转义字符。该API在POST数据中需要一个字符串。

我已经在每个双引号前面加上`进行了测试,结果相同:

Microsoft.PowerShell.Commands.HttpResponseException: Response status code does not indicate success: 405 (Method Not Allowed).
   at System.Management.Automation.MshCommandRuntime.ThrowTerminatingError(ErrorRecord errorRecord)
powershell http-post
1个回答
0
投票

注意:首先,我无法测试解决方案,因为我无法将查询传递给类似的API,但是经过一些测试,以下似乎是您的问题。

在第二个块Call-API功能的第5行中,您使用-replace来转义"

PowerShell中的ConvertTo-Json函数已经转义了字符串中必需的字符。另请注意,PowerShell将未转换的JSON对象作为字符串处理,因此执行-replace '"', '\"'的结果如下:

(@{name = '"name"'} | ConvertTo-Json) -replace '"', '\"'

输出:

{\"name\": \"\\"name\\"\"}

这是无效的json。删除-replace功能输出:

{"name": "\"name\""}

这是有效的json

除此之外,您可以使用PowerShell splatting使您的功能更易于阅读/管理。同样,如果您确定传递的哈希表与该函数相同,则将其作为一个整体传递并调用函数中的属性。

$hashArrayOfStrings = @(
    @{
        criteria    = '"platform" = "iOS" AND "connected_at" >= "now-1d" AND "client.connected" >= "now-1d" AND "apns" = true AND ( "version" STARTS WITH "1" OR "version" STARTS WITH "2" )'
        name        = "iOS"
        description = "Description1"
    },
    @{
        criteria    = '“platform” = “android” AND “connected_at” >= “now-1d” AND ( “client.connected” < “now-1d” OR “apns” = false ) AND ( “version” STARTS WITH “1” OR “version” STARTS WITH “2” )'
        name        = "name2"
        description = "Description2"
    }
)

function Call-API($Id, $Object){
    $params = @{
        Uri     = "$($Global:apiURL)?id=1"
        Headers = $global:headers
        Method  = "POST"
        ContentType = "application/json" 
        Body    = @{
            SpaceId         = $Id
            static          = $false
            criteria        = $Object.critera
            name            = $Object.name
            $description    = $Object.description
        } | ConvertTo-Json
    }

    try{
        $Respose = Invoke-RestMethod @params
        return $Respose.results
    } catch {
        throw $_
    }
}

foreach($object in $hashArrayOfStrings){
    Call-API -Id $id -Object $object
    #you dont need a additional try catch here as this is embedded in your Call API function
}
© www.soinside.com 2019 - 2024. All rights reserved.