How do I check whether a device is already in an Azure group (Powershell) - azure

I'm trying to find a way to see whether an Azure-enrolled device is a member of an Azure group.
The functionality I am aiming for is:
Enter device Object ID
Get all the Azure AD groups
Get the target device using 'Get-AzureADDevice'
Loop through a collection of groups and check if each group contains the device
If the device isn't in a group, add the device to the group. Otherwise skip.
Here is a snippet of my code so far:
$DeviceOID = Read-Host "Enter device's Object ID "
#Get All Azure AD Groups
$AzureGroups = Get-AzureADGroup -All:$true| Sort DisplayName
$Collection = #("Group1", "Group2", "Group3")
$targetDevice = Get-AzureADDevice -ObjectId $DeviceOID
#loop through and add user to each group
foreach ($Item in $Collection)
{
$GroupOID = ($AzureGroups | Where {$_.DisplayName -eq $Item}).ObjectID
$GroupMembers = Get-AzureADGroupMember -ObjectId $GroupOID -All $true
if ($GroupMembers -contains $targetDevice) {
Write-Output "Device already in $Item"
} else {
Add-AzureADGroupMember -ObjectID $GroupOID -RefObjectID $DeviceOID
}
}
The problem I am running into is that although the device is indeed in all 3 groups, the script is not recognising this and is still trying to add the device into said groups:
Add-AzureADGroupMember : Error occurred while executing AddGroupMember
Code: Request_BadRequest
Message: One or more added object references already exist for the following modified properties: 'members'.

I tried to reproduce the same in my environment its work successfully.
When I tried to use your cmdlet, my device is added in azure group successfully as below.
I tried to check whether my device is already exists in azure group I am getting the same error as below.
To resolve this issue, try to remove sort display the term 'Sort' is not recognized as a name of a cmdlet, and I agree with the guiwhatsthat you need to add ($Group in Members.ObjectId -contains $targetDevice.ObjectId) in if statement as below.
$DeviceOID = Read-Host "Enter device's Object ID "
#Get All Azure AD Groups
$AzureGroups = Get-AzureADGroup -All:$true
$Collection = #("Group1", "Group2", "TestGroup")
$targetDevice = Get-AzureADDevice -ObjectId $DeviceOID
#loop through and add user to each group
foreach ($Item in $Collection)
{
$GroupOID = ($AzureGroups | Where {$_.DisplayName -eq $Item}).ObjectID
$GroupMembers = Get-AzureADGroupMember -ObjectId $GroupOID -All $true
if ($GroupMembers.ObjectId -contains $targetDevice.ObjectId) {
Write-Output "Device already in $Item"
} else {
Add-AzureADGroupMember -ObjectID $GroupOID -RefObjectID $DeviceOID
}
}
Output:

Related

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.

Getting Subscription ID with Resource Group without setting az context

I have a tenant with multiple subscriptions.
When I first login using Connect-AzAccount, it shows a message "TenantId 'xxxxx-xxxxx-xxx-xxx' contains more than one active subscription. First one will be selected for further use. To select another subscription, use Set-AzContext."
But I want to be able to do Get-AzResourceGroup -name 'abcd'.
The problem is resource group abcd is not under the first selected subscription selected from the login command.
I want to progromatically Get-AzResourceGroup -Name "ResourcegroupName" to retrieve the subscriptionID without setting az context as it defeats the purpose.
tried to clear the context clear-azContext but that signs me out.
I want to progromatically Get-AzResourceGroup -Name "ResourcegroupName" to retrieve the subscriptionID without setting az context as it defeats the purpose.
After reproducing from my end, Using the below script I could able to achieve your requirement.
$ResourceGroupName = Read-Host "Enter the resource group name you are searching for"
Get-AzSubscription | ForEach-Object {
$subscriptionName = $_.Name
$subscriptionId = $_.SubscriptionId
Set-AzContext -SubscriptionId $subscriptionId
(Get-AzResourceGroup).ResourceGroupName | ForEach-Object {
If ($ResourceGroupName -eq $_) {
[PSCustomObject] #{
Subscription = $subscriptionName
SubscriptionId = $subscriptionId
ResourceGroup = $_
}
}
}
}
RESULTS:

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

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
}'''

Query Azure AD using Powershell to find which users can access different resources in Azure

Overview
I want to have a way to query the Azure AD, and return a list of Azure AD Groups that are assigned to different resources groups in Azure.
Current Solution
Currently, i have a powershell script running as a Service principle that authenticates with Azure, then it gets the current subscription. Based on that searches for the logged in user and returns all the security groups the user is assigned to. Which is then checked against all the resources groups the AD group is assigned to, which returns a list of the VM's in the resource groups that the logged in user can access.
This does work, however it takes about 10 minutes to run. We have a 100 resources groups per subscription and its to slow.
I have pasted the code below, and removed any private information.
Questions
Understand a way to make the script run faster - 30 seconds at a max.
Is there a more efficient way to run the script or a command that is designed for this sole purpose.
I am using Az Powershell 2.4.0 library to create the code.
function userLogin($azureAplicationId, $azureAppPassword)
{
$azureTenantId= ""
$azurePassword = ConvertTo-SecureString $azureAppPassword -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($azureAplicationId , $azurePassword)
Connect-AzAccount -Credential $psCred -TenantId $azureTenantId -ServicePrincipal
}
function userRGAccessCheck($RG)
{
$resoruceGroupChoice = Read-Host -Prompt "Enter Resource Group Name "
}
function userRTAccessCheck($RName)
{
$resoruceNameChoice = Read-Host -Prompt "Enter VM Name "
}
$subAccess = Read-Host -Prompt "Enter Subscription, Press (1) OR (2): `n(1) Microsoft Azure Enterprise Non-Production `n(2) Microsoft Azure Enterprise Production`n"
if ($subAccess -eq 1)
{
$azureAplicationId =""
$azureAppPassword = ""
userLogin -azureAplicationId $azureAplicationId -azureAppPassword $azureAppPassword
#userRGAccessCheck -RG $reresoruceGroupChoice
} elseif ($subAccess -eq 2)
{
$azureAplicationId =""
$azureAppPassword = ""
userLogin -azureAplicationId $azureAplicationId -azureAppPassword $azureAppPassword
#userRGAccessCheck -RG $reresoruceGroupChoice
#userRTAccessCheck -RName $resoruceNameChoice
} else
{
Write-Host "Please Enter 1 OR 2"
}
# Arrays for app
$groupArray = #()
$ADAccessGroupArray = #()
$resourceGroupArray = #()
$userObjectID = "USER_OBJECT_ID"
# Get AD User Groups and list of resource groups
$groupArray += (Get-AzADGroup -SearchString 'SS_*' | Select-Object -ExpandProperty Id)
foreach($group in $groupArray)
{
if(Get-AzADGroupMember -GroupObjectId $group | Where-Object {$_.Id -eq $userObjectID})
{
$ADAccessGroupArray += $group
Write-Host "User has access to group: " $group
} else
{
Write-Host "User does not have access to group: " $group
}
}
# Get a list of resource groups
$resourceGroupArray += Get-AzResourceGroup | Select-Object -ExpandProperty ResourceGroupName
# Check if the AD group has been assigned to the resource group
foreach ($resourceGroupName in $resourceGroupArray)
{
foreach ($ADAccessGroup in $ADAccessGroupArray)
{
if(Get-AzRoleAssignment -ResourceGroupName $resourceGroupName | Where-Object {$_.ObjectId -eq $ADAccessGroup})
{
Write-Host "User has access to group: " $resourceGroupName
}
}
}
$groupArray = $null
$ADAccessGroupArray = $null
$resourceGroupArray = $null
Thanks in advance
I have made some modifications that should help.
function userLogin($azureAplicationId, $azureAppPassword)
{
$azureTenantId= ""
$azurePassword = ConvertTo-SecureString $azureAppPassword -AsPlainText -Force
$psCred = New-Object System.Management.Automation.PSCredential($azureAplicationId , $azurePassword)
Connect-AzAccount -Credential $psCred -TenantId $azureTenantId -ServicePrincipal
}
function userRGAccessCheck($RG)
{
$resoruceGroupChoice = Read-Host -Prompt "Enter Resource Group Name "
}
function userRTAccessCheck($RName)
{
$resoruceNameChoice = Read-Host -Prompt "Enter VM Name "
}
$subAccess = Read-Host -Prompt "Enter Subscription, Press (1) OR (2): `n(1) Microsoft Azure Enterprise Non-Production `n(2) Microsoft Azure Enterprise Production`n"
if ($subAccess -eq 1)
{
$azureAplicationId =""
$azureAppPassword = ""
userLogin -azureAplicationId $azureAplicationId -azureAppPassword $azureAppPassword
#userRGAccessCheck -RG $reresoruceGroupChoice
} elseif ($subAccess -eq 2)
{
$azureAplicationId =""
$azureAppPassword = ""
userLogin -azureAplicationId $azureAplicationId -azureAppPassword $azureAppPassword
#userRGAccessCheck -RG $reresoruceGroupChoice
#userRTAccessCheck -RName $resoruceNameChoice
} else
{
Write-Host "Please Enter 1 OR 2"
}
# Arrays for app
$groupArray = #()
$ADAccessGroupArray = #() -as [System.Collections.Arraylist] # Using Arraylist type
$resourceGroupArray = #()
$userObjectID = "USER_OBJECT_ID"
# Get AD User Groups and list of resource groups
$groupArray = (Get-AzADGroup -SearchString 'SS_*' | Select-Object -ExpandProperty Id) # Removed += because it is unnecessary
foreach($group in $groupArray)
{
if((Get-AzADGroupMember -GroupObjectId $group).where({$_.Id -eq $userObjectID},'First')) # Used where method
{
$null = $ADAccessGroupArray.Add($group) # Add group to arraylist and suppress output. Removed += because it is a slow operation here.
Write-Host "User has access to group: " $group
} else
{
Write-Host "User does not have access to group: " $group
}
}
# Get a list of resource groups
$resourceGroupArray = Get-AzResourceGroup | Select-Object -ExpandProperty ResourceGroupName # Removed += because it is unnecessary
# Check if the AD group has been assigned to the resource group
foreach ($resourceGroupName in $resourceGroupArray)
{
if((Get-AzRoleAssignment -ResourceGroupName $resourceGroupName).where({$_.ObjectId -in $ADAccessGroupArray},'First')) # used where method
{
Write-Host "User has access to group: " $resourceGroupName
}
}
$groupArray = $null
$ADAccessGroupArray = $null
$resourceGroupArray = $null
I added comments to lines that I changed. Here is a summary of the changes:
I set $ADAccessGroupArray as an arraylist type. This is so that we can access the inherent Add() method to update it. If we use an array, which is immutable, you have to create a new array to add more entries. One way to update an array is using +=, which is a very inefficient operation as the size of the array grows.
Generally, += is not the most efficient approach. Sometimes it is a negligible operation, but I would avoid it unless you know it is negligible.
I removed += from your other array assignments because they aren't necessary when you are setting a variable to a command output that returns an array. The result will be an array without +=. There are cases where your command returns one value and your variable may not become an array then. There are ways around this using the , unary operator or declaring your array ahead of time.
I replaced Where-Object in favor of the where() method. Not only does where-object (and where()) wait for the LHS operation to complete before it does anything, it will enumerate through all of the pipelined items before it returns a result. Using the where() method, we gain access to modes. In both of your cases, I am using the 'First' mode so that where() will stop processing once it finds its first conditional match. This is extremely helpful if you have a list of 1000 objects and the match is within the top half of that list.
I removed the nested foreach loop within the $resourceGroupArray foreach loop. This was possible by updating the next where() condition to use the -in operator. -in allows you to find one item within a collection, which is what you were doing for every group. So we reduced the number of Get-AzRoleAssignment calls from ResourceGroups x Groups to ResourceGroups. There should be significant time savings here.

Disable all site creation except for a certain group

I want to lock down site creation to a certain group of admin suresh. We have created a group for this, but what do I tell the SharePoint Admin to do in order to achieve this?
To lock down site creation, you basically need to run a few PowerShell commands as below using Azure AD PowerShell. Run them commands with Global admin priviledges.
I am assuming that you have created an Azure AD group with certain users who will have access to create the site.
$creds = Get-Credential
Connect-AzureAD -Credential $creds
$group = Get-AzureADGroup -All $True | Where-Object {$_.DisplayName -eq "ENTER GROUP DISPLAY NAME HERE"}
$policySetting = Get-AzureADDirectorySetting | where-object {$_.displayname -eq "Group.Unified"}
if($policySetting -eq $null) {
$template = Get-AzureADDirectorySettingTemplate | Where-Object {$_.DisplayName -eq "Group.Unified"}
$settings = $template.CreateDirectorySetting()
$settings["EnableGroupCreation"] = $false
$settings["GroupCreationAllowedGroupId"] = $group.ObjectId
$policySetting = New-AzureADDirectorySetting -DirectorySetting $settings
}
else{
$policySetting["EnableGroupCreation"] = $false
$policySetting["GroupCreationAllowedGroupId"] = $group.ObjectId
Set-AzureADDirectorySetting -Id $policySetting.Id -DirectorySetting $policySetting
}
Links:
Installing the Azure AD module
Code modified from - Managing Office 365 group creation using Azure AD PowerShell v2

Resources