Azure 无法使用PowerShell发布Cosmos DB存储过程

Azure 无法使用PowerShell发布Cosmos DB存储过程,azure,powershell,azure-cosmosdb,Azure,Powershell,Azure Cosmosdb,我正在尝试将存储过程部署到Azure Cosmos DB帐户内的集合,作为我在Azure DevOps中部署管道的一部分。由于安全原因,我必须使用RESTAPI(无法使用或导入PowerShell模块来执行此操作) 我使用的构建代理是内部部署代理。同样,出于安全原因 为了生成授权令牌以发出请求,我有以下PowerShell函数: Add-Type -AssemblyName System.Web # Generate Authorization Key for REST calls Funct

我正在尝试将存储过程部署到Azure Cosmos DB帐户内的集合,作为我在Azure DevOps中部署管道的一部分。由于安全原因,我必须使用RESTAPI(无法使用或导入PowerShell模块来执行此操作)

我使用的构建代理是内部部署代理。同样,出于安全原因

为了生成授权令牌以发出请求,我有以下PowerShell函数:

Add-Type -AssemblyName System.Web

# Generate Authorization Key for REST calls
Function Generate-MasterKeyAuthorizationSignature
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$true)][String]$verb,
        [Parameter(Mandatory=$true)][String]$resourceLink,
        [Parameter(Mandatory=$true)][String]$resourceType,
        [Parameter(Mandatory=$true)][String]$dateTime,
        [Parameter(Mandatory=$true)][String]$key,
        [Parameter(Mandatory=$true)][String]$keyType,
        [Parameter(Mandatory=$true)][String]$tokenVersion
    )

    $hmacSha256 = New-Object System.Security.Cryptography.HMACSHA256
    $hmacSha256.Key = [System.Convert]::FromBase64String($key)

    $payLoad = "$($verb.ToLowerInvariant())`n$($resourceType.ToLowerInvariant())`n$resourceLink`n$($dateTime.ToLowerInvariant())`n`n"
    $hashPayLoad = $hmacSha256.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($payLoad))
    $signature = [System.Convert]::ToBase64String($hashPayLoad);

    [System.Web.HttpUtility]::UrlEncode("type=$keyType&ver=$tokenVersion&sig=$signature")
}
然后,我在POST函数中调用此函数,该函数用于将存储过程发布到Azure Cosmos DB:

Function Post-StoredProcToCosmosDb
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory=$true)][String]$EndPoint,
        [Parameter(Mandatory=$true)][String]$DataBaseId,
        [Parameter(Mandatory=$true)][String]$CollectionId,
        [Parameter(Mandatory=$true)][String]$MasterKey,
        [Parameter(Mandatory=$true)][String]$JSON
    )

    $Verb = 'Post'
    $ResourceType = "sprocs"
    $ResourceLink = "dbs/$DataBaseId/colls/$CollectionId"

    $dateTime = [DateTime]::UtcNow.ToString("r")
    $authHeader = Generate-MasterKeyAuthorizationSignature -verb $Verb -resourceLink $ResourceLink -resourceType $ResourceType -key $MasterKey -keyType "master" -tokenVersion "1.0" -dateTime $dateTime
    $header = @{authorization=$authHeader;"x-ms-version"="2017-02-22";"x-ms-date"=$dateTime;"xs-ms-session-token"="28"}
    $contentType = "application/json"
    $queryUri = "$EndPoint$ResourceLink/sprocs"

    $result = Invoke-RestMethod -Headers $header -Method $Verb -ContentType $contentType -Uri $queryUri  -Body $JSON

    return $result.statuscode
}
从中可以看出,我需要在主体中以字符串形式传递存储过程,因此我将存储过程的路径设置为一个变量,如下所示:

$HelloWorld = Get-Content -Path '.\Databases\MyCosmosDB\MyCosmosCollection\Stored Procedures\HelloWorld.js' | Out-String
然后我调用我的POST函数,如下所示:

Post-StoredProcToCosmosDb -EndPoint $env:COSMOSENDPOINT -DataBaseId $env:MYCOSMOSDB -CollectionId $MyCollection -MasterKey $env:MASTERKEY -JSON $HelloWorld
但是,当我运行任务时,会出现以下错误:

调用RestMethod:远程服务器返回错误:(400)请求错误 在D:_workAzure\r12\a_Cosmos\Deployment\scripts\poststoredprocesses.ps1:61 char:15
$result=Invoke RestMethod-Headers$header-Method$Verb-Content…
+CategoryInfo:InvalidOperation:(System.Net.HttpWebRequest:HttpWebRequest)[调用RestMethod],WebException
+FullyQualifiedErrorId:WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

我遵循了存储过程的中概述的示例请求体

以下是您的信息的外观:

"function () {\r\n    var context = getContext();\r\n    var response = context.getResponse();\r\n\r\n    response.setBody(\"Hello, World\");\r\n}"
我对PowerShell相当陌生,所以我想知道我哪里出了问题。我已经尝试将
contentType
同时设置为
application/json
application/query+json
,但除此之外,我不确定哪里出了问题


如果有人能就此提供指导,我将不胜感激。

因此,请求主体是错误的。应该是这样的:

{
    "body":"function HelloWorld() {\r\n    var context = getContext();\r\n    var response = context.getResponse();\r\nresponse.setBody(\"Hello, World\");\r\n}",
    "id": "HelloWorld"
}
这是可接受的存储过程请求主体。因此,我应该将$HelloWorld变量设置为:

$HelloWorld = Get-Content -Path '.\Databases\MyCosmosDB\MyCosmosCollection\Stored Procedures\HelloWorld.json' | Out-String
希望有一天我的愚蠢能帮助别人:/