I am trying to make a powershell script to bulk import users to an enterprise application but keep receiving errors - azure

Here is the code that I have written and modified several times, but still cannot get to work. Any help would be greatly appreciated. I keep receiving the following errors:
Get-AzureADUser : Cannot bind argument to parameter 'ObjectId' because it is null** and **New-AzureADUserAppRoleAssignment : Cannot bind argument to parameter 'ObjectId' because it is null.
# Assign the global values to the variables for the script.
$app_name = "App Name"
$app_role_name = "User"
$users = Get-Content 'Path\Users.txt'
$Credential=Get-StoredCredential -UserName #####
# Connect to Azure AD using Azure AD Powershell
Connect-AzureAD -Credential $Credential
# Get the user to assign, and the service principal for the app to assign to
foreach ($user in $users) {
$AADuser = Get-AzureADUser -ObjectId $user
$sp = Get-AzureADServicePrincipal -Filter "displayName eq '$app_name'"
$appRole = $sp.AppRoles | Where-Object { $_.DisplayName -eq $app_role_name }
# Assign the user to the app role
New-AzureADUserAppRoleAssignment -ObjectId $user.ObjectId -PrincipalId $user.ObjectId -ResourceId $sp.ObjectId -Id $appRole.Id
}'''

Related

Update App Registration Approles by Microsoft Graph API Patch method returns always Unable to read JSON request payload

On a App Registration I want to remove the App Roles by first disable the active ones and afterwards removing them.
I checked the commands by the developer tools what is executed and I come to the following request:
$graphApiUrl = 'https://graph.microsoft.com/v1.0/applications'+'/'+$apiAppReg.appId
$body = '{"appRoles":[{"description":"Applications can read","displayName":"Reader","id":"xxxxxxx-xxxx-xxxx-xxxx-xxxxxx","isEnabled":false,"value":"Read","allowedMemberTypes":["Application"]}]}
'
az rest --method PATCH --url $graphApiUrl --headers 'Content-Type=application/json' --body '$body'
I tried this in all orders, but it seems that this is resulting in an error.
btw. the boby is copy from the request from the azure website
After reproducing from my end, I could able to achieve your requirement using PowerShell. To Disable the App Role I have set IsEnabled=$false for each app role in my Application.
Below is the script that worked for me to disable the app role.
$App = Get-AzureADApplication -Filter "appId eq '$appId'"
$AppRoles = $app.AppRoles
for($I=0;$I -lt $AppRoles.Count;$I++)
{
$app.AppRoles[$I].IsEnabled=$false
Set-AzureADApplication -ObjectId $app.ObjectId -AppRoles $AppRoles
}
To Remove the app roles from the application I have used $AppRoles.Remove($AppRoles[$I]). Below is the complete code that worked to delete the app roles from my Application.
for($I=0;$I -lt $AppRoles.Count;$I++)
{
$AppRoles.Remove($AppRoles[$I])
Set-AzureADApplication -ObjectId $app.ObjectId -AppRoles $AppRoles
}
Below is the complete working code
Connect-AzureAD
$AppId = "<APPLICATION_ID>"
$ObjectId = "<OBJECT_ID>"
$App = Get-AzureADApplication -Filter "appId eq '$appId'"
$AppRoles = $app.AppRoles
for($I=0;$I -lt $AppRoles.Count;$I++)
{
$app.AppRoles[$I].IsEnabled=$false
Set-AzureADApplication -ObjectId $app.ObjectId -AppRoles $AppRoles
}
for($I=0;$I -lt $AppRoles.Count;$I++)
{
$AppRoles.Remove($AppRoles[$I])
Set-AzureADApplication -ObjectId $app.ObjectId -AppRoles $AppRoles
}

Add device objects to the Azure group in Powershell foreach

I am trying to run a simple Powershell command let, which is listing all devices matching name criteria and in the next step is moving these devices to a select Azure group.
I tried with:
$result = Get-AzureADDevice -All $True -SearchString "LAP-BK" | ForEach-Object -Process {Add-AzureADGroupMember -ObjectId "25f94620-d850-4ec6-9476-050429d44926" -RefObjectId "$result.ObjectId"}
but that throwing errors. I also tried with
$result = Get-AzureADDevice -All $True -SearchString "LAP-BK" |Select-Object ObjectId
forEach ($item in $result)
{
Add-AzureADGroupMember -ObjectId "25f94620-d850-4ec6-9476-050429d44926" -RefObjectId "$item"
}
exit
The error are various, the last one I get was:
Error occurred while executing AddGroupMember Code: Request_BadRequest Message: Invalid object identifier ' #{ObjectId=debb95af-9h1f-49d6-ad84-8438f9c99b10}'. RequestId: 6df36830-7708-4f6b-b836-cd065f5f60b1
I tried to figure out the error from my end by running your script line by line, and I was able to find exactly where it was occurring:
Referring to Jamesyumnam article, I was able to successfully create and run the below script.
$groupName = "<groupName>"
Connect-AzureAD
$groupObject = Get-AzureADGroup -SearchString $groupName
$outcome = Get-AzureADDevice -SearchString "xxxxxx" | select-object objectID
try{
foreach ($item in $outcome)
{
$deviceObj = Get-AzureADDevice -SearchString $item.DeviceName
Add-AzureADGroupMember -ObjectId $groupObject.ObjectId -RefObjectId $item.ObjectId
}
}
catch {
Write-Host "Device not existed"
}
Executed in Azure PowerShell:
Member added in Azure Portal:
Note: It will be more helpful if you include try{} catch{} blocks in your code to find these kinds of blockers.

Graph API permissions not removed from system assigned Managed Identity

I successfully assigned and am able to use Graph API Permissions in a system assigned Managed Identity context. However, I wanted to amend the permission scope. Using
$sp = Get-AzureADServicePrincipal -ObjectId "31dd2948-d2ed-49e8-a47c-188b607a3cf1" # AzureAutomationTest
# $sp = Get-AzureADServicePrincipal -ObjectId "ff628842-99a2-4d9c-990b-c008e7942efd" # AzureAutomationProd
# Get all delegated permissions for the service principal
$spOAuth2PermissionsGrants = Get-AzureADOAuth2PermissionGrant -All $true | Where-Object { $_.clientId -eq $sp.ObjectId }
# Remove all delegated permissions
$spOAuth2PermissionsGrants | ForEach-Object {
Remove-AzureADOAuth2PermissionGrant -ObjectId $_.ObjectId
}
# Get all application permissions for the service principal
$spApplicationPermissions = Get-AzureADServiceAppRoleAssignedTo -ObjectId $sp.ObjectId -All $true | Where-Object { $_.PrincipalType -eq "ServicePrincipal" }
# Remove all delegated permissions
$spApplicationPermissions | ForEach-Object {
Remove-AzureADServiceAppRoleAssignment -ObjectId $_.PrincipalId -AppRoleAssignmentId $_.objectId
}
I'm able to visibly delete the permissions from the https://portal.azure.com/#blade/Microsoft_AAD_IAM/ManagedAppMenuBlade/Permissions menu. However, it's not taking effect and it still works in the background.
Any idea?
Thanks.

How to Add Api Permissions to an Azure App Registration using PowerShell

I am figure out the commands in Azure PowerShell to add an the User.Read Ape Permission to my App Registration in Azure.
I can find some examples using *Azure, but would prefer one that uses the *Az commands, e.g. https://learn.microsoft.com/en-us/powershell/azure/?view=azps-2.8.0.
Wonder if anybody knows how to do this? Thanks!
This can currently only be achieved using the Azure AD PowerShell. Please note that there is a difference between Azure AD PowerShell and Azure PowerShell. The Azure AD PowerShell is not simply the old Azure PowerShell module.
Azure AD PowerShell is a separate module. There is no "AZ*" for Azure AD yet. Only couple of most commonly used commands, that have Azure Resource Provider implementation.
Azure PowerShell has a limited set of features for working with Azure AD. If you need more features, like the one you mention, you must use Azure AD PowerShell. Azure AD PowerShell is not depricated and is the officially supported PowerShell module for working with Azure AD.
You can manage these required permissions by the Set-AzureAdApplication cmdlet and passing proper -RequiredResourceAccess object.
In order to construct this object, you must first get a reference to "exposed" permissions. Because permissions are exposed by other service principals.
as I cannot upload whole file, here is a PowerShell script that creates a sample application with required permission to some MS Graph and some Power BI permissions.
Function GetToken
{
param(
[String] $authority = "https://login.microsoftonline.com/dayzure.com/oauth2/token",
[String] $clientId,
[String] $clientSecret,
[String] $resourceId = "https://graph.windows.net"
)
$scope = [System.Web.HttpUtility]::UrlEncode($resourceId)
$encSecret = [System.Web.HttpUtility]::UrlEncode($clientSecret)
$body = "grant_type=client_credentials&resource=$($scope)&client_id=$($clientId)&client_secret=$($encSecret)"
$res = Invoke-WebRequest -Uri $authority -Body $body -Method Post
$authResult = $res.Content | ConvertFrom-Json
return $authResult.access_token
}
#`
# -RequiredResourceAccess #($requiredResourceAccess)
#
Function CreateChildApp
{
param (
[string] $displayName,
[string] $tenantName
)
# create your new application
Write-Output -InputObject ('Creating App Registration {0}' -f $displayName)
if (!(Get-AzureADApplication -SearchString $displayName)) {
$app = New-AzureADApplication -DisplayName $displayName `
-Homepage "https://localhost" `
-ReplyUrls "https://localhost" `
-IdentifierUris ('https://{0}/{1}' -f $tenantName, $displayName)
# create SPN for App Registration
Write-Output -InputObject ('Creating SPN for App Registration {0}' -f $displayName)
# create a password (spn key)
$appPwd = New-AzureADApplicationPasswordCredential -ObjectId $app.ObjectId
$appPwd
# create a service principal for your application
# you need this to be able to grant your application the required permission
$spForApp = New-AzureADServicePrincipal -AppId $app.AppId -PasswordCredentials #($appPwd)
}
else {
Write-Output -InputObject ('App Registration {0} already exists' -f $displayName)
$app = Get-AzureADApplication -SearchString $displayName
}
#endregion
return $app
}
Function GrantAllThePermissionsWeWant
{
param
(
[string] $targetServicePrincipalName,
$appPermissionsRequired,
$childApp,
$spForApp
)
$targetSp = Get-AzureADServicePrincipal -Filter "DisplayName eq '$($targetServicePrincipalName)'"
# Iterate Permissions array
Write-Output -InputObject ('Retrieve Role Assignments objects')
$RoleAssignments = #()
Foreach ($AppPermission in $appPermissionsRequired) {
$RoleAssignment = $targetSp.AppRoles | Where-Object { $_.Value -eq $AppPermission}
$RoleAssignments += $RoleAssignment
}
$ResourceAccessObjects = New-Object 'System.Collections.Generic.List[Microsoft.Open.AzureAD.Model.ResourceAccess]'
foreach ($RoleAssignment in $RoleAssignments) {
$resourceAccess = New-Object -TypeName "Microsoft.Open.AzureAD.Model.ResourceAccess"
$resourceAccess.Id = $RoleAssignment.Id
$resourceAccess.Type = 'Role'
$ResourceAccessObjects.Add($resourceAccess)
}
$requiredResourceAccess = New-Object -TypeName "Microsoft.Open.AzureAD.Model.RequiredResourceAccess"
$requiredResourceAccess.ResourceAppId = $targetSp.AppId
$requiredResourceAccess.ResourceAccess = $ResourceAccessObjects
# set the required resource access
Set-AzureADApplication -ObjectId $childApp.ObjectId -RequiredResourceAccess $requiredResourceAccess
Start-Sleep -s 1
# grant the required resource access
foreach ($RoleAssignment in $RoleAssignments) {
Write-Output -InputObject ('Granting admin consent for App Role: {0}' -f $($RoleAssignment.Value))
New-AzureADServiceAppRoleAssignment -ObjectId $spForApp.ObjectId -Id $RoleAssignment.Id -PrincipalId $spForApp.ObjectId -ResourceId $targetSp.ObjectId
Start-Sleep -s 1
}
}
cls
#globaladminapp
$clientID = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
$key = "****"
$tenantId = "aaaaaaaa-bbbb-xxxx-yyyy-aaaaaaaaaaaa";
$TenantName = "customdomain.com";
$AppRegName = "globaladminChild-0003";
$token = GetToken -clientId $clientID -clientSecret $key
Disconnect-AzureAD
Connect-AzureAD -AadAccessToken $token -AccountId $clientID -TenantId $tenantId
$appPermissionsRequired = #('Application.ReadWrite.OwnedBy', 'Device.ReadWrite.All', 'Domain.ReadWrite.All')
$targetServicePrincipalName = 'Windows Azure Active Directory'
#$appPermissionsRequired = #('Files.ReadWrite.All','Sites.FullControl.All','Notes.ReadWrite.All')
#$targetServicePrincipalName = 'Microsoft Graph'
$app = CreateChildApp -displayName $AppRegName -tenantName $TenantName
$spForApp = Get-AzureADServicePrincipal -Filter "DisplayName eq '$($AppRegName)'"
$appPermissionsRequired = #('Tenant.ReadWrite.All')
$targetServicePrincipalName = 'Power BI Service'
GrantAllThePermissionsWeWant -targetServicePrincipalName $targetServicePrincipalName -appPermissionsRequired $appPermissionsRequired -childApp $app -spForApp $spForApp
$appPermissionsRequired = #('Files.ReadWrite.All','Sites.FullControl.All','Notes.ReadWrite.All')
$targetServicePrincipalName = 'Microsoft Graph'
GrantAllThePermissionsWeWant -targetServicePrincipalName $targetServicePrincipalName -appPermissionsRequired $appPermissionsRequired -childApp $app -spForApp $spForApp
The interesting parts are around "apppermissionrequired" and "targetserviceprincipalname" variables.
I can't reply to Rolfo's comment directly as I don't have enough clout yet. While it's true it's not dead simple, it's possible to use both in the same session as of July 2021. Not sure this was always the case, or something was updated to allow it.
#Import modules if needed
$mList = #("AzureAD","Az.Resources","Az.Accounts")
foreach($m in $mList){if ((gmo -l $m).Count -eq 0){Install-Module -Name $m -AllowClobber -Scope CurrentUser -Force}}
#Authentication Popup
Connect-AzAccount
#Use authentication context cached from above to authenticate to AAD graph
$IDObject = Get-AzAccessToken -Resource "https://graph.windows.net"
Connect-AzureAD -AadAccessToken $IDObject.token -AccountId $IDObject.UserId
UPDATE
With the new Graph API we can use the following command to add API permissions to an App Registration/Service Principal using PowerShell. It's much simpler than the old process.
Add-AzADAppPermission -ApplicationId "$spId" -ApiId "00000009-0000-0000-c000-000000000000" -PermissionId "7504609f-c495-4c64-8542-686125a5a36f"
(This is the case for the PowerBI API)
If deploying via an Azure Devops Pipeline I often recommend using the following script to authenticate into AAD:
echo "Install Azure AD module..."
Install-Module -Name "AzureAD" -Force
Import-Module AzureAD -Force
echo "Connect Azure AD..."
$context = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile.DefaultContext
echo $context
$graphToken = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $context.Tenant.Id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, "https://graph.microsoft.com").AccessToken
echo $graphToken
$aadToken = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate($context.Account, $context.Environment, $context.Tenant.Id.ToString(), $null, [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never, $null, "https://graph.windows.net").AccessToken
Write-Output "Hi I'm $($context.Account.Id)"
Connect-AzureAD -AadAccessToken $aadToken -AccountId $context.Account.Id -TenantId $context.tenant.id -MsAccessToken $graphToken
echo "Connection ends"

Multiple values fetched when try to get the azure web app objectid

I am trying to get web app objectid using powershell but multiple objectid fetched in the result.
$app = Get-AzureADServicePrincipal -SearchString "devt002"
$app.ObjectId
Result :
33b7cfc5-ca71-412a-ac3b-8b0ca49fb8a6
976a5114-4fab-4b5a-ab92-7403ef25ac29
The original objectid is '976a5114-4fab-4b5a-ab92-7403ef25ac29'.
This is nothing strange, as mentioned in the comment, you have two service principals match the search.
If you want to get the service principal named devt002, try the command below.
$app = Get-AzureADServicePrincipal -SearchString "devt002" | Where-Object {$_.DisplayName -eq "devt002"}
$app.ObjectId
Update:
Try the command as below, the $objectid is what you want.
$webapp = Get-AzWebApp -ResourceGroupName "<resource group name >" -Name "<web app name>"
$objectid = $webapp.Identity.PrincipalId

Resources