Remove Single IDs from local administrator group - powershell

I want to delete individual ID's from Administrator group
I have below code to get the members and delete them
Get-LocalGroupMember -Name 'Administrators'
$AdminGroup = [ADSI]"WinNT://$ComputerName/Administrators,group"
$User = [ADSI]"WinNT://$DomainName/$UserName,user"
$AdminGroup.Remove($User.Path)
Write-Host "Successfull:" $ComputerName
the problem I am facing is how to identify the single/individual IDs in the group.
below is one sample output from one of the server I fetched the members where there is no individual IDs present
Name SID PrincipalSource ObjectClass
---- --- --------------- -----------
AUTO1AP\csgadm# S-1-5-21-126948685-454775200-1760099607-500 Local User
ZA\ S-1-5-21-3095416536-3097367016-2845470932 ActiveDirectory Other
ZA\A-Auto$ S-1-5-21-3095416536-3097367016-2845470932-1423106 ActiveDirectory User
ZA\A-Server Administrators S-1-5-21-3095416536-3097367016-2845470932-128673 ActiveDirectory Group
ZA\A92361 S-1-5-21-3095416536-3097367016-2845470932-1423726 ActiveDirectory User
ZA\A-SAN-AUTO S-1-5-21-3095416536-3097367016-2845470932-1475616 ActiveDirectory User
ZA\Domain Admins S-1-5-21-3095416536-3097367016-2845470932-512 ActiveDirectory Group
I have the above data now and I want to delete the Individual account from this which is ZA\A92361 ( here I know this is the individual account but in actual case I need to find out and delete)
Please let me know on this

Although it is still not clear to me what you mean by identify the users you want to remove, I believe the Get-LocalGroupMember cmdlet returns everything you need to identify them.
$ADusersToRemove = 'jdoe', 'cblossom' # example some SamAccountNames of users to remove from the group
# from these users to remove, get an array of their Security IDs
$ADsidsToRemove = $ADusersToRemove | ForEach-Object { (Get-ADUser -Identity $_ -ErrorAction SilentlyContinue).SID }
# get a list of members of the local group, AD users only
$allADMembers = Get-LocalGroupMember -Name 'Administrators' | Where-Object { $_.ObjectClass -eq 'user' -and $_.PrincipalSource -eq 'ActiveDirectory' }
# remove the wanted AD users from the group
$ADmembersToRemove = #($allADMembers | Where-Object { $ADsidsToRemove -contains $_.SID })
if ($ADmembersToRemove.Count) {
Remove-LocalGroupMember -Name 'Administrators' -Member $membersToRemove.SID
}
If you also want to remove LOCAL users (not AD), you can do something similar
# get an array of LocalPrincipal objects
$LocalUsersToRemove = #(Get-LocalUser -Name 'someguy', 'anotheruser' )
if ($LocalUsersToRemove.Count) {
Remove-LocalGroupMember -Name 'Administrators' -Member $LocalUsersToRemove
}
If as you say you want to exclude service accounts, then this question really is how to distinguish between a service account and a normal user account.
I have no idea how you have organized your AD, but therfe are several options of course:
you can have all service accounts start their samaccountname with a special prefix, like svc_ or something.
Then you can alter the filter to become
Where-Object { $ADsidsToRemove -contains $_.SID -and (($_.Name -split '\\') -notlike 'svc_*')}
you can have a special OU where all service accounts are stored like OU=ServiceAccounts,DC=Company,DC=com
Then you can use filter
Where-Object { $ADsidsToRemove -contains $_.SID -and ((Get-ADUser -Identity $_.SID).DistinguishedName -notlike '*OU=ServiceAccounts,DC=Company,DC=com')}
you can have the Description property of the service accounts all contain the words Service account
Then you can use filter
Where-Object { $ADsidsToRemove -contains $_.SID -and ((Get-ADUser -Identity $_.SID -Properties Description).Description -notlike '*Service account*')}
maybe you have used an Extension attribute on service accounts to test like ExtensionAttribute1=svc
Then you can use filter
Where-Object { $ADsidsToRemove -contains $_.SID -and ((Get-ADUser -Identity $_.SID -Properties ExtensionAttribute1).ExtensionAttribute1 -notlike 'svc')}
The possibilities are almost endless as you can see..

Related

Export the AD Group Membership of a list of users from a CSV Powershell

I am trying to get a CSV output of all the users in the 'VPN Users' group that are also in the 'Domain Users' group. I'd like it to give their name and then their group membership. Each member should only be in the VPN group. I am looking to identify who is in both groups.
To achieve this I have first exported a list of the users in the VPN Group to a CSV which works fine. Second part of the code is meant to go through the list of users in the CSV from that AD group and export an output as a CSV containing the users and their group membership which isn't working for me. For each user in the CSV it returns the error: Get-ADUser : Cannot find an object with identity: '"User001_vpn"'.....
I'm not sure if the way I'm going about it is the best way to achieve the task in hand or if any of you might be able to help me make it work? It seems like Get-ADUser isn't finding the users from the CSV.
#Retrieves list of users that are in the VPN Users group and exports them into a CSV
(Get-ADGroupMember "VPN Users" -Recursive | Get-ADUser -Properties * |
Select-Object SamAccountName |
ConvertTo-Csv -NoTypeInformation) |
Select-Object -Skip 1 |
Set-Content -Path "C:\Documents\VPN Users Report\VPNUsers.csv”
Get-Content “C:\Documents\VPN Users Report\VPNUsers.csv” | Get-ADUser | ForEach{
$user = $_
$groups = Get-ADPrincipalGroupMembership $user
$groups | %{ New-Object PSObject -Property #{ User = $user.SamAccountName; Group = $_.SamAccountName } }
} | Export-Csv "C:\VPN Users Report\Results\Output.csv"
I believe the problem is with the quotes, since you are using ConvertTo-Csv while retrieving the users, all user SamAccountNames will be quoted.
Afterwards you read this csv file using Get-Content, not Import-Csv, so the quotes will not be removed and you have user names like "User001_vpn" instead of User001_vpn
You do not have to use this 'in-between' cvs at all and on second thought, you can leave out Get-ADUser too unless you want other properties from these users than what Get-ADGroupMember already returns (i.e. distinguishedName, name, objectClass, objectGUID, SamAccountName, SID)
Try
# Retrieves list of users that are in the VPN Users group
(Get-ADGroupMember "VPN Users" -Recursive | Where-Object { $_.objectClass -eq 'user' }).SamAccountName | ForEach-Object {
foreach ($group in (Get-ADPrincipalGroupMembership -Identity $_)) {
[PsCustomObject]#{
User = $_
Group = $group.SamAccountName
}
}
} | Export-Csv "C:\VPN Users Report\Results\Output.csv" -NoTypeInformation
I have added Where-Object { $_.objectClass -eq 'user' }, because the Get-ADGroupMember cmdlet can return users, groups, and/or computer objects
As per your latest comment:
If you want more properties from the user, you need Get-ADUser, which by default returns objects with these properties:
DistinguishedName, Enabled, GivenName, Name, ObjectClass, ObjectGUID, SamAccountName, SID, Surname, UserPrincipalName
If you still need more, like for instance the users email address, you need to ask for it by adding -Properties EmailAddress
# demo to include the users first and last name
Get-ADGroupMember "VPN Users" -Recursive | Where-Object { $_.objectClass -eq 'user' } | ForEach-Object {
$user = Get-ADUser -Identity $_.DistinguishedName
foreach ($group in (Get-ADPrincipalGroupMembership -Identity $user.DistinguishedName)) {
[PsCustomObject]#{
User = $user.SamAccountName
FirstName = $user.GivenName
LastName = $user.Surname
Group = $group.SamAccountName
}
}
} | Export-Csv "C:\VPN Users Report\Results\Output.csv" -NoTypeInformation
I propose an alternative to Theo's helpful answer letting LDAP handle the filtering of users.
The result of this query would be those users which are members of GroupX and members of GroupY:
$groupX = (Get-ADGroup 'VPN Users').DistinguishedName
$groupY = (Get-ADGroup 'Domain Users').DistinguishedName
Get-ADUser -LDAPFilter "(&(memberOf=$groupX)(memberOf=$groupY))"
If you were looking for indirect members of one of the groups or both groups, meaning, possible members of nested groups in those groups you could use memberOf:1.2.840.113556.1.4.1941:. Example:
Get-ADUser -LDAPFilter "(&(memberOf:1.2.840.113556.1.4.1941:=$groupX)(memberOf=$groupY))"
Would bring all members (recursive) of GroupX which are also direct members of GroupY.

Find users who don't belong to multiple groups

My company uses Microsoft Intune. We've got 4 groups in an on-premise AD that controls the conditional access. We'll just call them AllowGroup1, AllowGroup2, BlockGroup1, and BlockGroup2. What I want know find is all users that are not in all of the groups. The result I'm wanting to find is any User object that is not in the mentioned groups. That way I can provide proof that our entire system is compliant. See below for the Powershell code I've borrowed from this post List AD Users who do not belong to one of several groups
I'm running these tests on my home domain controller. The problem I'm having is that the script isn't looking in the entire domain for users. Specifically, there is an OU in my personal DC that is called Home (I created the OU) and there are 2 user objects in a child OU called Users that this script isn't pulling from. I am running this script with a user that is in the Enterprise Admins group so I know it has sufficient privilege's. It's supposed to search AD via PowerShell for users not in multiple groups and place those users in a group called NotInGroup
To further elaborate, some users will be in AllowGroup1 and in BlockGroup2. Some users will be in BlockGroup1 and BlockGroup2. I want to find all users that are not in any of the groups listed above.
Import-Module ActiveDirectory
$groupname = "NotInGroup"
$members = Get-ADGroupMember -Identity $groupname
foreach($member in $members)
{
Remove-ADGroupMember -Identity $groupname -Member $member.samaccountname
}
$users = Get-ADUser -Filter
{
((memberof -notlike "CN=AllowGroup1,OU=Intune,OU=Groups,DC=domain,DC=local")
-AND (memberof -notlike "CN=AllowGroup2,OU=Intune,OU=Groups,DC=domain,DC=local")
-AND (memberof -notlike "CN=BlockGroup1,OU=Intune,OU=Groups,DC=domain,DC=local")
-AND (memberof -notlike "CN=BlockGroup2,OU=Intune,OU=Groups,DC=domain,DC=local"))
}
-SearchBase "dc=domain,dc=local" -SearchScope Subtree
foreach($user in $users)
{
Add-ADGroupMember -Identity $groupname -Members $user.samaccountname -ErrorAction SilentlyContinue
}
I don't think a complex filter like that would work and I would opt for using a regex.
Perhaps something like
# get users not in groups 'AllowGroup1', 'AllowGroup2', 'BlockGroup1', 'BlockGroup2'
$regex = 'CN=(AllowGroup[12]|BlockGroup[12])'
$users = Get-ADUser -Filter * -Properties MemberOf | Where-Object { ($_.MemberOf -join ';') -notmatch $regex }
Or you could try using the LDAPFilter parameter:
$filter = '(!(|(memberof=CN=AllowGroup1,OU=Intune,OU=Groups,DC=domain,DC=local)
(memberof=CN=AllowGroup2,OU=Intune,OU=Groups,DC=domain,DC=local)
(memberof=CN=BlockGroup1,OU=Intune,OU=Groups,DC=domain,DC=local)
(memberof=CN=BlockGroup2,OU=Intune,OU=Groups,DC=domain,DC=local)))'
$users = Get-ADUser -LDAPFilter $filter
Both parameters Filter and LDAPFilter are expecting a string, not a scriptblock

Filtering AD Group by User Properties ; Returning improperly

Disclaimer: I am not good with powershell, this in mainly butchered code. I apologize if this is done poorly or is a stupid question.
I am trying to filter the ACTIVE users in my company by their company (ET) and whether or not they are in a certain group.
So the filter for ACTIVE users in the company "ET" is working properly, the output of this script gives me every active users with that parameter; it does not filter it further down into only users in a certain group.
$users = Get-ADUser -filter {(Enabled -eq $True) -and (Company -eq "ET")}
-SearchBase 'DC=CSOKI,DC=Local' |select -exp samaccountname
$group = "O365-E3-Full"
$members = Get-ADGroupMember -Identity $group -Recursive | Select -
ExpandProperty samaccountname
ForEach ($user in $users) {
If ($members -contains $user) {
Write-output $(name) | out-file ".\TEST.txt"
} Else {
Write-Host "$user does not exist in the group"
}}
Expected:
Output ACTIVE users in company ET that are in group O365-E3-FULL and write-host users that are not(unnecessary, I just want the filter).
Actual:
Write-hosts every ACTIVE user in company ET and ignores the group filter.
In getting your list of users you are collecting the account name for the users with:
| Select -exp samaccountname
Then in getting group members you are getting the Name with:
| Select -ExpandProperty Name
You need to be selecting SamAccountName in both of your Gets
Sorry, pretty quick knock together
# Create empty array
$answer = New-Object System.Collections.ArrayList
# If is in group then add to array
If ($members -contains $user) {
$answer.Add($user) > $null
} Else {
Write-Host $user "does not exist in the group"
}
# Output the array to the text file
Write-output $answer | out-file ".\TEST.txt"

Replace AD Group in Exchange with Users in that AD Group

We have to migrate to Microsoft Azure and since Azure cant handle AD Groups in Exchange I have to get the members of a spezifc group and then add them to exchange. So I thought I can achive this with powershell.
The princip:
I have the Mailbox Name and the Group that has to be extracted in a csv like this:
Mailbox1 GroupForMailbox1
Mailbox2 GroupForMailbox2
Mailbox2 GroupForMailbox2
I know how to extract all users out of a group:
Get-ADGroupMember -identity "GroupForMailbox1" -Recursive
But the problem is, that there is a Group in this Group which I dont want to get the users out of it. Let me call that "ExcludedGroup". How can I get all AD Group Members except the ones of the Group "ExcludedGroup"?
Then I have to put those AD Members to the specific mailbox:
$Users= "Users that I've got out of the upper command"
foreach ($Users){
Add-MailboxPermission -Identity "Mailbox1" -User $Users Accessright Fullaccess -InheritanceType all
}
But i cant fit everything of this in one Script because of lack of knowledge.
And I cant find something on the internet althought it is a real problem with azure.
I thought someone out there can help me out.
Something like this?
#Sample data
$csv = #"
Mailbox,GroupName
Mailbox1,GroupForMailbox1
Mailbox2,GroupForMailbox2
Mailbox2,GroupForMailbox2
"# | ConvertFrom-Csv
#Uncomment to import file
#$csv = Import-CSV -Path MyInputFile.csv
$ExcludedUsers = Get-ADGroupMember -Identity "ExcludedGroup" -Recursive | Select-Object -ExpandProperty SamAccountName
$csv | ForEach-Object {
$mailbox = $_.Mailbox
#Get members for group
Get-ADGroupMember -Identity $_.GroupName -Recursive |
#Remove unwanted users and keep only user objects (remove groups, computers etc.)
Where-Object { ($ExcludedUsers -notcontains $_.SamAccountName) -and ($_.objectclass -eq 'user') } |
ForEach-Object {
#Grant each group member permission
Add-MailboxPermission -Identity $mailbox -User $_.SamAccountName -AccessRights FullAccess -InheritanceType All
}
}

How to get all groups that a user is a member of?

PowerShell's Get-ADGroupMember cmdlet returns members of a specific group. Is there a cmdlet or property to get all the groups that a particular user is a member of?
I fixed my mistake: Get-Member should be Get-ADGroupMember.
Get-ADPrincipalGroupMembership will do this.
Get-ADPrincipalGroupMembership username | select name
name
----
Domain Users
Domain Computers
Workstation Admins
Company Users
Company Developers
AutomatedProcessingTeam
Single line, no modules necessary, uses current logged user:
(New-Object System.DirectoryServices.DirectorySearcher("(&(objectCategory=User)(samAccountName=$($env:username)))")).FindOne().GetDirectoryEntry().memberOf
Kudos to this vbs/powershell article: http://technet.microsoft.com/en-us/library/ff730963.aspx
A more concise alternative to the one posted by Canoas, to get group membership for the currently-logged-on user.
I came across this method in this blog post: http://www.travisrunyard.com/2013/03/26/auto-create-outlook-mapi-user-profiles/
([ADSISEARCHER]"samaccountname=$($env:USERNAME)").Findone().Properties.memberof
An even better version which uses a regex to strip the LDAP guff and leaves the group names only:
([ADSISEARCHER]"samaccountname=$($env:USERNAME)").Findone().Properties.memberof -replace '^CN=([^,]+).+$','$1'
More details about using the [ADSISEARCHER] type accelerator can be found on the scripting guy blog: http://blogs.technet.com/b/heyscriptingguy/archive/2010/08/24/use-the-powershell-adsisearcher-type-accelerator-to-search-active-directory.aspx
Old school way from CMD:
net user mst999 /domain
(GET-ADUSER –Identity USERNAME –Properties MemberOf | Select-Object MemberOf).MemberOf
This should provide you the details for current user. Powershell not needed.
whoami /groups
If you cannot get Get-ADPrincipalGroupMembership to work for you could try logging in as that user then use.
$id = [Security.Principal.WindowsIdentity]::GetCurrent()
$groups = $id.Groups | foreach-object {$_.Translate([Security.Principal.NTAccount])}
$groups | select *
While there are many excellent answers here, there is one which I was personally looking for that was missing. Once I figured it out - I thought I should post it in case I want to find it later, or it actually manages to help someone else at some point:
Get-ADPrincipalGroupMembership username | Format-Table -auto
A second approach for presenting this is to specify the individual columns you are interested in eg:
Get-ADPrincipalGroupMembership username | select name, GroupScope, GroupCategory
This gives all the AD groups the username belongs to - but also presents all of the default properties of each group formatted nicely as a table.
The key benefit this gives you is you can see at a glance which are distribution lists, & which are Security groups. You can further see at a glance which are Universal, which are DomainLocal & which are Global.
Why would you care about this last bit?
Universal group is a security or distribution group that contains
users, groups, and computers from any domain in its forest as
members. You can give universal security groups rights and
permissions on resources in any domain in the forest.
Global group is a group that can be used in its own domain, in member
servers and in workstations of the domain, and in trusting domains.
In all those locations, you can give a global group rights and
permissions and the global group can become a member of local groups.
However, a global group can contain user accounts that are only from
its own domain.
Domain local group is a security or distribution group that can
contain universal groups, global groups, other domain local groups
from its own domain, and accounts from any domain in the forest. You
can give domain local security groups rights and permissions on
resources that reside only in the same domain where the domain local
group is located.
Get-Member is not for getting user's group membership. If you want to get a list of groups a user belongs to on the local system, you can do so by:
$query = "ASSOCIATORS OF {Win32_Account.Name='DemoUser1',Domain='DomainName'} WHERE ResultRole=GroupComponent ResultClass=Win32_Account"
Get-WMIObject -Query $query | Select Name
In the above query, replace DemoUser1 with the username you want and the DomainName with either your local computer name or domain name.
Get group membership for a user:
$strUserName = "Primoz"
$strUser = get-qaduser -SamAccountName $strUserName
$strUser.memberof
See Get Group Membership for a User
But also see Quest's Free PowerShell Commands for Active Directory.
[Edit: Get-ADPrincipalGroupMembership command is included in Powershell since v2 with Windows 2008 R2. See kstrauss' answer below.]
Get-Member is a cmdlet for listing the members of a .NET object. This has nothing to do with user/group membership. You can get the current user's group membership like so:
PS> [System.Security.Principal.WindowsIdentity]::GetCurrent().Groups |
Format-Table -auto
BinaryLength AccountDomainSid Value
------------ ---------------- -----
28 S-1-5-21-... S-1-5-21-2229937839-1383249143-3977914998-513
12 S-1-1-0
28 S-1-5-21-... S-1-5-21-2229937839-1383249143-3977914998-1010
28 S-1-5-21-... S-1-5-21-2229937839-1383249143-3977914998-1003
16 S-1-5-32-545
...
If you need access to arbitrary users' group info then #tiagoinu suggestion of using the Quest AD cmdlets is a better way to go.
I wrote a PowerShell function called Get-ADPrincipalGroupMembershipRecursive. It accepts the DSN of a user, computer, group, or service account. It retrieves an initial list of groups from the account's memberOf attribute, then recursively checks those group's memberships. Abbreviated code is below. Full source code with comments can be found here.
function Get-ADPrincipalGroupMembershipRecursive( ) {
Param(
[string] $dsn,
[array]$groups = #()
)
$obj = Get-ADObject $dsn -Properties memberOf
foreach( $groupDsn in $obj.memberOf ) {
$tmpGrp = Get-ADObject $groupDsn -Properties memberOf
if( ($groups | where { $_.DistinguishedName -eq $groupDsn }).Count -eq 0 ) {
$groups += $tmpGrp
$groups = Get-ADPrincipalGroupMembershipRecursive $groupDsn $groups
}
}
return $groups
}
# Simple Example of how to use the function
$username = Read-Host -Prompt "Enter a username"
$groups = Get-ADPrincipalGroupMembershipRecursive (Get-ADUser $username).DistinguishedName
$groups | Sort-Object -Property name | Format-Table
No need for long scripts when it is a simple one liner..
QUEST Command
(Get-QADUser -Identity john -IncludedProperties MemberOf | Select-Object MemberOf).MemberOf
MS AD Command
(GET-ADUSER –Identity john –Properties MemberOf | Select-Object MemberOf).MemberOf
I find the MS AD cmd is faster but some people like the Quest ones better..
Steve
Use:
Get-ADPrincipalGroupMembership username | select name | export-CSV username.csv
This pipes output of the command into a CSV file.
First, import the ActiveDirectory module:
Import-Module ActiveDirectory
Then issue this command:
Get-ADGroupMember -Identity $group | foreach-object {
Write-Host $_.SamAccountName
}
This will display the members of the specified group.
It is just one line:
(get-aduser joe.bloggs -properties *).memberof
end of :)
The below works well:
get-aduser $username -Properties memberof | select -expand memberof
If you have a list of users:
$list = 'administrator','testuser1','testuser2'
$list | `
%{
$user = $_;
get-aduser $user -Properties memberof | `
select -expand memberof | `
%{new-object PSObject -property #{User=$user;Group=$_;}} `
}
Get-QADUser -SamAccountName LoginID | % {$_.MemberOf } | Get-QADGroup | select name
Get-ADUser -Filter { memberOf -RecursiveMatch "CN=Administrators,CN=Builtin,DC=Fabrikam,DC=com" } -SearchBase "CN=Administrator,CN=Users,DC=Fabrikam,DC=com" -SearchScope Base
## NOTE: The above command will return the user object (Administrator in this case) if it finds a match recursively in memberOf attribute.
I couldn't get the following to work for a particular user:
Get-ADPrincipalGroupMembership username
It threw an error that I was not willing to troubleshoot.
I did however come up with a different solution using Get-ADUser. I like it a bit better because if you don't know the account name then you can get it based off of a wildcard on the user's actual name. Just fill in PartOfUsersName and away it goes.
#Get the groups that list of users are the member of using a wildcard search
[string]$UserNameLike = "*PartOfUsersName*" #Use * for wildcards here
[array]$AccountNames = $(Get-ADUser -Filter {Name -like $UserNameLike}).SamAccountName
ForEach ($AccountName In $AccountNames) {
Write-Host "`nGETTING GROUPS FOR" $AccountName.ToUpper() ":"
(Get-ADUser -Identity $AccountName -Properties MemberOf|select MemberOf).MemberOf|
Get-ADGroup|select Name|sort name
}
Huge props to schmeckendeugler and 8DH for getting me to this solution. +1 to both of you.
To get it recursive, you can use:
<#
.SYNOPSIS
Get all the groups that a user is MemberOf.
.DESCRIPTION
This script retrieves all the groups that a user is MemberOf in a recursive way.
.PARAMETER SamAccountName
The name of the user you want to check #>
Param (
[String]$SamAccountName = 'test',
$DomainUsersGroup = 'CN=Domain Users,CN=Users,DC=domain,DC=net'
)
Function Get-ADMemberOf {
Param (
[Parameter(ValueFromPipeline)]
[PSObject[]]$Group,
[String]$DomainUsersGroup = 'CN=Domain Users,CN=Users,DC=grouphc,DC=net'
)
Process {
foreach ($G in $Group) {
$G | Get-ADGroup | Select -ExpandProperty Name
Get-ADGroup $G -Properties MemberOf| Select-Object Memberof | ForEach-Object {
Get-ADMemberOf $_.Memberof
}
}
}
}
$Groups = Get-ADUser $SamAccountName -Properties MemberOf | Select-Object -ExpandProperty MemberOf
$Groups += $DomainUsersGroup
$Groups | Get-ADMemberOf | Select -Unique | Sort-Object
Studying all comments presented gave me a starting point (thanks for such) but left me with several unresolved issues. As result here is my answer. The code snippet provided does a little more than what is asked for but it provides helpful debugging info.
[array] $script:groupsdns = #()
function Get-ADPrincipalGroupMembershipRecursive()
{
Param( [string] $dn, [int] $level = 0, [array] $groups = #() )
#if(($groupsdns | where { $_.DistinguishedName -eq $dn }).Count -ne 0 ) { return $groups } # dependency on next statement
#$groupsdns += (Get-ADObject $dn -Properties MemberOf) # Get-ADObject cannot find an object with identity
if ($script:groupsdns.Contains($dn)) { return $groups }
$script:groupsdns += $dn
$mo = $Null
$mo = Get-ADObject $dn -Properties MemberOf # Get-ADObject cannot find an object with identity
$group = ($dn + " (" + $level.ToString())
if ($mo -eq $Null) { $group += "!" }
$group += ")"
$groups += $group
foreach( $groupdn in $mo.MemberOf )
{
$groups = Get-ADPrincipalGroupMembershipRecursive -dn $groupdn -level ($level+1) -groups $groups
}
if ($level -le 0)
{
$primarygroupdn = (Get-ADUser -Identity $dn -Properties PrimaryGroup).PrimaryGroup
$groups = Get-ADPrincipalGroupMembershipRecursive -dn $primarygroupdn -level ($level+1) -groups $groups
}
return $groups
}
$adusergroups = Get-ADPrincipalGroupMembershipRecursive -dn $aduser.DistinguishedName
$adusergroups | ft -AutoSize | `
Out-File -Width 512 Get-ADPrincipalGroupMembershipRecursive.txt #-Append #-Wrap # | Sort-Object -Property Name
When you do not have privileges to consult other member groups but you do have the privilege to consult group members, you can do the following to build a map of which user has access to which groups.
$groups = get-adgroup -Filter * | sort name | select Name
$users = #{}
foreach($group in $groups) {
$groupUsers = #()
$groupUsers = Get-ADGroupMember -Identity $group.Name | Select-Object SamAccountName
$groupUsers | % {
if(!$users.ContainsKey($_.SamAccountName)){
$users[$_.SamAccountName] = #()
}
($users[$_.SamAccountName]) += ($group.Name)
}
}
For LOCAL users and groups (ie not in Active Directory), and if you don't want to, or aren't allowed to, or can't install RSAT and/or Install-WindowsFeature RSAT-AD-PowerShell and/or import-module activedirectory then here's a pure, pre-installed powershell (5.1+) way to do it.
(Note: Get-LocalGroup* used below are only available Powershell v5.1 and above. "...v5.1 was released along with the Windows 10 Anniversary Update on August 2, 2016, and in Windows Server 2016. ...[F]or Windows 7, Windows Server 2008, Windows Server 2008 R2, Windows Server 2012, and Windows Server 2012 R2 [it] was released on January 19, 2017." (wikipedia))
$username = "user002"
Get-LocalGroup | ForEach-Object {
# the usernames are returned in the string form "computername\username"
if (Get-LocalGroupMember -Group $_ | Where-Object name -like "*\$username") {
$_.name
}
}
Example output:
Administrators
Users
Import-Module ActiveDirectory
Get-ADUser -SearchBase "OU=Users,DC=domain,DC=local" -Filter * | foreach-object {
write-host "User:" $_.Name -foreground green
Get-ADPrincipalGroupMembership $_.SamAccountName | foreach-object {
write-host "Member Of:" $_.name
}
}
Change the value of -SearchBase to reflect the OU you need to list the users from :)
This will list all of the users in that OU and show you which groups they are a member of.
Get-ADPrincipalGroupMembership USERLOGON | select name
This is the simplest way to just get the names:
Get-ADPrincipalGroupMembership "YourUserName"
# Returns
distinguishedName : CN=users,OU=test,DC=SomeWhere
GroupCategory : Security
GroupScope : Global
name : testGroup
objectClass : group
objectGUID : 2130ed49-24c4-4a17-88e6-dd4477d15a4c
SamAccountName : testGroup
SID : S-1-5-21-2114067515-1964795913-1973001494-71628
Add a select statement to trim the response or to get every user in an OU every group they are a user of:
foreach ($user in (get-aduser -SearchScope Subtree -SearchBase $oupath -filter * -Properties samaccountName, MemberOf | select samaccountName)){
Get-ADPrincipalGroupMembership $user.samaccountName | select name}
Almost all above solutions used the ActiveDirecotry module which might not be available by default in most cases.
I used below method. A bit indirect, but served my purpose.
List all available groups
Get-WmiObject -Class Win32_Group
And then list the groups the user belongs to
[System.Security.Principal.WindowsIdentity]::GetCurrent().Groups
Comparison can then be done via checking through the SIDs. This works for the logged in user. Please correct me if I am wrong. Completely new to PowerShell, but had to get this done for a work commitment.
With user input and fancy output formatting:
[CmdletBinding(SupportsShouldProcess=$True)]
Param(
[Parameter(Mandatory = $True)]
[String]$UserName
)
Import-Module ActiveDirectory
If ($UserName) {
$UserName = $UserName.ToUpper().Trim()
$Res = (Get-ADPrincipalGroupMembership $UserName | Measure-Object).Count
If ($Res -GT 0) {
Write-Output "`n"
Write-Output "$UserName AD Group Membership:"
Write-Output "==========================================================="
Get-ADPrincipalGroupMembership $UserName | Select-Object -Property Name, GroupScope, GroupCategory | Sort-Object -Property Name | FT -A
}
}
Putting this here for future reference. I'm in the midst of an email migration. I need to know each user account and its respective group membership, and also I need to know each group and its respective members.
I'm using the code block below to output a CSV for each user's group membership.
Get-ADUser -Filter * |`
ForEach-Object { `
$FileName = $_.SamAccountName + ".csv" ; `
$FileName ; `
Get-ADPrincipalGroupMembership $_ | `
Select-Object -Property SamAccountName, name, GroupScope, GroupCategory | `
Sort-Object -Property SamAccountName | `
Export-Csv -Path $FileName -Encoding ASCII ; `
}
The export process for the groups and their respective members was a little convoluted, but the below works. The output filenames include the type of group. Therefore, the email distribution groups I need are/should be the Universal and Global Distribution groups. I should be able to just delete or move the resulting TXT files I don't need.
Get-ADGroup -Filter * | `
Select-Object -Property Name, DistinguishedName, GroupScope, GroupCategory | `
Sort-Object -Property GroupScope, GroupCategory, Name | `
Export-Csv -Path ADGroupsNew.csv -Encoding ASCII
$MyCSV = Import-Csv -Path .\ADGroupsNew.csv -Encoding ASCII
$MyCSV | `
ForEach-Object { `
$FN = $_.GroupScope + ", " + $_.GroupCategory + ", " + $_.Name + ".txt" ; `
$FN ; `
Get-ADGroupMember -Identity $_.DistinguishedName | `
Out-File -FilePath $FN -Encoding ASCII ; $FN=""; `
}