How to query Azure AppInsights custom metric from Powershell - powershell

I'm publishing a custom metric called "ConnectionCount" on my AppInsights component.
I'm looking for a way to query the last values for that metric in a PowerShell script.
I've used this command in the past:
$resourceId = "/subscriptions/$subscriptionId/resourceGroups/MyResourceGroup/providers/microsoft.insights/components/MyAppInsight"
Get-AzureRmMetric -ResourceId $resourceId -TimeGrain $timeGrain -StartTime $startTime -MetricNames $metric`
But when run this, I just get an error back:
Get-AzureRmMetric : Operation returned an invalid status code 'NotFound'
I also tried the REST API, using this code:
$resourceGroupId = "subscriptions/$subscriptionId/resourceGroups/$resourceGroupName"
$filter = "(name.value eq 'ConnectionCount') and timeGrain eq duration'PT5M' and " +
"startTime eq 2017-07-20T17:00:47.8791884Z and endTime eq 2017-07-25T17:30:47.8832111Z"
$apiVersion = "2015-05-01"
$uri = "https://management.azure.com/$resourceGroupId/providers/microsoft.insights/components/$appInsightName/metrics?api-version=$apiVersion&`$filter=$filter"
Invoke-RestMethod $uri -Headers $headers
But it simply gives me back an empty response.
Does anyone know if something has changed in the Metrics API that would prevent custom metrics values to be retrieve from PowerShell or the REST API?

if you're getting an empty response (and not any kind of failure) then i'd suggest verifying that your query is doing what you expect and not filtering out all your data?
your filter looks really suspicious to me, this part timeGrain eq duration'PT5M' seems like an odd filter to me. normally you'd specify the range and the grain as other parts of the query, not inside the $filter part
i'd suggest verifying all of your REST stuff with the API docs at https://dev.applicationinsights.io, and try testing your query at
https://dev.applicationinsights.io/apiexplorer/metrics

Related

Filtering REST API PowerBI results in Powershell

I am attempting to call the "Get Groups" REST API to return a list of all the workspaces I have access to in Power BI. I want to be able to add a filter to the API call and return only the workspaces whose names have the word "email" in them. I've tried to edit the API url, but nothing seems to change the result set. Any thoughts help!
$GetWorkspaces = Invoke-PowerBIRestMethod -Url "https://api.powerbi.com/v1.0/myorg/groups/" -Method Get
I've tried the "try it" function in microsoft docs learn pages, but these urls aren't working either.
Give this a try
You can use the $filter query parameter to filter the workspaces by name. The $filter parameter supports OData filter expressions. To filter workspaces whose names contain the word "email", you can use the following expression:
$filter=indexof(name,'email') ne -1
Here is the updated PowerShell script that includes the $filter parameter:
The backtick () character is used to escape the $character in the $filter parameter so that PowerShell does not treat it as a variable.
This script should return a list of workspaces whose names contain the word "email"
$GetWorkspaces = Invoke-PowerBIRestMethod -Url "https://api.powerbi.com/v1.0/myorg/groups/?`$filter=indexof(name,'email') ne -1" -Method Get
This is what worked for me:
$GetWorkspaces = Invoke-PowerBIRestMethod -Url "https://api.powerbi.com/v1.0/myorg/groups?%24filter=contains(name%2C%27email%27)" -Method Get

Add if-then-else logic to Azure DevOps release pipeline

I have a release pipeline in Azure DevOps.
I have added an Agentless job running that calls a REST API endpoint.
At the moment this works as expected.
However my next challenge is to take the response from the API call and perform some tasks. Here is a breakdown of the logic I am trying to achieve:
GET list of students (Connect to REST API with GET)
Read response from above step and look for a specific value
If value exists continue
If value does not exist then POST new value to REST API endpoint
Like I said, I have step 1 sorted but I do not know how to add the if-then-else logic
Any help appreciated
Thanks
You need to look at the output of your response to get your specific value.
$reponse = Invoke-RestMethod -Method GET -URI $url
$specificValue = $response.output.specificValue
if(!$specificValue) {
##value does not exist
Invoke-RestMethod -Method POST -URI $url -Body $body
}

What is the REST API rate limit for a standard Azure Search service?

I have a release pipeline in Azure DevOps that is creating 36 search indexes on a standard Azure Search Service that has a max of 50.
I am using a Powershell script that reads json files in a repo to create the search indexes using the REST API directly.
First I delete all indexes and then I create them again. (to cater for any changes in the json files stored in the repo)
It seems to be able to run for about 25 REST API calls before I get an error of:
(503) Server Unavailable. You are sending too many requests. Please try again later.
Even if I insert a delay of 4 seconds between each REST API call (that either deletes or creates an index) I still get the same error.
Is there anything special I need to do? Are the limits REST API call rate documented anywhere? ( I thought here, but sadly no.)
The Powershell script fragment is: ($indexFiles is a list of the json files to apply)
$headers = #{"Content-Type" = "application/json"
"api-key" = $SearchAPIKey }
$indexesUrl = "https://$SearchSiteName.search.windows.net/indexes?api-version=$SearchAPIVersion"
Write-Host "Applying the following $($indexFiles.count) index files: "
$indexFiles | ForEach-Object { $indexData = Get-Content -Path $_.FullName -raw
$filename = $_.Name
try
{
Start-Sleep -Milliseconds $APICallDelay
$response = Invoke-WebRequest -Method Post -Uri $indexesUrl -Headers $headers -Body $indexData
if ($response.StatusCode -eq 201)
{
Write-Host "- $filename applied"
}
else
{
Write-Error "Issues with creating index $filename with Url $indexesUrl. Status code returned was $($response.StatusCode). Msg: $($response.StatusDescription)"
}
}
catch
{
$summaryMsg = $_.Exception.Message
$detailed = $_.ErrorDetails.Message | ConvertFrom-Json
$detailedMsg = $detailed.error.message
Write-Error "Error with creating index $filename. $summaryMsg. Detailed error: $detailedMsg"
}
}
If anyone can offer any suggestions, it would be greatly appreciated!
Have been told of the current limits to Azure Search Services:
Create index (POST) can be called up to 12 times per minute
Update index (PUT) can be called up to 360 times per minute
Delete index can be called up to 12 times per minute
Get index can be called up to 600 times per minute
List indexes can be called up to 300 times per minute
So currently, we have no choice but to put in Start-Sleep -Minutes 2 in our code if we have more than 12 indexes to deploy at once. :(

GoDaddy DNS API - Building a module with numerous commands

EDIT: I am looking for assistance on the GoDaddy API and how to form the request so I can delete a record. I can replace records and add new records and, of course, read records. I do not need assistance on building the module. Just having a problem figuring out the REST API piece for doing a delete on GoDaddy with the API.
I found this: Error 422 When Using Powershell to Update DNS Records on GoDaddy API
This gave me a good start. I have a number of functions I have already written to create or modify various different types of record. I have learned a lot along the way. Something that I have been unable to figure out so far is how to use the API to delete an existing record that is no longer needed.
I discovered that if I had an existing record of the same name and type and I tried to create a new, it would replace what was there with the new value. If it is just an A record and that is your desire, that's great. But if it is an MX or NS record, that is probably not the desired result. I am working on the helper functions to make sure that I don't blow away existing records before I publish to my module.
I am relatively new to reading API documentation and working with REST API's so I am probably just missing something basic, but if anyone could provide me with some guidance on how to configure my call so that I can clean up records that are no longer needed.
I am also having some issues formatting the SRV record properly so that it doesn't error out when I make the call. I am not sure where my problem is and I am not seeing anything in the documentation of allowed/expected values for Protocol, Service, etc.
Here is an excerpt of my code where I am calling:
try{
$ret = Invoke-WebRequest https://api.godaddy.com/v1/domains/domain/records/$type/$alias -method put -headers $headers -Body $json -ContentType "application/json"
if ($ret.StatusCode -eq 200) { Write-Verbose -Message "Success!" }
else { Write-Warning -Message "ERROR" }
} catch {
$result = $_.Exception.Response.GetResponseStream()
$reader = New-Object System.IO.StreamReader($result)
$reader.BaseStream.Position = 0
$reader.DiscardBufferedData()
$responseBody = $reader.ReadToEnd();
$responseBody = $responseBody | ConvertFrom-Json | Format-Custom | Out-String
Write-Warning -Message "ERROR: $responseBody"
}
You will recognize this code block as it is largely taken intact from the aforementioned post. I am passing in $type as a valid record type (A, CNAME, etc.). $alias is the name of an existing record. $headers is a properly formatted header with a valid key/secret pair (I am able to Get and Put other records). I have tried omitting the body altogether to delete a value and that fails. I have tried doing the body with a JSON empty set ([], [{}]) as well as passing in data and TTL values with no value in the JSON. I can't get a successful query to work. I am testing with the following:
Invoke-WebRequest "https://api.godaddy.com/v1/domains/mydomain/records/A/test2" -method put -headers $header -ContentType "application/json" -Body '[{}]'
Any guidance or pointers to documentation that I haven't found would be greatly appreciated.
I had the same problem, it's about JSON encoding. I will show you a PHP example you can adapt to anything. The format that GoDaddy will provide is like this:
[{"":"","":"","":"",.....}]
I don't know from where comes the [] but I remove them, the parse json with regular PHP functions:
$json = str_replace("]","",$json);
//print_r($json);
$json = json_decode($json,true);
Now you will get the usable object to work with.
When send data to GoDaddy, do the same (I use curl)
$data = '[{"type":"'.$type.'","name":"'.$name.'","data":"'.$data.'","ttl":'.$ttl.'}]';
A full example that I build for updating my home server dynamic IP :) Check the functions Update() and get()
https://github.com/yo3hcv/Dynamic-DNS-hosting-home-or-mobile-with-GoDaddy/blob/master/pip.php
This maybe useful for others as I ran into the same unclarity about deleting a DNS record from a Godaddy domain using their API.
Godaddy doesn't support deleting an individual record.
From their support on the question whether it was possible to delete a record:
Dear Sir/Madam,
This API call does not exist at this time and it is something on our backlog to build out but there is no ETA to have it created. Current you can use the Put endpoint on the record type to replace all but the one you do not want to keep or you may go into our UI to remove it that way.
See their api documentation for what is available (at this date July 2020).
However, what you can do is replace all the existing records with a new set.
So suppose you have three A records with subdomain SD1, SD2 and SD3 and you want to remove SD2. You could sent an update command using:
curl -X PUT "https://api.godaddy.com/v1/domains/<yourdomain>/records/A" -H "accept: application/json" -H "Content-Type: application/json" -H "Authorization: <yourAPIKEY>" -d "[ { \"data\": \"<IP for SD1>\", \"name\": \"SD1\", \"ttl\": 3600 }, { \"data\": \"<IP for SD3>\", \"name\": \"SD3\", \"ttl\": 3600 }]"
Which will result in two A records one for SD1 and one for SD3. As long as you have at least one recordtype left (this also works for MX, MS, TXT) you will be able to remove others.
If you want to remove the last you have to go back to the Godaddy GUI, unfortunately.

REST API PowerShell Array response

Using PowerShell Invoke-RestMethod to query a REST and getting back a response as shown below:
REST> Write-Host $response
#{Success=}
REST> Write-Host $response.Success
#{count=1; uri=https://useful}
I would like to be able to assign uri to a variable.
You can access the uri using:
$yourVariable = $response.Success.uri