Install the Quest CMDlets and then run this code:
Add-PSSnapin Quest.ActiveRoles.ADManagement
$memberships = @()
Get-QADGroup -SizeLimit 0 | Foreach-Object {
$NameGroup = $_.Name
Write-Host "Working with $NameGroup"
$membership = Get-QADGroupMember $_.DN -Enabled -SizeLimit 0
if ($membership -ne $null ) {
$membership | Add-Member -type NoteProperty -name AuditGroupUserIsMemberOf -value $_.Name
$memberships += $membership
}
}
$memberships | Select-Object AuditGroupUserIsMemberOf, NTAccountname | Export-Csv "GroupsWithUsers.csv"
This will give you a 1 record per group-user connection so expect multiple occurrences of users and groups. If you wan't other fields, you can just edit the Select-Object
statement. Use $memberships | gm
to see all the possibilities for the users. If you want more fields for the groups, use Get-QADGroup | gm
, you will then need to add these by adding a new NoteProperty
.
If you don't really care about more options, here is a one-liner you can just mash in the terminal:
Get-QADGroup -sizeLimit 0 | select @{name="Group";expression={$_.name}} -expand members | select Group,@{n='User';e={ (Get-QADObject $_).NTAccountName}} | Export-Csv "MyUsersAndGroups.csv"
The ActiveDirectory
module has clever logic that calculate "popular" properties like whether a user account is Enabled
or have PasswordNeverExpires
set and presents them like regular attributes.
Internally, they're derived from actual account attributes like userAccountControl
and pwdLastSet
.
Account Settings
userAccountControl
is a bitfield, and contains a long list of account security related settings, like "User cannot change password" and account "Disabled".
Microsoft's LDAP implementation let's you filter such an attribute with bitwise operators, identified by an Object Identifier (OID):
LDAP_MATCHING_RULE_BIT_AND: 1.2.840.113556.1.4.803
LDAP_MATCHING_RULE_BIT_OR : 1.2.840.113556.1.4.804
To find Disabled
accounts, we can use the following filter syntax:
(&(userAccountControl:1.2.840.113556.1.4.803:=2))
As always, you can negate an ldap expression with !
, in this example retrieving all Enabled
accounts:
(!(userAccountControl:1.2.840.113556.1.4.803:=2))
Likewise, a setting called DONT_EXPIRE_PASSWORD
has value 65536 (0x10000), and we can find these accounts with:
(&(userAccountControl:1.2.840.113556.1.4.803:=65536))
Password Expiration
Calculating password expiration is a bit more complicated. To aid developers and integrators, Microsoft has implemented a dynamic attribute named msDS-User-Account-Control-Computed
.
msDS-User-Account-Control-Computed
transparently returns the same value as userAccountControl
, but with the addition of the following bits, computed on the fly at lookup time:
UF_LOCKOUT 0x0010
UF_PASSWORD_EXPIRED 0x800000
UF_PARTIAL_SECRETS_ACCOUNT 0x4000000
UF_USE_AES_KEYS 0x8000000
I haven't tested this, but if memory serves me right, this should help you reliably identify accounts with expired passwords with this filter:
(&(msDS-User-Account-Control-Computed:1.2.840.113556.1.4.803:=8388608))
Unfortunately you cannot use contructed attributes in LDAP query filters, so what you'll have to do is filter on the first two statements:
(&(!userAccountControl:1.2.840.113556.1.4.803:=2)(!userAccountControl:1.2.840.113556.1.4.803:=65536))
Be sure to ask the directory server for the msDS-User-Account-Control-Computed
value, and then perform your bitwise AND mask on the results, client-side.
Best Answer
As indicated by the cmdlet help, Identity does not accept an array of input:
So, you can loop over an array of input:
Or you can run against an entire OU:
Or construct an appropriate LDAPFilter
Or any number of other ways. But your best bet is always the help. If you don't have it downloaded, there's always:
You should be able to find examples, if not, these should give you an idea of where to start: https://docs.microsoft.com/en-us/powershell/module/activedirectory/get-aduser?view=winserver2012-ps&redirectedfrom=MSDN#examples