Using $filter through Microsoft graph API request - azure

I'm trying to use MS graph API via a small Powershell script as described here https://learn.microsoft.com/en-us/graph/api/riskyusers-list?view=graph-rest-beta&tabs=http
this filter doesn't give any result and if I remove it it works but do not give the complete list (only few results)
$ApplicationID = "45xxxxxxxx"
$TenatDomainName = "2a3xxxxx"
$AccessSecret = Read-Host "Enter Secret"
$Body = #{
Grant_Type = "client_credentials"
Scope = "https://graph.microsoft.com/.default"
client_Id = $ApplicationID
Client_Secret = $AccessSecret
}
$ConnectGraph = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenatDomainName/oauth2/v2.0/token" -Method POST -Body $Body
$token = $ConnectGraph.access_token
#$GrapRisk = "https://graph.microsoft.com/v1.0/identityProtection/riskyUsers"
$GrapRisk = "https://graph.microsoft.com/beta/identityProtection/riskyUsers?$filter=riskLevel eq microsoft.graph.riskLevel'medium'"
$riskyList= (Invoke-RestMethod -Headers #{Authorization = "Bearer $($token)"} -Uri $GrapRisk -Method Get).value |select userPrincipalName, riskState, riskLastUpdatedDateTime, riskLevel
$riskyList
I execute this script through Powershell ISE but even with curl and terminal I cannot use the filter parameter.
Thanks

Whenever a string literal uses double-quotes ("'s), PowerShell interprets it as expandable, meaning PowerShell will attempt to resolve and expand variable expressions (like $filter) when evaluating the string.
Use a backtick (`) to escape the $, and it should work:
$GrapRisk = "https://graph.microsoft.com/beta/identityProtection/riskyUsers?`$filter=riskLevel eq microsoft.graph.riskLevel'medium'"
For more details about the semantics of different types of string literals in PowerShell, read the about_Quoting_Rules help topic

Related

Export all API names Azure APIM

I am trying to export all the url endpoints of my APIs which are stored in Azure APIM.
I need them listed in the format [POST]: https://apim-resource-name.azure-api.net/api-name/api-function, or something similar, so I am trying to enumerate all the endpoints first and the VERB that can be used much like what SwaggerUI or one of the OpenAPI docs might show.
I have this code so far but cannot get the output I would like, am I on the right track or is there any easier way to do this even via UI? I have also tried exporting the template and parsing the script, but it seemed overly complicated for this task.
#az login
$token = az account get-access-token | ConvertFrom-Json
$token = $token.accessToken -replace "`n","" -replace "`r",""
$headers = #{Authorization="Bearer $token.accessToken"}
$subscriptionId = 'subscriptionid'
$resourceGroupName = 'resourcegroupname'
$resourceName = 'resourcename'
$apiName = 'apiname'
$url_getapiexport = "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.ApiManagement/service/$resourceName/apis/$apiName`?format=swagger-link&export=true&api-version=2021-08-01" #GET
$url_getapiexport
#Invoke-RestMethod -Uri $url_getapiexport -Method GET -Headers #{Authorization="Bearer $token"} -ContentType "application/json"
$url_getapibytags = "https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroupName/providers/Microsoft.ApiManagement/service/$resourceName/apisByTags?&includeNotTaggedApis=true&api-version=2021-08-01" #GET
$url_getapibytags
$api_tags = Invoke-RestMethod -Uri $url_getapibytags -Method GET -Headers #{Authorization="Bearer $token"} -ContentType "application/json"
$api_tags
foreach ($api in $api_tags) {
write-host API: $api.value.api.name
}
So if you want to export all APIM APIs and their service URLs you can do like this (replace xxx with correct values). Example in PHP
<?php
echo "[INFO] API Names and Service Urls \n\n";
$apiList = shell_exec('az apim api list --resource-group "xxx" --service-name "xxx" ');
$apis = json_decode($apiList, true);
$cli = "az rest --method get --url";
foreach ($apis as $api)
{
$name = $api["name"];
$apiRequest = "$cli " . "\"https://management.azure.com/subscriptions/xxx/resourceGroups/xxx/providers/Microsoft.ApiManagement/service/xxx/apis/$name?api-version=2021-08-01\"";
$json = shell_exec($apiRequest);
$apiInfo = json_decode($json, true);
$displayName = $apiInfo["properties"]["displayName"];
$serviceUrl = $apiInfo["properties"]["serviceUrl"];
printf("%s: %s \n", $displayName, $serviceUrl);
}
?>

Need to get a value in single quotes in the body section while calling a restapi through powershell

I'm using below script to call a RestAPi using powershell:
$cd = 12000
$Url = 'https://exampleSet/Set'
$Body = #{
OperationType = 'new'
Number = "'$($cd)'"
CdAspId = 'Z_CK_BUGFIX'
CdType = 'CA_106_4'
} | ConvertTo-Json
$headers = #{
'ContentType' = 'application/json'
'Accept' = 'application/json'
'APIKey' = 'abcdef'
}
Invoke-RestMethod -contentType "application/json" -Uri $url -Method Post -body $Body -Headers $headers
While execution, powershell task in Azure is showing me internal server error.
I need help in passing the value in the body as:
Number = '12000'
How can I get the values in body in single quotes. Please help in this.
As mentioned in the comments, JSON exclusively uses double-quoted string literals, so trying to create a JSON document with a property entry Number = '12000' doesn't make any sense - it wouldn't be valid JSON.
To force string encoding rather than a numerical value, simply surround the value with double-quotes in PowerShell:
$Body = #{
OperationType = 'new'
Number = "$cd"
CdAspId = 'Z_CK_BUGFIX'
CdType = 'CA_106_4'
} | ConvertTo-Json

Invoke-Restmethod powershell in Azure Devops - strange powershell errors

I am using this invoke-restmethod so I can get a token so I can do some sql work. the variables come from Azure Key Vault. I have tried to write the variables as
$($SPNAppid)
$SPNAppid
${$SPNAppid} etc
Here is the code :
$request = Invoke-RestMethod -Method POST -Uri
"https://login.microsoftonline.com/${$TenantId}"/oauth2/token" -Body
#{ resource="https://database.windows.net/";
grant_type="client_credentials"; client_id=${$SPNAppid};
client_secret=${$SPNValue} } -ContentType
"application/x-www-form-urlencoded"
Getting this error below. What is the best way to do this - whatever i do i am getting the errors below.
Variable reference is not valid. ':' was not followed by a valid variable name character. Consider using ${} to
delimit the name.
At C:\agent01_2\_work\_temp\b3f54d23-b7b6-4cc3-96ec-8b4b534be571.ps1:20 char:319
+ ... ervicePrincipalKey } -ContentType "application/x-www-form-urlencoded"
+ ~
The string is missing the terminator: ".
The code you posted, has an extra " and given the ambiguity of the long line I would suggest to use splatting like this :
$header = #{
"Content-type" = "application/x-www-form-urlencoded"
"Authorization" = "Bearer $token"
}
$body = #{
resource = "https://database.windows.net/"
grant_type = "client_credentials"
client_id = $SPNAppid
client_secret = $SPNValue
}
$params = #{
Method = 'Post'
Uri = "https://login.microsoftonline.com/$($TenantId)/oauth2/token"
Body = $body
ContentType = $header
}
$request = Invoke-RestMethod #params
I do not think the API call would work this way, usually clientId etc. are part of the URL, you can read more about it here - https://learn.microsoft.com/en-us/azure/active-directory/develop/v2-oauth2-auth-code-flow

Powershell invoke-restmethod variable in url

I am new to powershell, and I am trying to create a simple script that will allow me to turn on several Azure VMs using the invoke-restmethod.
My code works when instead of using a variable I directly write the VM name into the url, but I want to use a variable, since eventually this must work for more than one VM.
Relevant part of code:
$body = #{
"$virtualMachines" = "VM1"
} | ConvertTo=Json
$url= "https://management.azure.com/subscriptions/mySubscriptionId/resourceGroups/myResourceGroupName/providers/Microsoft.DevTestLab/labs/myLabName/virtualmachines/" + $virtualMachines + "/start?api-version=2018-09-15"
$response = Invoke-RestMethod -uri $url -Method 'POST' -Headers $headers -Body $body
$response | ConvertTo-Json
If you had a number of VMs, you could put them all into a PowerShell variable like this, an array of strings.
$VMs = "myVm1", "myVm2", "myVm3"
PowerShell has a number of flow control statements, the one you want to use is ForEach, which will step through an array one at a time. We just modify the way you're setting up the URL to be friendlier and easier to read and this should work just fine.
$baseUrl = "https://management.azure.com/subscriptions/mySubscriptionId/resourceGroups/myResourceGroupName/providers/Microsoft.DevTestLab/labs/myLabName/virtualmachines/"
ForEach ($vm in $VMs){
$url = $baseurl + $vm + "/start?api-version=2018-09-15"
Write-host "About to start [$Vm]"
$response = Invoke-RestMethod -uri $url -Method 'POST' -Headers $headers
$response | ConvertTo-Json
}
I checked the API documentation for the start? REST API endpoint, and it doesn't look like you need the -Body parameter for this endpoint.

PowerShell- Use Credentials instead of Basic Bas64 with Token to Invoke-RestMethod against AzureDevops

I have PowerShell scripts that I run to kick off a build in Azure DevOps as well as doing lots of things in Azure DevOps using the Rest API. I am currently using the token that is converted to Base64 using basic in the header to authenticate. If there a way of using -Credentials (Get-Credentials) with the token instead of a base64 header encoded token when using Invoke-RestMethod? Below is a sample for connecting with the Base64 token and Basic.
Sample script that lists Projects:
$token = "##############################################"
$UriOrg = "https://dev.azure.com/myADO/"
$AzureDevOpsAuthenicationHeader = #{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($token)")) }
$uriProcess = $UriOrg + "_apis/process/processes?api-version=5.1"
Invoke-RestMethod -Uri $uriProcess -Method get -Headers $AzureDevOpsAuthenicationHeader
Although Get-Credential is designed to get a credential using a username and password, you can of course also use it to have someone enter the token..
Something like
$cred = Get-Credential -Message 'Please enter the AzureDevops Token in the Password field' -UserName 'AzureDevops'
if ($cred) {
$token = $cred.GetNetworkCredential().Password
$authHeader = #{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($token)")) }
$UriOrg = 'https://dev.azure.com/myADO/'
$uriProcess = $UriOrg + "_apis/process/processes?api-version=5.1"
Invoke-RestMethod -Uri $uriProcess -Method Get -Headers $authHeader
}
Another option would be to create your own form where it is also possible to enter the Uri for the organization, because Get-Credential does not accept usernames like https://dev.azure.com/myADO/

Resources