Find out the direct assigned licenses of an o365 user - powershell

I am trying to write a powershell script, where I need to remove the licenses of the user. However, I only need to remove the license if it is assigned directly and not via some Azure group. I do not have to touch the licenses which are showing up because of group based policy.
While testing, I noted that for the licenses property of a msoluser there also exists GroupsAssingningLicense which I could explore, however it contains value even for direct assign licenses.
Is there way I can figure out if the license is a direct assign or is showing up due to user being part of some group?

Your direction is correct.
We really should filter according to GroupsAssingningLicense.
For a direct assigned license, the value of GroupsAssingningLicense is the object id of the user.
But for an inherited assigned license, the value of GroupsAssingningLicense is the object id of the group.
A sample for your reference:
Connect-MsolService
$username = ""
$user = Get-MsolUser -UserPrincipalName $username
foreach ($license in $user.Licenses){
if($license.GroupsAssigningLicense[0].ToString() -eq $user.ObjectId){
Write-Host $license.AccountSkuId
Set-MsolUserLicense -UserPrincipalName $user.UserPrincipalName -RemoveLicenses $license.AccountSkuId
}
}

Related

MS Graph API - Group & membership info

I'm trying to pull out a listing of all groups in our Azure Active Directory org along with all the associated members (be them users, groups, contacts, etc).
Since I was unable to locate a method to do this through the various Microsoft portals with a simple export button I began the process of obtaining access to the Microsoft Graph API/SDK via Powershell.
I'm by no means a PowerShell expert as it's not one of my go-to scripts; however, from what I can tell the ability to pull group info in this fashion is fairly limited.
The following is what I've been able to accomplish thus far:
Pull in a list of the groups using Get-MgGroup -All
Use Get-MgGroupMembers to pull back a list of Directory Objects.
This is where I get stuck. From what I've read it looks like a Directory Object by default only returns the ID and the Deleted Date. I'd like to get a display Name for these objects; I can obviously do this by running the appropriate 'Get' cmdlet for the type of directory object (i.e. Get-MgUser); From what I can tell the type of directory object can't be gleaned via PowerShell with out 'trial-and-error'... This seems highly inefficient to simply get a displayName.
Is there a more effective way to determine either the displayName of a Directory Object via a PowerShell cmdlet or at the very least a type so I can write a case statement to run the right cmdlet on the first try?
For the record this is going to be incorporated in to a Powershell Script, the current iteration of which looks like this and sorta works okay... assuming the Id passed in $member.Id belongs to a User type directory object.
Connect-MgGraph
$groups=Get-mgGroup -All
ForEach ($group in $groups){
$members = #{}
$members = Get-MgGroupMember -GroupId $group.Id -All
ForEach ($member in $members){
$user = Get-MgUser $member.Id
Write-Output $object.ODataType
Write-output $group.DisplayName "," $member.Id "," $user.UserType"," $user.DisplayName "," $user.UserPrincipalName "," $user.Mail >> C:scripts\Azure_Groups.txt
}
}
Would appreciate any direction/assistance on this. Thanks in advance!
Not sure why its not returning all the details on the PowerShell query:
This is working fine in MS Graph Explorer with the results showing all the details of the members:
For more details:https://learn.microsoft.com/en-us/graph/api/group-list-members?view=graph-rest-1.0&tabs=http#example-1-get-the-direct-membership-in-a-group

Is it possible to use Get-AzureADServicePrincipal and Get-AzureADServiceAppRoleAssignment to remove users access to all azure enterprise apps?

I am trying to automate the removal all enterprise app access for terminated employee's with powershell but can not figure out if its possible to store all of a users app assignments to a variable and then remove them from all app assignments stored in that variable.
https://learn.microsoft.com/en-us/azure/active-directory/manage-apps/assign-user-or-group-access-portal
Until now, there is no such cmdlets to directly assign variable to a user for all the apps that are assigned to that user. Rather than that, you can add all the terminated employees(users)to a group and then assign a variable to them for unassigning them from an application. An example of the same is as follows: -
$group = get-azureadgroup -ObjectId
$spo = Get-AzureADServicePrincipal -ObjectId
$assignments = Get-AzureADServiceAppRoleAssignment -ObjectId $spo.ObjectId | Where {$_.PrincipalDisplayName -eq $group.DisplayName}
$assignments | Select *
Remove-AzureADServiceAppRoleAssignment -ObjectId $spo.ObjectId -AppRoleAssignmentId
$assignments[assignment #].ObjectId
Also, find the below links for your reference: -
https://learn.microsoft.com/en-us/azure/active-directory/manage-apps/assign-user-or-group-access-portal
https://learn.microsoft.com/en-us/azure/active-directory/manage-apps/disable-user-sign-in-portal
https://learn.microsoft.com/en-us/azure/active-directory/manage-apps/manage-application-permissions
Thanking you,

Add AD user to group when creating the user?

I've seen multiple examples on adding a user to a group after creation, but not at the time of creation. Is that possible? Currently, I have something like this: (most attributes removed for simplicity)
$user = New-ADUser -Name "person" -Path "OU=test,OU=myorg" -Office "home" -samAccountName "snuffy.john" -PassThru
if ($user){
Add-ADGroupMember -Identity mygroup -Members $user.samAccountName
}
This causes two calls to the ldap server for each user added and I'm trying to prevent that as I have many thousands of users and the script takes a long time to run. I've checked MS docs but didn't see anything. If it's not possible, it is what it is. Thought I'd try asking at least. I also just started using powershell last week.
You may turn your thinking. with thousands of users I would do it like this.
First create all users.
Then get them by Get-ADUser -Filter * -SearchBase "OU=test,OU=myorg" (or maybe Filter the CreatedDate Attribute to get all new users)
After getting the users try to filter them for the groups you want to put them into and use the Add-ADGroupMember cmdlet, which accepts an array of ADPrincipals for parameter "-members".
This will speed up your code.

Security Accounts Manager attributes

I would like to create user in AD using the attributes defined for other user from the same OU. But I do have issue with SAM protected items.
For do that I am creating an instance of user already defined in AD with all the properties. After I am using New-AdUser command to create a new user using the created instance. However in the properties there are elements which are managed by Security Accounts Manager - I tried to find which parameters belong to SAM but with no results. Can anyone help me to determinate the parameters I am able to copy acctualy. So I can define which parameters I would like to copy form the created instance.
PS C:\Users\xxx> $userInstance = Get-ADUser $accountIdentifier -properties *
PS C:\Users\xxx> New-ADUser -GivenName "John" -Instance $userInstance -Surname "Smith" -Title "Salesman" -EmailAddress "John.Smith#yahoo.com" -UserPrincipalName smithj#yahoo.com -Name "John Smith"
As a reslut I have the folowing errro message:
New-ADUser : Access to the attribute is not permitted because the attribute is owned by the Security Accounts Manager (SAM)
You can use the following to determine which attributes can be copied:
$searchBase = "CN=Schema,$((Get-ADRootDSE).configurationNamingContext)"
$Attributes = Get-ADObject -SearchBase $searchBase -Filter * -Properties searchflags,ldapdisplayname |
Where-Object {$_.SearchFlags -band 16} | Select ldapdisplayname
$Attributes
Then you can use the attributes listed in the output as a guide for what you feed into the -Properties parameter of the New-ADUser command.
Essentially, this goes through every schema attribute in AD and returns the attributes where the searchflags attribute has the 16 decimal bit turned on. Depending on your display, you may see this as a hex representation (0x00000010). You cannot just rely on the value of 16 because if other flags are turned on, that value will change if other bits are turned on. The decimal values for the bits are summed. For this reason, we use the -band (bitwise and) operator. You can read more about the Search-Flags attribute here.

How to get effective permissions with PowerShell for an attribute on the AD user object

Does anyone know how to generate a report for ACLs on the AD user's attributes.
for example who has rights to Active Directory users "read Initials" or "write Initials" attributes.
I have found PowerShell Commands to get ACLs on the AD user object itself, but not at attribute level.
Check out the PowerShell Access Control module. Version 3.0 is implemented almost completely in PowerShell, which makes it pretty slow compared to using Get-Acl, but I think it can do what you're asking for (and I'm working on the speed issue).
It has a function named Get-EffectiveAccess that can compute the effective access of a principal over a securable object, but I don't think that's what you're looking for. It sounds like you want to get a list of ACEs that provide access to read/write the 'initials' property. To do that, you would use Get-AccessControlEntry:
# Get any ACEs that grant or deny read or write access to the 'initials' property:
Get-ADUser TestUser | Get-AccessControlEntry -ObjectAceType initials
# Get any ACEs that grant or deny write access to the 'initials' property:
Get-ADUser TestUser | Get-AccessControlEntry -ObjectAceType initials -ActiveDirectoryRights WriteProperty
# Get any ACEs that grant write access to the 'initials' property:
Get-ADUser TestUser | Get-AccessControlEntry -ObjectAceType initials -ActiveDirectoryRights WriteProperty -AceType AccessAllowed
Those examples all used Get-ADUser to lookup a single user. You should be able to feed the function any AD object, whether you use the AD module or a DirectorySearcher. You can even provide the distinguished name as the -Path parameter to the function.
The -ObjectAceType parameter should be able to take a GUID, or you can put in one or more property/property set/validated write/extended right/class object names (you can use * as a wildcard).
If you did want to compute the actual effective access, here are some examples of the Get-EffectiveAccess function:
# Get effective access that 'AnotherUser' has over 'TestUser' object (this doesn't include property, property set, validated write, etc effective permissions):
Get-ADUser TestUser | Get-EffectiveAccess -Principal AnotherUser
# Same as before, but this time include effective access down to the ObjectAceType level:
Get-ADUser TestUser | Get-EffectiveAccess -Principal AnotherUser -ObjectAceTypes initials
Get-ADUser TestUser | Get-EffectiveAccess -Principal AnotherUser -ObjectAceTypes init*
While working on the last few examples, I noticed that there are some errors that are written when using Get-EffectiveAccess with the -ObjectAceTypes parameter, even though the function appears to work correctly. If I have time over the weekend, I may fix that, but I'll probably just wait for version 4.0.