Rest API Powershell

metrics

#1

Good Afternoon All,

I am trying to get a basic setup to do a REST API call for some metrics but i am having an issue with just getting the powershell script to parse the JSON data that i am sending. I have validated the data is in JSON format but when it goes to run the header it says cannot parse JSON.

Has anyone had any luck with doing a simple API request with the API key in Powershell? I have checked the REST API and powershell doc but want something simpler and i have also checked the article on created it but the example is failing on me. Any examples or direction would be great. Ultimately i would like to be able to call dynamic queries of data so i can parse it out as needed from the EH.


#2

Can you please provide an example body for your PowerShell invocation?


#3

indeed. i have redacted some info but here is the jist of it. this is originally from “anoryx” at EH.

<#
503.ps1

This script prints the number of 404 errors for a specific URI
on a specific device on my EDA.
Author: anoryx
Last Updated: 09 Jan 2017
#>

<#
Param(
  [Parameter(Mandatory=$True,Position=1)]
   [string]$apiKey
)
#>

# This block of code permits insecure certs.
# Source: http://stackoverflow.com/a/15841856

add-type @"
     using System.Net;
     using System.Security.Cryptography.X509Certificates;
     public class TrustAllCertsPolicy : ICertificatePolicy {
         public bool CheckValidationResult(
             ServicePoint srvPoint, X509Certificate certificate,
             WebRequest request, int certificateProblem) {
             return true;
         }
     }
"@
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12


# ---------
# Variables
# ---------

$apiKey = "removed"
$cycle = "auto"
$from = "-30m"
$until = 0
$object_ids = "[55834576295]"
$object_type = "device"
$metric_category = "uri_http_server_detail"
$metric_spec = @"
[
  {
    "name": "status_code",
    "key1": "404",
    "key2": "https://uriofinterest.com/test"

  }
]
"@

# ----------------------
# ExtraHop REST API Call
# ----------------------

$uri = "https://extrahopECAURL/api/v1/metrics/total"
$headers = @{Accept="application/json";Authorization="ExtraHop apikey=$($apiKey)"}









$method = "POST"
$body = @"
{
    "cycle": "$($cycle)",
    "from": $($from),
    "until": $($until),
    "metric_category": "$($metric_category)",
    "metric_specs": $($metric_spec),
    "object_type": "$($object_type)",
    "object_ids": $($object_ids)
}
"@

# The actual API call to our ExtraHop appliance


$results = Invoke-RestMethod -Uri $uri -Headers $headers -Method $method -Body $body

# We can do whatever we want with our results. I just want to print to console,
# but you are limited only by your imagination and the requirements of
# your managers. :)

Write-Host 404 Errors in the Last 30 min = $results.stats.values.value[0].value

#4

I’m not super familiar with PowerShell, but can you try wrapping the value of your from argument in the $body declaration in quotation marks, like you did cycle on the preceding line? I suspect that’ll fix the issue.

As an aside, there’s a simpler and (slightly) safer way to solve the certificate verification issue in PowerShell: You can get the appliance’s public CER file by sending a GET request to http://extrahopECAURL/public.cer (note that is not HTTPS), and then importing/installing that certificate. If I can find the exact command I used to do this 15 months ago, I’ll post it here.


#5

Thank you @teddriggs. i’ll give it a shot. appreciate the feedback.


#6

Changed it to the following header format to this

$headers = @"
[
    {
        "Accept": "application/json",
        "Authorization": "ExtraHop apikey=$($apiKey)"
    }
]
"@

and got the following error.

Invoke-RestMethod : Cannot bind parameter 'Headers'. Cannot convert the "[
    {
        "Accept": "application/json",
        "Authorization": "ExtraHop apikey=*****************************************"
    }
]" value of type "System.String" to type "System.Collections.IDictionary".
At line:1 char:49
+ $results = Invoke-RestMethod -Uri $uri -Headers $headers -Method $met ...
+                                                 ~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Invoke-RestMethod], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

#7

That’s a PowerShell error, not an ExtraHop one. See this Stack Overflow post for guidance on how to declare and initialize a dictionary.


#8

Understood. it seems something simple is missing. A’ll i’m trying to do is create a REST call to get metrics with an API key in a header. i am using the original post from anoryx but haven’t had any luck.


#9

Can you try the following?

<#
503.ps1

This script prints the number of 404 errors for a specific URI
on a specific device on my EDA.
Author: anoryx
Last Updated: 09 Jan 2017
#>

<#
Param(
  [Parameter(Mandatory=$True,Position=1)]
   [string]$apiKey
)
#>

# This block of code permits insecure certs.
# Source: http://stackoverflow.com/a/15841856

add-type @"
     using System.Net;
     using System.Security.Cryptography.X509Certificates;
     public class TrustAllCertsPolicy : ICertificatePolicy {
         public bool CheckValidationResult(
             ServicePoint srvPoint, X509Certificate certificate,
             WebRequest request, int certificateProblem) {
             return true;
         }
     }
"@
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12


# ---------
# Variables
# ---------

$apiKey = "removed"
$cycle = "auto"
$from = "-30m"
$until = 0
$object_ids = "[55834576295]"
$object_type = "device"
$metric_category = "uri_http_server_detail"
$metric_spec = @"
[
  {
    "name": "status_code",
    "key1": "404",
    "key2": "https://uriofinterest.com/test"

  }
]
"@

# ----------------------
# ExtraHop REST API Call
# ----------------------

$uri = "https://extrahopECAURL/api/v1/metrics/total"
$headers = @{Accept="application/json";Authorization="ExtraHop apikey=$($apiKey)"}









$method = "POST"
$body = @"
{
    "cycle": "$($cycle)",
    "from": "$($from)",
    "until": $($until),
    "metric_category": "$($metric_category)",
    "metric_specs": $($metric_spec),
    "object_type": "$($object_type)",
    "object_ids": $($object_ids)
}
"@

# The actual API call to our ExtraHop appliance


$results = Invoke-RestMethod -Uri $uri -Headers $headers -Method $method -Body $body

# We can do whatever we want with our results. I just want to print to console,
# but you are limited only by your imagination and the requirements of
# your managers. :)

# Write-Host 404 Errors in the Last 30 min = $results.stats.values.value[0].value

This is the same as the one you first posted, except that I’ve wrapped the value of the from specifically in quotation marks. I suspect yours is broken because you’re using the string form of relative time, and that example was written using millisecond times.


#10

that worked.


#11

side question, is there any way to query the device name and get the api key? trying to get it so i can query “machine name” rather than going ot the extrahop to query the object id for each object. trying to make a query more dynamic.


#12

If you meant the REST API ID for the device, you can first search using the GET /api/v1/devices endpoint to search devices by name. There’s no way to look up a device by name and return metrics for that device in one API call.