0
votes

I have an azure function app in PowerShell, in this azure function app, i am calling azure table api to update the data in azure table. (same code is working fine in powershell console) getting error in azure function app: "The cmdlet cannot run because the -ContentType parameter is not a valid Content-Type header. Specify a valid Content-Type for -ContentType, then retry."

script:

$hash = "045tgh4fd"
$Id = "12345"
$StorageAccountName = "mystaccname"
$resourceGroup = "myrgname"

$StorageAccountAccessKey = "mystacckey";
try {
    #Add data in table.
   
    $entity = @{"Id" = $Id; "Hash" = $hash; "SoftDeleted" = "Y"};
    #$body = $entity | ConvertTo-Json

    $RFC1123TimeUTC  = [datetime]::UtcNow.ToString("R")       
    Write-Verbose "Time stamp for authorization header signature: '$RFC1123TimeUTC'"
    $RequestHeaders = @{
      'x-ms-version' = '2015-04-05'
      'x-ms-date' = $RFC1123TimeUTC
      'Accept-Charset' = 'UTF-8'
      'DataServiceVersion' = '1.0;NetFx'
      'MaxDataServiceVersion' = '3.0;NetFx'
    }

    $urlPath = "mytable(PartitionKey='12345',RowKey='rw12345')";
    $TableStorageUri = "https://mystacc.table.core.windows.net/mytable(PartitionKey='12345',RowKey='rw12345')";

    [Byte[]] $StorageAccountAccessKeyByteArray = [System.Convert]::FromBase64String($StorageAccountAccessKey)
    $hasher = New-Object System.Security.Cryptography.HMACSHA256
    $hasher.key = $StorageAccountAccessKeyByteArray
    $strToSign = $RFC1123TimeUTC + "`n" + "/" + $StorageAccountName + "/" + $UrlPath
    $AuthKey = [System.Convert]::ToBase64String($hasher.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($strToSign)))
    $SharedKeyLiteAuthorizationHeader = "SharedKeyLite $StorageAccountName`:$AuthKey"

    $RequestHeaders.Add('Accept', 'application/json;odata=nometadata')
    $RequestHeaders.Add('Authorization', $SharedKeyLiteAuthorizationHeader)
    $RequestHeaders.Add('If-Match', "*")
    $RequestBody = ConvertTo-Json -InputObject $entity -Depth 2
    $ContentType = "application/json"
    $HttpMethod = "Put"

    $RequestHeaders.Add("Content-Length", $requestBody.Length)
    $UpdateRequest = Invoke-WebRequest -UseBasicParsing -Uri $TableStorageUri -Method $HttpMethod -Body $RequestBody -ContentType $ContentType -Headers $RequestHeaders
    
    Write-Host "Updated Successfully"
}
catch
{
    Write-Host $_
}

tried this below script, this script also working in local PS console but not working in azure function app:

try {
    $entity = @{"Id" = "12345"; "hash" = "34f45gfh"; "SoftDeleted" = "N"};
    $body = $entity | ConvertTo-Json

    $version = "2017-04-17"
    $resource = "tableName(PartitionKey='myPartitionKey',RowKey='myRowkey')"
    $table_url = "https://StorageAccountName.table.core.windows.net/$resource"
    $GMTTime = (Get-Date).ToUniversalTime().toString('R')
    $stringToSign = "$GMTTime`n/StorageAccountName/$resource"

    $hmacsha = New-Object System.Security.Cryptography.HMACSHA256
    $hmacsha.key = [Convert]::FromBase64String("storageaccoutkey")
    $signature = $hmacsha.ComputeHash([Text.Encoding]::UTF8.GetBytes($stringToSign))
    $signature = [Convert]::ToBase64String($signature)
   
    $headers = @{
        'x-ms-date'      = $GMTTime
        Authorization    = "SharedKeyLite " + $StorageAccountName + ":" + $signature
        "x-ms-version"   = $version
        Accept           = "application/json;odata=minimalmetadata"
        'If-Match'       = "*"
        'Content-Length' = $body.length
    }
    $response = Invoke-RestMethod -Method MERGE -Uri $table_url -Headers $headers -Body $body -ContentType "application/json;odata=minimalmetadata"
    Write-Host "Updated Successfully"
}
catch
{
    Write-Host $_
}
1
Please try by removing Content-Length header from your request headers. - Gaurav Mantri
It worked after removing Content-Length. Thanks @GauravMantri - Arvind Singh
Awesome! I have added an answer giving more details about the cause of the problem and why removing Content-Length header solved the problem. HTH. - Gaurav Mantri

1 Answers

1
votes

The reason you're getting this error has nothing to do with Content-Type request header :). The real culprit is same header getting added multiple times (Content-Length in your case).

Essentially what is happening is that you're manually adding Content-Length header and Invoke-RestMethod is also adding Content-Length request header. Because this header is added multiple times, you're getting this error. Once you removed Content-Length header from your request, the issue was solved because now this header is added just once.

Please see this issue on Github for more details: https://github.com/PowerShell/PowerShell/issues/12500#issuecomment-777757252. This is where I found this solution.