How to manage the Azure APIM developer portal delegation with Azure PowerShell - azure

I want to enable the Azure APIM developer portal sign-in & sign-up delegation and to generate a "Delegation Validation Key". This is straightforward with the Azure portal:
I want to achieve the same thing but with Azure PowerShell as part of a bigger deployment pipeline.
I cannot find any documentation on how to do that.
Thanks

AFAIK, We can not achieve the above requirement using powershell , Here are the details (MICROSOFT DOCUMENTATION) for what we can configure through powershell for APIM .
Instead of that we can configure the above requirement using git , Please refer this MICRSOFT DOCUMENTATION for more details & the list of cmdlets for APIM .

An additional option is to use an HTTP call against the resource. The call can be made with the PowerShell script as well.
This can be done as follows:
Get an Azure access token - you should have a Service Principal with sufficient permissions for the resource we are going to deal with.
$tokenUri = "https://login.microsoftonline.com/${tenantId}/oauth2/token"
$form = #{
grant_type = 'client_credentials'
resource = 'https://management.core.windows.net/'
client_id = $spClientId
client_secret = $spClientSecret
}
$response = Invoke-RestMethod -Uri $tokenUri -Method Post -Body $form
$azureToken = $response.access_token
Send an HTTP request against the APIM service
$url = "https://management.azure.com/subscriptions/${subscriptionId}/resourceGroups/${apiManagementRg}/providers/Microsoft.ApiManagement/service/${apiManagementName}/portalsettings/delegation?api-version=2020-12-01"
$headers = #{ 'Authorization' = "Bearer ${azureToken}" }
$body = #"
{
"properties": {
"url": "$delegationUrl",
"validationKey": "$validationKey",
"subscriptions": {
"enabled": false
},
"userRegistration": {
"enabled": true
}
}
}
"#
$delegationResponse = Invoke-RestMethod -Method 'Put' -Body $body -Uri $url -Headers $headers

Related

Azure AutomationAccount DSC scripts debug

I am running a DSC script from an Azure automation account to configure Windows VMs. It downloads files from a storage account in Azure to hosts for more configurations. If I hardcode the storage SAS token, it works fine. But I would like to get the SAS token in the DSC script. I use managed identity of the Automation account and assigned proper IAM access in storage account. I am able to get the SAS token in a test runbook script, but not in DSC script.
I got the main part of the code from
https://learn.microsoft.com/en-us/azure/automation/enable-managed-identity-for-automation
The error I am getting indicates that the SAS token is not generated correctly, but I can't find a way to see what the error msgs are from this part of the code in DSC when it executed.
any help/suggestion is appreciated!
Configuration DSCtest {
Import-DscResource -ModuleName 'PSDesiredStateConfiguration'
$resource= "?resource=https://management.azure.com/"
$url = $env:IDENTITY_ENDPOINT + $resource
$Headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$Headers.Add("X-IDENTITY-HEADER", $env:IDENTITY_HEADER)
$Headers.Add("Metadata", "True")
$accessToken = Invoke-RestMethod -Uri $url -Method 'GET' -Headers $Headers
$Atoken = $accessToken.access_token
Write-Output $Atoken
$toDate = (Get-Date).AddDays(4).toString("yyyy-MM-ddT00:00:00Z")
$params = #{canonicalizedResource="/file/storageacnt/exec";signedResource="c";signedPermission="rcw";signedProtocol="https";signedExpiry=$toDate}
$jsonParams = $params | ConvertTo-Json
$sasResponse = Invoke-WebRequest -Uri https://management.azure.com/subscriptions/xxxxxxxxxxxx/resourceGroups/rg-xxxxx/providers/Microsoft.Storage/storageAccounts/storageaccnt/listServiceSas/?api-version=2017-06-01 -Method POST -Body $jsonParams -Headers #{Authorization="Bearer $Atoken"} -UseBasicParsing
$sasContent = $sasResponse.Content | ConvertFrom-Json
$sasCred = $sasContent.serviceSasToken
write-host $sasCred
$sasToken = "?$sasCred"
Node LocalHost {
....

Get-AzAccessToken keeps returning the same Token by targeting a different tenant

I have a PowerShell Azure Function that is secured with AAD. In my script I get the id token with the following command:
$assertion = $Request.Headers['x-ms-token-aad-id-token']
I use this assertion in order to get another token to use the Azure Service Management Api with the OBO Flow. Below is the code used:
$contentType = 'application/x-www-form-urlencoded'
$body = #{
grant_type = $grantType
client_id = $clientId
client_secret = $clientSecret
scope = $scope
requested_token_use = $requestedTokenUse
assertion = $assertion
}
$oboResponse = Invoke-RestMethod 'https://login.microsoftonline.com/e005f490-xxxx-4816-xxxx-b0ed7fa9xxxx/oauth2/v2.0/token' -Method 'POST' -body $body -ContentType $contentType
$accessToken = $oboResponse.access_token
Then I use this token to connect to azure with the Connect-AzAccount command. So far, everything is good well and the connection to Azure is working fine.
In my script, I try to have different tokens to connect to other tenants to which I belong. Unfortunately, it does not work as expected. Indeed the command returns the same token for different tenants. In fact, the produced token by the command "Get-AzAccessToken -TenantId $tenant.Id" is always equal to the token produced by the OBO flow.
Below is my PowerShell Azure function. I commented the part where I have a the issue.
using namespace System.Net
# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)
$accountId = $Request.Headers['x-ms-client-principal-name']
$grantType = "urn:ietf:params:oauth:grant-type:jwt-bearer"
$clientId = "xxxx"
$clientSecret = "xxxx"
$scope = "https://management.azure.com/user_impersonation"
$requestedTokenUse = "on_behalf_of"
$assertion = $Request.Headers['x-ms-token-aad-id-token']
$contentType = 'application/x-www-form-urlencoded'
$body = #{
grant_type = $grantType
client_id = $clientId
client_secret = $clientSecret
scope = $scope
requested_token_use = $requestedTokenUse
assertion = $assertion
}
$oboResponse = Invoke-RestMethod 'https://login.microsoftonline.com/e005f490-xxxx-4816-xxxx-b0ed7fa9xxxx/oauth2/v2.0/token' -Method 'POST' -body $body -ContentType $contentType
$accessToken = $oboResponse.access_token
Connect-AzAccount -AccessToken $accessToken -AccountId $accountId
$allTenants = Get-AzTenant
foreach ($tenant in $allTenants) {
# Here I get the same access token for different tenants.
# The token is always equal to the token produced by the OBO flow.
$accessToken_ = Get-AzAccessToken -TenantId $tenant.Id
....
....
}
...
...
I don't understand why the token produced by the OBO flow is always equal to the token produced by Get-AzAccessToken. I hope I have described my problem correctly, thank you for your help.
Thank you.
I think the problem is due to your Invoke-RestMethod call using a static tenant ID/GUID:
$oboResponse = Invoke-RestMethod 'https://login.microsoftonline.com/e005f490-xxxx-4816-xxxx-b0ed7fa9xxxx/oauth2/v2.0/token' -Method 'POST' -body $body -ContentType $contentType
https://login.microsoftonline.com/{**tenant**}/oauth2/v2.0/token

Managed Identity read access to Azure Storage Blob & Table with PowerShell

I've been trying to get access to a storage blob (and table in future) with a managed identity in Azure Automation, but unfortunately I can't get it to work.
The Managed Identity has the following permissions on the Blob:
Contributor
Managed Application Operator Role
Storage Blob Data Contributor
Storage Table Data Contributor
I've tried several resources to get my accesstoken:
'https://storage.azure.com/'
'https://STORAGE.blob.core.windows.net/'
I do get the AccessToken for both resources, yet I still get the famous 403 forbidden errors.
This is the Uri I use to access the blob:
'https://{0}.blob.core.windows.net/{1}{2}' -f $($Storage), $Container, $FileName
My invoke uses the Get method:
$InvokeSplatting = #{
Uri = $Uri
Method = 'Get'
headers = $Headers
}
The header contains the AccessToken: "Bearer ~"
Am I doing something wrong?
PS: the script did work with a SASToken, so something must be up with the AccessToken.
function New-ManagedIdentityAccessToken {
<#
.SYNOPSIS
Short description
.DESCRIPTION
Resources:
'https://vault.azure.net'
'https://management.azure.com'
'https://storage.azure.com/'
.PARAMETER Resource
Parameter description
.EXAMPLE
An example
.NOTES
General notes
#>
[CmdletBinding()]
param (
[parameter(mandatory = $true)]
$Resource
)
begin {
$url = $env:IDENTITY_ENDPOINT
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("X-IDENTITY-HEADER", $env:IDENTITY_HEADER)
$headers.Add("Metadata", "True")
$body = #{resource = $Resource }
}
process {
$accessToken = Invoke-RestMethod $url -Method 'POST' -Headers $headers -ContentType 'application/x-www-form-urlencoded' -Body $body
$Headers = #{
Authorization = "Bearer $($accessToken.access_token)"
}
}
end {
return $Headers
}
}

Is it possible to update URL is availability test in application insights through powershell on a schedule task/frequency

I have a number of environments in azure which utilize on-premise Restful services for one of our customers. We currently have application insights configured within a resource group, and an availability test configured to ping a URL at a specified frequency, configured with an insights alert (email when goes down)
An access token is embedded into the URL which needs to be updated frequently. Is it possible to update the URL highlighted programmatically to replace the token (Scheduled/automated basis )
Just wondering what technologies could be used to update an availability URL on a scheduled basis (every two weeks)
Azure functions?
Some sort of PowerShell script as a scheduled task?
ARM templates using the example here https://learn.microsoft.com/en-us/azure/azure-monitor/app/powershell#add-an-availability-test
Any advice on how to proceed with this task efficiently and using the most appropriate technologies would be appreciated.
I have to say seems there is no PowerShell module provided to modify the url of App Insight webtest , but we can do it via REST API . Try the PowerShell below :
$clientId = "<your Azure AD application ID>"
$clientSec="<your Azure AD application secret>"
$appInsightName ="<your app insight name>"
$webtestName="<your webtest name>"
$subscriptionId = "<your subscription ID>"
$resourceGroupName = "<your resource group name that your app insight in>"
$tenant = "<your tenant name/ID>"
$newUrl = "<the new URL>"
#get access token to fetch details of webtest
$body=#{
    "grant_type"="client_credentials";
    "resource"="https://management.azure.com/";
    "client_id"= $clientId;
    "client_secret" = $clientSec
}
$accessToken=(Invoke-RestMethod -Uri "https://login.windows.net/$tenant/oauth2/token" -Method POST -Body $body ).access_token
$uri = "https://management.azure.com/subscriptions/{0}/resourcegroups/{1}/providers/microsoft.insights/webtests/{2}-{3}?api-version=2015-05-01"
$uri = $uri.Replace("{0}",$subscriptionId).Replace("{1}",$resourceGroupName).Replace("{2}",$webtestName).Replace("{3}",$appInsightName)
$webtestResult = Invoke-RestMethod -Uri $uri -Method GET -Headers #{"Authorization"="Bearer $accessToken"}
#modify the url of webtest
$webTestConf = [xml]#($webtestResult.properties.Configuration.WebTest)
$webTestConf.WebTest.Items.Request.Url = $newUrl
#structure request json to update webtest
$locations = $webtestResult.properties.Locations | ConvertTo-Json
$Configuration = $webTestConf.WebTest.OuterXml | ConvertTo-Json
$Configuration = $Configuration.Replace("\u003c","<").replace("\u003e",">")
$location = $webtestResult.location
$tags = $webtestResult.tags| ConvertTo-Json
$name = $webtestResult.properties.Name
$kind = $webtestResult.properties.Kind
$json = #"
{
"location":"$location",
"tags":$tags,
"properties":{
"Name":"$name",
"Enabled": true,
"Frequency": 300,
"Timeout": 120,
"Locations":$locations,
"Configuration":{"webtest":$Configuration},
"Kind":"$kind"
}
}
"#
Invoke-RestMethod -Uri $uri -Method PUT -Body $json -Headers #{"Authorization"="Bearer $accessToken";"Content-Type"="application/json"}
Except for Azure function, you can use Azure automation powershell Runbook with scheduled task to meet your requirement .
Btw, this powershell demo uses service principle to connect to your Azure subscription, make sure your Azure ad application has permission to modify your app insight. If you have anything unclear , pls feel free to let me know . This issue shall not be passed !

Azure DevOps REST API returns a 403 when using the system OAuth token during a build

I'm running a script:
# Variables
$organization = "****"
$project = "****"
$repositoryId = "****"
$pullRequestId = $env:BUILD_PULLREQUEST_ID
$pat = "Bearer $env:System_AccessToken"
$featureReleaseUrl = "http://" + $env:prSourceBranchName + ".azurewebsites.net"
$body = #"
{
"comments": [
{
"content": "Link naar feature release $featureReleaseUrl"
}
]
}
"#
$createThreadInPRUrl = "https://dev.azure.com/$organization/$project/_apis/git/repositories/$repositoryId/pullRequests/$pullRequestId/threads?api-version=5.0"
if ($pullRequestId) {
Invoke-RestMethod -Uri $createThreadInPRUrl -Headers #{Authorization = $pat} -Body $body -Method Post -ContentType 'application/json'
}
When it runs it returns a:
##[error]The remote server returned an error: (403) Forbidden.
I've created a Personal Access Tokens in my personal settings.
I've also created this script:
# Variables
$organization = "****"
$project = "****"
$buildId = $****
$pat = "Bearer $env:System_AccessToken"
if (!$env:Build_PullRequest_SourceBranchName) {
$retrieveSourceBranchFromBuildURL = "https://dev.azure.com/$organization/$project/_apis/build/builds/$buildId" + "?api-version=5.0"
$buildInformation = Invoke-RestMethod -Uri $retrieveSourceBranchFromBuildURL -Headers #{Authorization = $pat } -Method Get -ContentType 'application/json'
$SourceBranchFromBuild = $buildInformation.sourceBranch.split('/')[-1]
Write-Host "### no Build PullRequest SourceBranchName available ###"
Write-Host "##vso[task.setvariable variable=prSourceBranchName;]"$SourceBranchFromBuild
}
And this runs fine. The difference between the first and second script is that the first is a POST and the second a GET. But they both use the $pat token.
Even though the token you used is System.AccessToken, if you don't have access permission of Pull Request, you will also could not operate it.
Go Project Setting--> Repositories--> Repository you want to access, locate your account or the group you are in. Check the permission state of Contribute to pull requests.
You must have this Contribute to pull requests permission allowed, so that you can add the comment to PR.

Resources