jsonpowershellssisinvoke-restmethod

PowerShell Invoke-RestMethod gives an error after password change


I have a PowerShell script for calling an API. Currently it looks like this:

param( [string]$resultFile, [string]$from, [string]$to)

try {
    $headers = @{'api-key' = '763bcb3d-7b62-4075-877e-03a7cdfbbb4d'}

    $url = 'https://******?query={ calendar(where: {
        and: { from: { gte: "' + $from + '" }, to: { lte: "' + $to + '" } } } )
        {
            concerned
            {
                username
                regime
            }
            id
            status
            from
            to  
            primaryType
            secondaryType    
        }
    }'

    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
    Invoke-RestMethod -Uri $url -Method Get -Headers $headers -OutFile $resultFile
}
catch {
    write-output $PSItem.ToString()
    exit 1
}

Which works fine. However, increased security means that I can nolonger have a permanent API key and it will have to be replaced every six months. Rather than modifying my script every time, I would rather put the key in the SSIS package configuration and just change that. Now my script looks like:

param( [string]$resultFile, [string]$from, [string]$to, [string]$ApiKey)

try {
    $headers = @{'api-key' = '$ApiKey'}

    $url = 'https://******?query={ calendar(where: {
        and: { from: { gte: "' + $from + '" }, to: { lte: "' + $to + '" } } } )
        {
            concerned
            {
                username
                regime
            }
            id
            status
            from
            to  
            primaryType
            secondaryType    
        }
    }'

    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
    Invoke-RestMethod -Uri $url -Method Get -Headers $headers -OutFile $resultFile
}
catch {
    write-output $PSItem.ToString()
    exit 1
}

I was not expecting any problems as it was just the source of the API key that I changed from being hard coded to being a parameter but I got this error message:

E:\temp\hrnet.ps1 : The remote server returned an error: (500) Internal Server Error.
At line:1 char:1
+ E:\temp\hrnet.ps1 E:\temp\HRNet.json 2024-04-15 2024-06-10 acb59383-a ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,hrnet.ps1

I have looked at the parameters and everything looks good and I just can't figure out what is going wrong.

If I chnge it back then it works fine again so I am wondering if it is something to do with the character set of the parameters but, honestly, I'm out of ideas on what is the problem and how to fix it.

Does anybody have any suggestions?


Solution

  • The issue you're encountering is likely due to the way the API key is being passed into the headers. In PowerShell, when you use single quotes around a string, it does not perform variable substitution. Therefore, in your second script, the API key is being passed as the literal string $ApiKey instead of the value contained in the $ApiKey variable.

    You should use double quotes instead of single quotes for the api-key value in the headers hashtable to ensure that the variable is correctly expanded. script:

    param( [string]$resultFile, [string]$from, [string]$to, [string]$ApiKey)
    
    try {
        $headers = @{'api-key' = $ApiKey}
    
        $url = 'https://******?query={ calendar(where: {
            and: { from: { gte: "' + $from + '" }, to: { lte: "' + $to + '" } } } )
            {
                concerned
                {
                    username
                    regime
                }
                id
                status
                from
                to  
                primaryType
                secondaryType    
            }
        }'
    
        [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
        Invoke-RestMethod -Uri $url -Method Get -Headers $headers -OutFile $resultFile
    }
    catch {
        write-output $PSItem.ToString()
        exit 1
    }
    

    In this version, the api-key header is assigned the value of the $ApiKey variable directly, without being enclosed in quotes.

    Additionally, remember that when calling the script, you are correctly passing the API key. .\hrnet.ps1 -resultFile "E:\temp\HRNet.json" -from "2024-04-15" -to "2024-06-10" -ApiKey "acb59383-a..."

    This change should resolve the 500 Internal Server Error you're seeing, as the API key will now be correctly included in the request headers.