I'd like to get an AD user account via powershell within a specific group.
I will know the GivenName and Surname of the user I will be looking for, so Get-ADUser seems like a good function to use.
The issue is that we have a large number of users in the OU and I want to limit the scope of the search to one AD group and the groups under that one AD group. As far as I can tell, the SearchBase parameter of Get-ADUser will only work for OUs and not for groups.
I'd like to do this as efficiently as possible (i.e. not get all the users in the group and search within those users).
You could use Get-ADGroupMember for enumerating the members of a group, and use that as input for Get-ADUser:
Get-ADGroupMember 'groupname' |
Get-ADUser -Properties EmailAddress |
Where-Object { $_.Surname -eq 'foo' -and $_.GivenName -eq 'bar' } |
Select-Object -Expand EmailAddress
If the group contains not only user objects you need to filter the members by class first:
Get-ADGroupMember 'groupname' |
Where-Object { $_.objectClass -eq 'user' } |
Get-ADUser -Properties EmailAddress |
Where-Object { $_.Surname -eq 'foo' -and $_.GivenName -eq 'bar' } |
Select-Object -Expand EmailAddress
For unrolling nested groups you need a recursive function:
function Unroll-Group($group) {
Get-ADGroupMember $group | ForEach-Object {
$userOrGroup = $_
switch ($_.objectClass) {
'group' { Unroll-Group $userOrGroup }
'user' { Get-ADUser $userOrGroup -Property EmailAddress }
}
}
}
Unroll-Group 'groupname' |
Where-Object { $_.Surname -eq 'foo' -and $_.GivenName -eq 'bar' } |
Select-Object -Expand EmailAddress
Note that this approach won't work for a user's primary group.
Related
I'm tryng to get all the groups the users of a domain are member of, but filtering only the groups with a given extensionattribute.
I set the extensionattribute12 of all the domain groups to better filter some queries (i.e. Infrastructure - security - elearning). My query should get only the user(s) groups with
extensionattribute12=security
(for example).
I use something like:
get-aduser -filter -Properties memberof | select name, #{ l="GroupMembership"; e={$_.memberof -join ";" } }
and I get all the groups of the users. How can I filter by group extensionattribute?
You could use the inverse relationship (member on the group object) to query all the groups a user is a member of, just 1 query per user. Here using an LDAP filter:
$groupLabel = "Security"
Get-ADUser -Filter * |ForEach-Object {
$groups = Get-ADGroup -LDAPFilter "(&(extensionattribute12=$groupLabel)(member=$($_.DistinguishedName)))"
[pscustomobject]#{
User = $_.SamAccountName
GroupMembership = $groups.DistinguishedName -join ';'
}
}
If you have to process a large number of users or group memberships, you may find it faster to retrieve all the groups satisfying the extensionAttribute12 criteria up front and use that list to filter the memberOf attribute on the users:
$groupLabel = "Security"
# Create a hash set and populate it with the distinguished
# names of all the groups we're looking for
$groupDNs = [System.Collections.Generic.HashSet[string]]::new(#(
Get-ADGroup -Filter "extensionAttribute12 -eq '$groupLabel'" |Select -Expand DistinguishedName
))
Get-ADUser -Filter * -Properties memberOf |ForEach-Object {
# Retrieve memberOf values and filter against the hash set
$groups = $_.memberOf |Where-Object { $groupDNs.Contains($_) }
[pscustomobject]#{
User = $_.SamAccountName
GroupMembership = $groups -join ';'
}
}
Make it with N+1 queries
$groups = #( Get-ADGroup -Filter '(extensionattribute12 -eq "security")' )
$users = #( $groups |
ForEach-Object { Get-ADGroupMember -Identity $_ -Recursive } |
Sort-Object -Unique )
$users # All users of all groups that have EA12 = security
Get-ADUser -filter {...} -Properties memberof | select name, #{ l="GroupMembership"; e={( $_.memberof | Get-ADGroup |?{ $_.extensionattribute12 -eq 'security' }) -join ";" }} |?{ $_.GroupMembership }
I'm a beginner in programming in general..
What I'm trying to do is to create a powershell script that will:
Get information on each user on an Active Directory group.
Inside each group there may be another group, so I would want it to get the list of users from each nested group as well.
Only give me the information for each group once.
This is what I have so far:
$list = Get-ADGroupMember Admins
foreach($u in $list) {
Get-ADObject $u
}
foreach ($_ in $u) {
if ($u.ObjectClass -eq 'user') {
Get-ADUser $u -Properties * | select givenname, surname, samaccountname | ft -autosize
} else {
Get-ADGroupMember $u -Recursive | select name, samaccountname | ft -autosize
}
}
So far I'm trying to get it to work with that one group 'Admins' and then if it does I would want to run the code for more groups at the same time.
Any help or guidance would be appreciated.
You seem to want only properties that are returned by default by Get-ADUser aswell as Get-ADGroup, so in both cases, there is no need to specify the -Properties parameter.
Get-ADGroupMember can return user, computer and group objects, so at the moment, your else condition expects groups, where you could end up with a computer object..
In your code, you output to console with ft -autosize both in the if and the else, but it would be simpler to capture both types of resulting objects in a variable at the start of the loop and output it as a whole afterwards:
# you can load a list of group names from a predefined array:
$Groups = 'Admins', 'Users'
# or load from a file, each group name listed on a separate line:
# $Groups = Get-Content -Path 'D:\Test\ADGroups.txt'
# or get all AD groups in the domain:
# $Groups = (Get-ADGroup -Filter *).Name
$result = foreach ($group in $Groups) {
Get-ADGroup -Filter "Name -eq '$group'" | ForEach-Object {
# we could use the $group variable, but this ensures correct casing
$groupName = $_.Name
$members = $_ | Get-ADGroupMember -Recursive
foreach ($member in $members) {
if ($member.objectClass -eq 'user') {
Get-ADUser -Identity $member.DistinguishedName |
Select-Object #{Name="GroupName"; Expression={$groupName}},
#{Name="MemberType";Expression={'User'}},
Name,
GivenName,
Surname,
SamAccountName
}
elseif ($member.objectClass -eq 'group') {
Get-ADGroup -Identity $member.DistinguishedName |
Select-Object #{Name="GroupName";Expression={$groupName}},
#{Name="MemberType";Expression={'Group'}},
Name,
#{Name="GivenName";Expression={''}}, # groups don't have this property
#{Name="Surname";Expression={''}}, # groups don't have this property
SamAccountName
}
}
}
}
# output is console
$result | Format-Table -AutoSize
# write to CSV file
$result | Export-Csv -Path 'D:\Test\GroupsInfo.csv' -NoTypeInformation
The trick is here to output objects with equal properties for both a user and a group object
In my company, I have a PowerShell script to copy group from one user to another. But it happens that I have two groups which one Denied access and the other Allow acces.
For example, after copying, I could have that in the user account :
FIC-LSM-APP-BO5-DND
FIC-LSM-APP-BO5-MAJ
I would like to delete the Denied access group with a script.
Here my code:
Import-Module ActiveDirectory
[void][System.Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
$nomuser = [Microsoft.VisualBasic.Interaction]::InputBox("Login de >l'utilisateur à traiter", "A traiter", "")
$nommodele = [Microsoft.VisualBasic.Interaction]::InputBox("Nom du >modèle", "Modèle", "")
try {
$user = Get-ADUser -Identity $nomuser -Properties memberOf
} catch {
[System.Windows.Forms.MessageBox]::Show("Utilisateur $nomuser non >trouvé","Erreur",[System.Windows.Forms.MessageBoxButtons]::OK,[System.Windows.Forms.MessageBoxIcon]::Error)
exit
}
try {
$usertemplate = Get-ADUser -Identity $nommodele -Properties memberOf
} catch {
[System.Windows.Forms.MessageBox]::Show("Utilisateur modèle $nomuser >non trouvé","Erreur",[System.Windows.Forms.MessageBoxButtons]::OK,[System.Windows.Forms.MessageBoxIcon]::Error)
exit
}
$Groups = $User.MemberOf | ForEach-Object {
Get-ADGroup $_
}
$groups = $Usertemplate.MemberOf | ForEach-Object {
Get-ADGroup $_
}
$Groups | ForEach-Object {
Add-ADGroupMember -Identity $_ -Members $user
}
$user = Get-ADUser -Identity $nomuser -Properties memberOf
$user.MemberOf | Get-ADGroup |
Group-Object {$_.Name -replace '^(.*)-(?:DND|MAJ)$', '$1'} |
Where-Object { $_.Count -eq 2 } | Select-Object -Expand Group |
Remove-ADGroupMember -Members $user -Confirm:$false
$user.MemberOf | ogv -Title "Nouvelle liste d'appartenance pour $nomuser"
I finally have time and a test data base to perform this code.
However I have a problem. For example :
Groups of $nomuser : FIC-LSM-APP-BO5-DND
Group of $nommodele : FIC-LSM-APP-BO5-MAJ
When I run the code, the target user ($nomuser) haven't no more group... I think there is an error in the code, but where I don't know.
You can use Group-Object to determine whether a user is member of both allow and deny group. The cmdlet allows you to specify custom matching criteria in a scriptblock, so you can remove a trailing -DND or -MAJ from the group name and group by the group "basename":
$user.MemberOf | Get-ADGroup |
Group-Object {$_.Name -replace '^(.*)-(?:dnd|maj)$', '$1'}
Use Where-Object to filter the result for groups with a count of 2 and expand the Group property to get the original AD groups:
... | Where-Object { $_.Count -eq 2 } | Select-Object -Expand Group | ...
Use another Where-Object filter to restrict the groups to just the ones you want to remove the user from (e.g. with a filter Name -like '*-dnd'), then remove the user from those groups:
... | Remove-ADGroupMember -Members $user -Confirm:$false
I've been trying to get an extract of AD users and select mail, name, memberof. I then need to list only specific groups from the memberof output so I end up with a list for each user than contains their name, email address and specific groups that match a certain name and not all of the groups they are a member of.
Get-ADUser username -Properties memberof | Select-Object memberof
I can't seem to find a way of doing this as I end up with either noteproperty above or an empty pipeline. Is there a way to achieve what I am trying to do?
The memberOf attribute contains a list of distinguishedName (DN) values, each corresponding to a group.
Retrieve the groups you are interested in, before you run Get-ADUser, that way you can compare the Group DN to the entry in memberOf:
$GroupDNs = Get-ADGroup -Filter {Name -like "*finance*" -or Name -like "*creditcontrol*"} | Select-Object -ExpandProperty DistinguishedName
Now, you can use those DN's to filter the group memberships with a calculated property, like so:
$UserInfo = foreach($username in #("bob","alice","joe")){
$User = Get-ADUser -Identity $username -Properties mail,memberOf |Select Name,mail,memberof
$User | Select-Object Name,mail,#{Label="GroupDNs";Expr = {$_.memberof | Where-Object {$Groups -contains $_}}}
}
without doing a new Get-ADGroup query for each memberof entry.
If you want a string of group names, rather than a NoteProperty containing an array of strings, you could fill the Groups into a hashtable and use that to "look up" the memberof entries using the ContainsKey() method:
$Groups = #{}
Get-ADGroup -Filter {Name -like "*finance*" -or Name -like "*creditcontrol*"} | ForEach-Object {
$Groups[$_.DistinguishedName] = $_
}
$UserInfo = foreach($username in #("bob","alice","joe")){
$User = Get-ADUser -Identity $username -Properties mail,memberOf |Select Name,mail,memberof
$User | Select-Object Name,mail,#{Label="Groups";Expr = { ($_.memberof | Where-Object {$Groups.ContainsKey($_)} | ForEach-Object { $Groups[$_].Name}) -join ";" }}
}
$UserInfo | Export-Csv C:\aduserinfo.csv -NoTypeInformation
I got a list of 150+ users and I want to know which group they have membership for?
I just started using PS. I can query for 1 user, but not for a list of users. Would like
to know exact command??? I got :
(get-aduser -identity "username" -properties memberof |select-object memberof).memberof > c:\temp\ss.csv
Read your user list into an array and check if your AD users are contained in that array:
$userlist = Get-Content 'C:\your\userlist.txt'
Get-ADUser -Filter '*' -Properties memberof | Where-Object {
$userlist -contains $_.SamAccountName
} | ForEach-Object {
$username = $_
$groups = $_ | Select-Object -Expand memberof |
ForEach-Object { (Get-ADGroup $_).Name }
"{0}: {1}" -f $username, ($groups -join ', ')
} | Out-File 'c:\temp\ss.csv'
Replace SamAccountName as appropriate if the user list doesn't contain the account names of the users.