Azure Advisor API Possible Limitations and Filter Issues - api

I manage many subscriptions so the current Azure Advisor while interesting requires you to go through too many screens and there is no way to download the CSV recommendations and compile them using PowerShell. This led to attempt to interface with the API. The issue I am having is that it appears that it limits you to 200 records so changing top does nothing. Many of the records are a generic security warning with a risk of none. I attempted to filter them out but my knowledge of API filters is poor and the documentation Microsoft provides could be better. Below is the PowerShell command I am using:
Call:
$Response = Invoke-RestMethod -Uri "https://management.azure.com/subscriptions/${SubscriptionId}/providers/Microsoft.Advisor/Recommendations?api-version=2017-04-19&`$top=999&`$filter=risk -ne None" -Method GET -Headers #{"Authorization" = "$AccessToken"} -Verbose
Response:
Without Filter Parameter
https://management.azure.com/subscriptions/<SubID>/providers/microsoft.Advisor/recommendations?api-version=2017-04-19&$top=200&$s
kiptoken=<Token>
With Filter Parameter
Invoke-RestMethod -Uri "https://management.azure.com/subscriptions/${SubscriptionId}/providers/Microsoft.Advisor/Recommendations?api-version=2017-04-19&`$top=999&`$filter=risk -eq 'None'" -Method GET -Headers #{"Authorization" = "$AccessToken"} -Verbose
VERBOSE: GET https://management.azure.com/subscriptions/<sub ID>/providers/Microsoft.Advisor/Recommendations?api-version=2017-04-1
9&$top=999&$filter=risk -eq 'None' with 0-byte payload
Invoke-RestMethod : {"message":"Invalid $filter param"}
At line:1 char:13
+ $Response = Invoke-RestMethod -Uri "https://management.azure.com/subs ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

I have been struggling with exactly the same today, hence I found your article.
I managed to resolve my issue by using a later version of the API, and slightly changing the filter
For example:
$filter="Category eq 'Cost'"
$url = "https://management.azure.com/subscriptions/$Subscriptionid/providers/microsoft.Advisor/recommendations?api-version=2017-04-19&`$top=999&`$filter=$filter"

There is a mistake in your API. The right API grammar is &$filter not $filter, you could see your API, you lose a &.
The following script works for me.
##get token
$TENANTID=""
$APPID=""
$PASSWORD=""
$result=Invoke-RestMethod -Uri https://login.microsoftonline.com/$TENANTID/oauth2/token?api-version=1.0 -Method Post -Body #{"grant_type" = "client_credentials"; "resource" = "https://management.core.windows.net/"; "client_id" = "$APPID"; "client_secret" = "$PASSWORD" }
$token=$result.access_token
##set subscriptionId
$subscriptionId=""
$Headers=#{
'authorization'="Bearer $token"
'host'="management.azure.com"
'contentype'='application/json'
}
$url="https://management.azure.com/subscriptions/$subscriptionID/providers/Microsoft.Advisor/Recommendations?api-version=2017-03-31&`$top=999`&$filter=risk -eq 'None'"
Invoke-RestMethod -Uri $url -Headers $Headers -Method GET

Related

Azure Data Factory API Connector

I am trying to access an application via API REST but I am stuck in the process using ADF.
Basically this process consists in 2 steps.
1 - Getting a session (https://horizon.akixi.com/CCS/API/v1/session)
2 - Authenticating (https://horizon.akixi.com/CCS/API/v1/login?locale=en_GB") using Username and Password.
I have created a Linked Service (Rest) and set the Base URL as (https://horizon.akixi.com/CCS/API/v1/session)
Authentication Anonymous.
Then I create a Data Set to point this API and finally I create a "Copy Data" and tried to set on the Additional Header the authentication's details, but it is not working, I got an error 405.
Basically I can run the below script using Powershell and it is working as expected, but is required to use it on ADF instead.
The script in Powershell is this one.
$user = "xxxxxx#mail.com"
$pass = "123456789"
$secpasswd = ConvertTo-SecureString $pass -AsPlainText -Force
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$pass)))
#Get Session
$url = "https://horizon.akixi.com/CCS/API/v1/session"
$response = Invoke-RestMethod -uri $url -Method Post -SessionVariable se
#Authentication
Write-Host "Authenticating" -ForegroundColor Green
$headers = #{
'Authorization' = "Basic $base64AuthInfo"
}
$headers
$url = "https://horizon.akixi.com/CCS/API/v1/login?locale=en_GB"
$response = Invoke-RestMethod -uri $url -Headers $headers -Method Get -WebSession $se
#List Reports
$url = "https://horizon.akixi.com/CCS/API/v1/report"
$response = Invoke-RestMethod -uri $url -Method Get -WebSession $se
$response
Thank you all.
As the 3 steps are separate, and only the last one fetches data, you should break up the process into multiple activities.
Use Web Activity for the first two steps,
https://horizon.akixi.com/CCS/API/v1/session
https://horizon.akixi.com/CCS/API/v1/login?locale=en_GB"
extract the session variable or Authentication from the web activities. Pass it to the copy activity. The copy activity should target
https://horizon.akixi.com/CCS/API/v1/report

Check if current user has permissions to create work items

Is there an endpoint in TFS rest api that i can use to check if the current logged in user has enough permissions to create a new TFS work item ?
Try to use validation with the validateOnly parameter Work Items - Create.
PowerShell sample:
$pat = '<pat>'
$url = 'https://dev.azure.com/<org>/<project>/_apis/wit/workitems/$Task?validateOnly=true&api-version=6.1-preview.3'
$body = '[{"op":"add","path":"/fields/System.Title","from":null,"value":"Sample task"}]'
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "",$pat)))
Invoke-RestMethod -Uri $url -Method Post -ContentType "application/json-patch+json" -Headers #{Authorization=("Basic {0}" -f $base64AuthInfo)} -Body $body
Result:
Invoke-RestMethod : {"$id":"1","innerException":null,"message":"TF237111: The current user does not have permissions to save work items under the specified area path.","typeName":"Microsoft.Azure.Boards.WebApi.Com
mon.PermissionDeniedException, Microsoft.Azure.Boards.WebApi.Common","typeKey":"PermissionDeniedException","errorCode":0,"eventId":3000}
At line:10 char:1
+ Invoke-RestMethod -Uri $url -Method Post -ContentType "application/js ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

Forward an email using rest api and powershell (Azure Automation)

I'm trying to forward emails with attachments to a specific email address via Azure Automation (with message ID). I get the error message at the bottom after I run the code. I'm not really sure am I on the right track here (both with email sending and sending of attachments). Perhaps there's a better way to do this.
Could anyone lend a hand?
$credObject = Get-AutomationPSCredential -Name "Myscreds"
$url = "https://outlook.office365.com/api/v1.0/me/AAMkADA1MTAAAH5JaL/forward"
$body = "{
""Message"":{
""Subject"": ""This is a test"",
""Importance"": ""Low"",
""Body"": {
""ContentType"": ""HTML"",
""Content"": ""This is great!""
},
""ToRecipients"": [
{
""EmailAddress"":{
""Address"": ""myname#test.com""
}
}
]
}}"
Invoke-RestMethod -Uri $url -Method Post -Credential $credobject -ContentType "application/json" -Body $Body
I get the following error message:
Invoke-RestMethod : The remote server returned an error: (400) Bad Request.
At line:24 char:1
+ Invoke-RestMethod -Uri $url -Method Post -Credential $credobject -Con ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod],
WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
Thanks.
Per the Microsoft documentation, you need to modify your request.
https://outlook.office.com/api/v1.0/me/messages/AAMkAGE0Mz8DmAAA=/forward
It looks like you forgot to include /messages/ in your request.
However, it looks like you want to change the body of a message when you forward it. This is more complicated, and you need to follow this workflow instead:
Alternatively, if you need to modify any updateable properties in the message to be forwarded, you can first create a draft forward message, update the message properties, and then send the reply.
Here's how that would look.
First, make a Draft of the message you want to forward
$request = "https://outlook.office365.com/api/v1.0/me/messages/AAMkADA1MTAAAH5JaL/createforward"
$body = {
"ToRecipients":[
{
""EmailAddress"":{
""Address"": ""myname#test.com""
}
}
],
"Comment": "Your sample message here"
}
The response back is going to include some properties, including the ID of the new message. You then use that to edit the Draft (to change the subject, etc) and then send it off. Let me know if you need any further help.
Ok. I had the incorrect message ID, that was my main problem. It's all resolved. I can forward messages with attachments using the message ID. Thanks again.
$credObject = Get-AutomationPSCredential -Name "mycreds"
$url = "https://outlook.office365.com/api/v1.0/Users('it-test#test.com')/messages/ASHJFKHFUISDFWIzLT=/forward"
$body = "{
""Comment"": ""A mail with some attachments (hopefully)"",
""ToRecipients"": [
{
""EmailAddress"":{
""Address"": ""myname#test.com""
}
}
]
}"
Invoke-RestMethod -Uri $url -Method Post -Credential $credobject -ContentType "application/json" -body $body

Using the attask api, how can update a task

Using the Attask api, how can a I add an update through the rest api? Updating the task looks like it will completely replace all updates as per the PUT documentation on nested objects, and doing a post on the /api/update doesn't seem to work : here is what I have tried so far using Powershell for testing
$url = "https:///attask/api/update?sessionID=$($session.data.sessionID)&message=Test Message from api&refObjID=56e9b1d100741c6eb3cab7df95269ba7&objCode=UPDATE&updateObjCode=NOTE"
$result = Invoke-RestMethod -Uri $url -Method "POST"
Result is :
Invoke-RestMethod : {"error":{"class":"java.lang.UnsupportedOperationException","message":null}}
Instead of Updates, post to notes instead - e.g.
$url = "https://lockton.attask-ondemand.com/attask/api/note?sessionID=$($session.data.sessionID)&updates={noteText:'Test Message from api',objID:'56e9b1d100741c6eb3cab7df95269ba7',noteObjCode:'TASK'}"
$postResult = Invoke-RestMethod -Uri $url -Method "POST"
$postResult

Powershell Invoke-RestMethod

I'm trying to create a powershell script to access DYN's API and perform checks/updates on DNS zones I use/test.
I'm following their API details and here's the first link, https://help.dyn.com/session-log-in/
Here's the beginning of the REST script I've put together:
$url = "https://api2.dynect.net/REST/Session/"
$body = #{customer_name='mahcompany';user_name='mahname';password='mahpass'}
Invoke-RestMethod -Method Post -Uri $url -Body $body
This produces the following results:
Invoke-RestMethod : The remote server returned an error: (406) Not Acceptable.
At line:12 char:9
+ $test = Invoke-RestMethod -Method Post -Uri $url -Body $body
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-> RestMethod], WebException
+ FullyQualifiedErrorId :
WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
This is supposed to be a JSON query according to the DYN information, and so I've tried sevveral other examples of DYN's using CURL as a basis:
$json = #"{"customer_name":"yourcustomer","user_name":"youruser","password":"yourpass"}'
However this doesn't work either.
Can anyone point me in the right direction here? This can't be that crazy, I'm just trying to pass the parameters into a rest-method query string. Any help would be very much appreciated at this point.
-Sean
Content Type
Invoke-RestMethod -Method Post -Uri $url -Body $body -ContentType 'application/json'
This might be the problem if dyn.com is expecting a proper content type.
According to the documentation on Invoke-RestMethod:
If this parameter is omitted and the request method is POST, Invoke-RestMethod sets the content type to "application/x-www-form-urlencoded". Otherwise, the content type is not specified in the call.
ConvertTo-JSON
You don't have to create your JSON string manually. You can create a hashtable and then convert it:
$data = #{
customer = 'something'
name = 'whatever'
}
$data | ConvertTo-JSON
I'm not saying that you are definitely making malformed JSON, but this can help prevent that.