How to add Extension Properties for Azure-AD Device Objects using PowerShell? - azure

I want to add extension properties for device objects in Azure AD using Power-Shell. I have search a lot but found examples for only User objects.I have written a script and its successful for User Objects but am not be able to set extension properties for Device.
A command Set-AzureADUserExtension
exists for User but for devices, there is no such commands e.g
Set-AzureADDeviceExtension
(there is no command exists like it). Can anyone help me how to achieve this?How can i set extension properties for Device Objects?
I want to achieve something like this:
New-AzureADApplicationExtensionProperty -ObjectId $MyApp -Name "MyNewProperty" -DataType "String" -TargetObjects "Device";
Set-AzureADDeviceExtension -ObjectId $deviceId -ExtensionName "extension_0380f0f700c040b5aa577c9268940b53_MyNewProperty" -ExtensionValue "MyNewValue";

I was looking for exactly the same and I did not find anything then and today either. I had to use the Microsoft Graph API to add new extensions to the device object. The same for consulting.
Step 1: Install or import the azure module.
Install-Module AzureAD
or
Import-Module AzureAD
Step 2: Search Object and save ObjectID.
$ObjectID = (Get-AzureADDevice -SearchString 'Object-Name').ObjectId
Note: The "id" in the request is the "id" property of the device, not the "deviceId" property.
Step 3: Create App
https://portal.azure.com - Azure Active Directory - App registrations - New registration
Name: YourAppName
Supported account types: Accounts in this organizational directory only (Default Directory)
Redirect URI: (WEB) https://login.microsoftonline.com/common/oauth2/nativeclient
Step 4: Configure App
https://portal.azure.com - Azure Active Directory - App registrations - YourAppName
Certificates & secrets - New client secret
Save client secret value
API permissions - Add a permission - Microsoft Graph - Delegated permissions
Directory.AccessAsUser.All
Step 5: Get access_token
## Directory.AccessAsUser.All : Minimun privilege for Get, add, update and delete extensions. (https://learn.microsoft.com/en-us/graph/api/opentypeextension-post-opentypeextension?view=graph-rest-1.0)
$scopes = "Directory.AccessAsUser.All"
$redirectURL = "https://login.microsoftonline.com/common/oauth2/nativeclient"
$clientID = "YourAppIdClient"
$clientSecret = [System.Web.HttpUtility]::UrlEncode("YourAppClientSecret")
$authorizeUrl = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize"
$requestUrl = $authorizeUrl + "?scope=$scopes"
$requestUrl += "&response_type=code"
$requestUrl += "&client_id=$clientID"
$requestUrl += "&redirect_uri=$redirectURL"
$requestUrl += "&response_mode=query"
Write-Host
Write-Host "Copy the following URL and paste the following into your browser:"
Write-Host
Write-Host $requestUrl -ForegroundColor Cyan
Write-Host
Write-Host "Copy the code querystring value from the browser and paste it below."
Write-Host
$code = Read-Host -Prompt "Enter the code"
$body = "client_id=$clientID&client_secret=$clientSecret&scope=$scopes&grant_type=authorization_code&code=$code&redirect_uri=$redirectURL"
$tokenUrl = "https://login.microsoftonline.com/common/oauth2/v2.0/token"
$response = Invoke-RestMethod -Method Post -Uri $tokenUrl -Headers #{"Content-Type" = "application/x-www-form-urlencoded"} -Body $body
$token = $response.access_token
Get Extensions device
$apiUrl = 'https://graph.microsoft.com/v1.0/devices/<ID-Object>/extensions' ## change <ID-Object> for your ObjectID.
(https://learn.microsoft.com/en-us/graph/api/device-get?view=graph-rest-1.0&tabs=cs)
$Data = Invoke-RestMethod -Headers #{Authorization = "Bearer $accessToken"} -Uri $apiUrl -Method Get
$Data.Value | fl
Add extensions device
$apiUrl = 'https://graph.microsoft.com/v1.0/devices/<ID-Object>/extensions'
$body = '{
"#odata.type": "microsoft.graph.openTypeExtension",
"id": "test.extension",
"name_extension": "example"
}'
Invoke-RestMethod -Headers #{Authorization = "Bearer $token"; "Content-type" = "application/json"} -Uri $apiUrl -Method Post -Body $body
Update extensions device
## Actualizar datos de una extensión
$apiUrl = 'https://graph.microsoft.com/v1.0/devices/<ID-Object>/extensions/test.extension' ## Extension ID to update
$body = '{
"#odata.type": "microsoft.graph.openTypeExtension",
"id": "test.extension",
"name_extension": "new_value"
}'
Invoke-RestMethod -Headers #{Authorization = "Bearer $token"; "Content-type" = "application/json"} -Uri $apiUrl -Method Patch -Body $body
Delete extensions device
$apiUrl = 'https://graph.microsoft.com/v1.0/devices/<ID-Object>/extensions/test.extension'
Invoke-RestMethod -Headers #{Authorization = "Bearer $token"; "Content-type" = "application/json"} -Uri $apiUrl -Method Delete

Related

Unable to create Azure B2C User Flow via powershell with b2cIdentityUserFlow

I am trying to create a user flow with PowerShell, but I receiveThe remote server returned an error: (403) Forbidden.. I was reading the documentation from Microsoft but with no success.
Connect-AzAccount -Tenant "myorg.onmicrosoft.com"
$managementAccessToken = Get-AzAccessToken -TenantId "$tenantId" -ResourceTypeName MSGraph
$DefinitionFilePath = "C:\azdeploy\flows\b2csignin.json"
$signinFlowContent = Get-Content $DefinitionFilePath
Invoke-WebRequest -Uri "https://graph.microsoft.com/beta/identity/b2cUserFlows" `
-Method "POST" `
-Headers #{
"Content-Type" = "application/json"
"Authorization" = "Bearer $($managementAccessToken.Token)";
} `
-Body $signinFlowContent
JSON Content(Default From Microsoft Docs):
{
"id": "Customer",
"userFlowType": "signUpOrSignIn",
"userFlowTypeVersion": 3
}
Connect-AzAccount is made with a user who is Global Administrator, also tried with Lifecycle Workflows Administrator permissions. I don't know what to do, trying the old API but it is deprecated. I need to create a few User Flows with а few Application Claims. How can I achieve this?
Thanks!
I tried to reproduce the same in my environment and got below results:
I created one json file with same parameters as you like below:
I have one user named Sritest having Global Administrator role like below:
When I ran the same code as you by signing in with above user, I got same error as below:
Connect-AzAccount -Tenant "myorg.onmicrosoft.com"
$managementAccessToken = Get-AzAccessToken -TenantId "$tenantId" -ResourceTypeName MSGraph
$DefinitionFilePath = "C:\test\b2csignin.json"
$signinFlowContent = Get-Content $DefinitionFilePath
Invoke-WebRequest -Uri "https://graph.microsoft.com/beta/identity/b2cUserFlows" `
-Method "POST" `
-Headers #{
"Content-Type" = "application/json"
"Authorization" = "Bearer $($managementAccessToken.Token)";
} `
-Body $signinFlowContent
Response:
You need to have IdentityUserFlow.ReadWrite.All permission to create userflow.
To resolve the error, I registered one Azure AD application and added that API permission like below:
Make sure to grant admin consent after adding API permissions in application. Now, I created one client secret and added all these details in getting access token by modifying PowerShell code.
When I ran below modified code, userflow created successfully as below:
Connect-AzureAD -TenantId "c6d99123-0cf9-4b64-bde3-xxxxxxxxx"
$graphtokenBody = #{
grant_type = "client_credentials"
scope = "https://graph.microsoft.com/.default"
client_id = "appID"
client_secret = "secret"
}
$graphToken = Invoke-RestMethod -Uri "https://login.microsoftonline.com/c6d99123-0cf9-4b64-bde3-xxxxxxxxx/oauth2/v2.0/token" -Method POST -Body $graphtokenBody
$token = $graphToken.access_token
$DefinitionFilePath = "C:\test\b2csignin.json"
$signinFlowContent = Get-Content $DefinitionFilePath
Invoke-WebRequest -Uri "https://graph.microsoft.com/beta/identity/b2cUserFlows" `
-Method "POST" `
-Headers #{
"Content-Type" = "application/json"
"Authorization" = "Bearer $($token)";
} `
-Body $signinFlowContent
Response:
To confirm that, I checked the same in Portal where B2C_1_Customer userflow is present like below:

Azure Databricks API

Trying to use the Databricks API to work with resources programmatically. I am using this microsoft documentto authenticate with a service principal.
https://learn.microsoft.com/en-us/azure/databricks/dev-tools/api/latest/aad/service-prin-aad-token
But I'm getting the following error
"Invoke-RestMethod : {"error":"invalid_resource","error_description":"AADSTS500011: The resource principal named
https://management.core.azure.com was not found in the tenant"
This is my full script. What am I missing?
$ApiCommand = "clusters/get"
$DataBrick = "https://adb-3522222096750220.0.azuredatabricks.net"
$DataBricksResourceID = ""
$VaultName = ""
$KeyName = ""
$apiEndpointUri = "https://management.core.azure.com"
$tenantId = ""
$applicationId = ""
$secret = Get-AzKeyVaultSecret -VaultName $VaultName -Name $KeyName -AsPlainText
$RequestAccessTokenUri = "https://login.microsoftonline.com/$tenantId/oauth2/token"
$body = "grant_type=client_credentials&client_id=$applicationId&client_secret=$secret&resource=2ff814a6-3304-4ab8-85cb-cd0e6f879c1d"
$Managementbody = "grant_type=client_credentials&client_id=$applicationId&client_secret=$secret&resource=$apiEndpointUri"
$contentType = 'application/x-www-form-urlencoded'
$AccessToken = Invoke-RestMethod -Method Post -Uri $RequestAccessTokenUri -Body $body -ContentType $contentType
Write-Output $AccessToken
$ManagementToken = Invoke-RestMethod -Method Post -Uri $RequestAccessTokenUri -Body $Managementbody -ContentType $contentType
Write-Output $ManagementToken
$apiuri = $DataBrick +"/api/2.0/$ApiCommand"
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", "Bearer " + $AccessToken.access_token)
$headers.Add("X-Databricks-Azure-SP-Management-Token", $ManagementToken.access_token)
$headers.Add("X-Databricks-Azure-Workspace-Resource-Id", $DataBricksResourceID)
Invoke-RestMethod -Uri $apiuri -Headers $headers
The trailing / character in the management endpoint URI is really important - you need to specify it as in the documentation: https://management.core.windows.net/
You can also add this SP into the workspace itself, then you will need to get only one AAD token (see the docs).

List Cloud Service Classic use PowerShell and Azure Rest API

I Have a problem. Could you please help me view list Cloud Service Classic use PowerShell and Azure Rest API. When I used script for Web APP I show list Web APP, but when I used scrip for Cloud Service Classic I show error.
# Variables
$TenantId = "" # Enter Tenant Id.
$ClientId = "" # Enter Client Id.
$ClientSecret = "" # Enter Client Secret.
$Resource = "https://management.core.windows.net/"
$SubscriptionId = "" # Enter Subscription Id.
$RequestAccessTokenUri = "https://login.microsoftonline.com/$TenantId/oauth2/token"
$body = "grant_type=client_credentials&client_id=$ClientId&client_secret=$ClientSecret&resource=$Resource"
$Token = Invoke-RestMethod -Method Post -Uri $RequestAccessTokenUri -Body $body -ContentType 'application/x-www-form-urlencoded'
Write-Host "Print Token" -ForegroundColor Green
Write-Output $Token
# Get Azure Resource Groups
$ResourceGroupApiUri = "https://management.core.windows.net/$SubscriptionId/services/hostedservices"
$Headers = #{}
$Headers.Add("Authorization","$($Token.token_type) "+ " " + "$($Token.access_token)")
$ResourceGroups = Invoke-RestMethod -Method Get -Uri $ResourceGroupApiUri -Headers $Headers
Write-Host "Print Resource groups" -ForegroundColor Green
Write-Output $ResourceGroups
Invoke-RestMethod : ForbiddenErrorThe server failed to authenticate the request. Verify that the certificate is valid and
is associated with this subscription.
Actually, there is a built-in ASM PowerShell to list the cloud services associated with the current subscription.
Get-AzureService
Reference - https://learn.microsoft.com/en-us/powershell/module/servicemanagement/azure/get-azureservice?view=azuresmps-4.0.0
Besides, if you insist on calling the ASM rest api with powershell, you could refer to this article, the sample calls the Get Deployment api, just change it to List Cloud Services.
#Request Headers required to invoke the GET DEPLOYMENT REST API
$method
=
“GET”
$headerDate
= ‘2009-10-01’
$headers
= #{“x-ms-version”=“$headerDate“}
#Retrieving the subscription ID
$subID
= (Get-AzureSubscription
-Current).SubscriptionId
$URI
=
https://management.core.windows.net/$subID/services/hostedservices/kaushalz/deployments/4f006bb7d2874dd4895f77a97b7938d0
#Retrieving the certificate from Local Store
$cert
= (Get-ChildItem
Cert:\CurrentUser\My
|
?{$_.Thumbprint -eq
“B4D460D985F1D07A6B9F8BFD67E36BC53A4490FC”}).GetRawCertData()
#converting the raw cert data to BASE64
body
=
“<Binary>—–BEGIN CERTIFICATE—–`n$([convert]::ToBase64String($cert))`n—–END CERTIFICATE—–</Binary>”
#Retrieving the certificate ThumbPrint
$mgmtCertThumb
= (Get-AzureSubscription
-Current).Certificate.Thumbprint
#Passing all the above parameters to Invoke-RestMethod cmdlet
Invoke-RestMethod
-Uri
$URI
-Method
$method
-Headers
$headers
-CertificateThumbprint
” B4D460D985F1D07A6B9F8BFD67E36BC53A4490FC”
-ContentType
$ContentType

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.

How to fix "401 Unauthorized" error in PUT Invoke-RestMethod (trying to replace stored procedure)

I'm trying to manage CosmosDB resources using REST API and PowerShell.
My code works fine when I use GET and POST, but when I try to replace an existing object using PUT, I get 401 error.
My code registers stored procedure when it doesn't exist and should update it when the SP already exists.
So when I create a new SP, I use the following variables:
$Verb = "POST"
$ResourceType = "sprocs"
$ResourceLink = "dbs/$DBName/colls/$CollName"
$queryUri = "$CosmosDBEndPoint$ResourceLink/$ResourceType"
get auth header:
...
$authHeader = Generate-MasterKeyAuthorizationSignature -verb $Verb -resourceLink $ResourceLink -resourceType $ResourceType -key $MasterKey -keyType "master" -tokenVersion "1.0" -dateTime $dateTime
and then call REST method:
$header = #{authorization=$authHeader;"x-ms-version"="2017-02-22";"x-ms-date"=$dateTime}
$contentType= "application/json"
Invoke-RestMethod -Method $Verb -ContentType $contentType -Uri $queryUri -Headers $header -Body $body
It works great and creates what it should.
And, when I need to replace existing object (SP in my case), I change variables like this:
$Verb = "PUT"
$ResourceType = "sprocs"
$ResourceLink = "dbs/$DBName/colls/$CollName"
$ItemName = "SP_Name"
$queryUri = "$CosmosDBEndPoint$ResourceLink/$ResourceType/$ItemName"
generate auth header just like in case with POST (only verb is different):
...
$authHeader = Generate-MasterKeyAuthorizationSignature -verb $Verb -resourceLink $ResourceLink -resourceType $ResourceType -key $MasterKey -keyType "master" -tokenVersion "1.0" -dateTime $dateTime
...
and the invoke REST method with new URI (which includes now name of SP to be changed):
$header = #{authorization=$authHeader;"x-ms-version"="2017-02-22";"x-ms-date"=$dateTime}
$contentType= "application/json"
Invoke-RestMethod -Method $Verb -ContentType $contentType -Uri $queryUri -Headers $header -Body $body
Which is throws me 401 Unauthorized, so it seems that auth header isn't right. Can't figure out what I should change there.
From here it looks like the resource or the value in the resource you are trying to change does not support a PUT action. You can confirm manually;
https://learn.microsoft.com/en-us/rest/api/cosmos-db/
or by going to;
https://resources.azure.com/
So the key was to change variables this way:
$ResourceType = "sprocs"
$ItemName = "SP_Name"
$ResourceLink = "dbs/$DBName/colls/$CollName/$ResourceType/$ItemName"
and then generate auth header.
I.e. resource link variable must contain the full path to the replaced object.

Resources