PowerShell to the rescue again! Datadog is a Cloud service for aggregating real-time metrics, events and logs from all your servers. The easiest way is to install an agent and let it report via HTTPS directly to the internet or via a web proxy. Another cloud aggregation solution that I’m more familiar with is Microsoft Operations Management Suite (OMS). Both of these services provide access via PowerShell.

Anyways, back to the actual blog post as you’ve probably come across this searching for Datadog and PowerShell! Datadog doesn’t provide a PowerShell module directly, but it does expose a lot of functionality via web services. There are a few authentication prerequisites that you need to do inside the Datadog portal though before you go ahead and attempt to communicate with the API.

  1. Create an API-Key
  2. Create an Application Key

Everyone connects to Datadog using their public URL, but instead of using a Username and Password combination, they’ve termed them API-Key and Application Key. Using these two together gives you access to your Datadog subscription and information.

Datadog publishes API documentation at http://docs.datadoghq.com/api/ . It has examples in Shell, Python and Ruby. Click on the area you want to see the API for and then click on the desired language. As the Shell method is the closest to HTTPS web service calls, I suggest you use that in order to understand the Datadog API and web service call.

Windows PowerShell comes to the rescue again. Not only can we do a web service call using Invoke-WebRequest , we can also deal with the Datadog response. This response will be in a JSON format (Essentially a less complex/verbose form of XML). We’ll use PowerShell’s ConvertFrom-Json cmdlet to create our handy PowerShell object.

Authentication

At the top of all my Datadog scripts I have the API and authentication information:

# http://docs.datadoghq.com/api/#embeds
$url_base = "https://app.datadoghq.com/" 
$api_key = "asdlfk771ja8z8m0980asz8knnn5f9a9"
$app_key = "x5jaja81jamnz81o85618fcce8a891912387a7f3"

Example Snippets

Below are a few snippets to get you going with Datadog. Most of the changes in each of the snippets are in the $url_signature line. This tells Datadog what information your actually after. Watch out as not all the API calls use api/v1, some may be api/v2.

After you prepare your URL line and parameters, you send it via Invoke-WebRequest and tell PowerShell to set the content type as JSON. Parse your way through $response.Content and find the relevant information you want.

Pulling Authorized Users

#Users
$url_signature = "api/v1/user"
$url = $url_base + $url_signature + "?api_key=$api_key" + "&" + "application_key=$app_key"
$response = Invoke-WebRequest -ContentType "application/json" -Uri $url
$response.Content | ConvertFrom-Json | Select-Object -ExpandProperty Users

Muting a Host

# Mute
$url_signature = "api/v1/host/MyHostName1/mute"
$url = $url_base + $url_signature + "?api_key=$api_key" + "&" + "application_key=$app_key"
$response = Invoke-WebRequest -Uri $url -Method Post
$response.Content | ConvertFrom-Json

Unmuting a Host

# Unmute
$url_signature = "api/v1/host/WMAPMTSTEST/unmute"
$url = $url_base + $url_signature + "?api_key=$api_key" + "&" + "application_key=$app_key"
$response = Invoke-WebRequest -Uri $url -Method Post
$response.Content | ConvertFrom-Json

Display Host/Agent Details

$includeInfo = @(
    "with_apps=true",
    "with_sources=true",
    "with_aliases=true",
    "with_meta=true",
    "with_mute_status=true",
    "with_tags=true"
)

$metricInfo = @(
    "metrics=avg",
    "system.cpu.idle avg",
    "aws.ec2.cpuutilization avg",
    "vsphere.cpu.usage avg",
    "azure.vm.processor_total_pct_user_time avg",
    "system.cpu.iowait avg",
    "system.load.norm.15"
)

$url_query = ""
$url_signature = "reports/v2/overview"
$url = $url_base + $url_signature + "?api_key=$api_key" + "&" + "application_key=$app_key" + "&" + "window=3h" + "&" + (($metricInfo -join "%3A") -replace " ", "%2C") + "&" + ($includeInfo -join "&")
if ($url_query) {
    $url += "&" + $url_query
}
$response = Invoke-WebRequest -Uri $url -Method Get
$response.Content | ConvertFrom-Json | Select-Object -ExpandProperty rows | Select-Object Host_name,  @{n="Actively_Reporting"; e={$_.has_metrics}}, @{n="Agent_Version"; e={$_.meta.Agent_version}}, @{n="Agent_Branch"; e={($_.meta.gohai | ConvertFrom-Json).gohai | Select-Object -ExpandProperty git_branch}}, @{n="ip"; e={($_.meta.gohai | ConvertFrom-Json).network | Select-Object -ExpandProperty ipaddress}}, @{n="LogicalProcessors"; e={$logical = ($_.meta.gohai | ConvertFrom-Json).cpu | Select-Object -ExpandProperty cpu_logical_processors; $cpu_cores = ($_.meta.gohai | ConvertFrom-Json).cpu | Select-Object -ExpandProperty cpu_cores; ($logical / $cpu_cores) * $logical }} | Sort-Object -Property host_name | ft

Searching for Events

In this example we’ll query any Microsoft event log errors between a certain time range and have them passed back. Then we’ll convert them from JSON and look for specific event log error messages.

# Event Log Errors
$dateStart = (Get-Date (Get-Date).AddDays(-30) -Uformat %s) -replace "\..*", ""
$dateEnd = (Get-Date (Get-Date).AddDays(0) -Uformat %s) -replace "\..*", ""
$url_signature = "api/v1/events"

 $EventSearch = @(
    "start=$dateStart",
    "end=$dateEnd"
    "source=Event Viewer" 
)

$url = $url_base + $url_signature + "?api_key=$api_key" + "&" + "application_key=$app_key" + "&" + ($EventSearch -join "&")
$response = Invoke-WebRequest -Uri $url -Method Get

$response.Content | ConvertFrom-Json | Select-Object -ExpandProperty events | Where {$_.Title -eq "Application/Microsoft-Windows-Folder Redirection" -and $_.Text -like "*redirect folder*"} | Select-Object -Unique -Property Text| fl text
$response.Content | ConvertFrom-Json | Select-Object -ExpandProperty events | Where {$_.Title -eq "System/TermDD"} | Select-Object -Unique -Property Text, Host, @{Name ="Timestamp"; Expression={[TimeZone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').AddSeconds($_.date_happened))}} | Group-Object -Property host