Getting usernames from active directory with powershell
From Svendsen Tech Powershell Wiki
Often as a Windows system administrator, you will need to retrieve lists of users from (an OU in) Active Directory. Here I demonstrate a few ways of doing it with PowerShell, using Get-ADUser from the Microsoft AD cmdlets, Get-QADUser from the Quest ActiveRoles cmdlets and also with LDAP/ADSI and DirectoryServices.DirectorySearcher.
These MS AD cmdlets that Get-ADUser and Get-ADObject are part of are installed as a feature under the category "Remote Server Administration Tools" (RSAT) from Server Manager on Windows Server 2008 R2 and Windows 7. There's more information about this here and here.
See this article for getting computer names.
Contents |
Using Get-ADUser
First, you need to import the Active Directory module from Microsoft.
PS C:\> Import-Module ActiveDirectory PS C:\>
Then you can simply use the filter "*" to target any user. Here I get the names of the last five users, using Select-Object to limit the results.
PS C:\> Get-ADUser -Filter '*' | Select -Exp Name -Last 5 hoppla testadmin deploymentuser SharePoint SharePointServices
Targeting A Specific OU
Here I target the OU svendsen.local/Bruker, using the SearchBase parameter and the OU's LDAP distinguished name:
PS C:\> Get-ADUser -SearchBase 'OU=Bruker,DC=svendsen,DC=local' -Filter '*' | Select -Exp Name pwdnotusr1 pwdnotusr2 pwdnotusr3
Get-ADUser Example With LastLogonTimestamp
With the Quest cmdlets described below, the LastLogonTimestamp attribute is automatically converted to a human-readable date for you. You will have to use something like this with Get-ADUser from the Microsoft cmdlets:
PS C:\> Get-ADUser -Filter '*' -Properties LastLogonTimestamp |
Sort LastLogonTimestamp |
Select Name,@{n='LastLogonTimestamp';e={if ($_.LastLogonTimestamp) { [datetime]::FromFileTime($_.LastLogonTimestamp)} } }
Name LastLogonTimestamp
---- ------------------
pwdnotusr3
pwdnotusr1
tullebruker
SharePointServices
deploymentuser
hoppla
krbtgt
Guest
SCCMuser 3/26/2011 2:04:12 PM
pwdnotusr2 9/25/2011 4:25:12 AM
testadmin 12/16/2011 3:10:29 PM
Administrator 3/3/2012 12:00:00 AM
SCOMuser 3/7/2012 1:15:40 AM
scomnotify 3/13/2012 3:25:16 AM
SharePoint 3/14/2012 1:15:34 AM
joakimbs 3/17/2012 7:14:01 AM
Using Get-ADObject And An LDAP Query
I describe this in more detail in the DirectorySearcher section, but basically this LDAP query filters out contacts and gets only "regular" user accounts.
PS C:\> Get-ADObject -LDAPFilter '(&(objectCategory=Person)(objectClass=User))' | Select -Exp Name -First 5 Guest krbtgt Administrator scomnotify SCOMuser
Using ADSI and DirectorySearcher
Here's a way of getting usernames that start with "scom". I filter after the query, using PowerShell's Where-Object cmdlet. To dump every single user, just leave out the last part (" | ? { $_ -imatch '^scom' }"). "?" is an alias for Where-Object/Where.
Using DirectoryServices.DirectorySearcher, you can have some logic in the LDAP query. To get users, you can use something like "objectCategory=User", but this will also get contacts. To get only "regular" user accounts, you can normally use "(&(objectCategory=Person)(objectClass=User))".
Also be aware that the properties you index from the returned System.DirectoryServices.ResultPropertyCollection object are case-sensitive. This almost tripped me up. All the properties appear to be all lowercase when you look at the object.
Here's the first, simple example:
PS C:\> $DirSearcher = New-Object System.DirectoryServices.DirectorySearcher([adsi]'')
PS C:\> $DirSearcher.Filter = '(&(objectCategory=Person)(objectClass=User))'
PS C:\> $DirSearcher.FindAll().GetEnumerator() | %{ $_.Properties.name } | ? { $_ -imatch '^scom' }
scomnotify
SCOMuser
I should also mention that there's a type accelerator in PowerShell v2 (I don't know about v1.x), which allows you to skip a few steps like this (notice the two quotes after the type accelerator):
PS C:\> $DirSearcher = [adsisearcher]'' PS C:\>
Here's what the returned System.DirectoryServices.ResultPropertyCollection object looks like:
PS C:\> $DirSearcher.FindAll().GetEnumerator() | select -first 1 | %{ $_.Properties | gm }
TypeName: System.DirectoryServices.ResultPropertyCollection
Name MemberType Definition
---- ---------- ----------
Clear Method System.Void Clear()
Contains Method bool Contains(string propertyName)
CopyTo Method System.Void CopyTo(System.DirectoryServices.ResultPropertyValueCollection[] arra...
Equals Method bool Equals(System.Object obj)
GetEnumerator Method System.Collections.IDictionaryEnumerator GetEnumerator()
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Item ParameterizedProperty System.DirectoryServices.ResultPropertyValueCollection Item(string name) {get;}
Count Property System.Int32 Count {get;}
PropertyNames Property System.Collections.ICollection PropertyNames {get;}
Values Property System.Collections.ICollection Values {get;}
And these are the properties:
PS C:\> $DirSearcher.FindAll().GetEnumerator() | select -first 1 | %{ $_.Properties.PropertyNames }
iscriticalsystemobject
samaccountname
useraccountcontrol
primarygroupid
instancetype
objectclass
pwdlastset
memberof
samaccounttype
usnchanged
accountexpires
adspath
distinguishedname
codepage
name
whenchanged
dscorepropagationdata
description
countrycode
cn
whencreated
objectsid
objectguid
objectcategory
usncreated
Code Example To Dump Every User In AD
Here is a script to dump every single user in AD (not including contacts), using DirectorySearcher.
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
$DirSearcher = New-Object System.DirectoryServices.DirectorySearcher([adsi]'')
$DirSearcher.Filter = '(&(objectCategory=Person)(objectClass=User))'
$DirSearcher.FindAll().GetEnumerator() | ForEach-Object {
# These properties are part of a DirectoryServices.ResultPropertyCollection
# NB! These properties need to be all lowercase!
$_.Properties.name
}
Targeting A Specific OU With ADSI/LDAP/DirectorySearcher
Change this line:
$DirSearcher = New-Object System.DirectoryServices.DirectorySearcher([adsi]'LDAP://OU=Bruker,dc=svendsen,dc=local')
The relevant part is "[adsi]'LDAP://OU=Bruker,dc=svendsen,dc=local'". Here I target the OU svendsen.local/Bruker.
If you were to use the [adsisearcher] type accelerator, it would look like this:
$DirSearcher = [adsisearcher][adsi]'LDAP://OU=Bruker,dc=svendsen,dc=local'
Getting Accounts With An LDAP Query
Here I describe how to use DirectoryServices.DirectoryServices and an LDAP query for getting disabled and enabled AD accounts. There's some more information here at this external technet.com link.
Getting Disabled AD Accounts
During earlier research, I found that you can use the following LDAP query for getting disabled AD accounts:
(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2))
Putting it to use, we get:
PS C:\> $DirSearcher = New-Object System.DirectoryServices.DirectorySearcher([adsi]'')
PS C:\> $DirSearcher.Filter = '(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2))'
PS C:\> $DirSearcher.FindAll().GetEnumerator() | %{ $_.Properties.name }
Guest
krbtgt
PS C:\>
Getting Enabled AD Accounts
For getting enabled AD accounts, you can use the following LDAP query:
(&(objectCategory=person)(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))
This basically means "not disabled". The exclamation point, enclosed in parentheses in the LDAP query, negates the logic from the disabled user query - effectively retrieving users that are not disabled.
Putting it to use, we get:
PS C:\> $DirSearcher = New-Object System.DirectoryServices.DirectorySearcher([adsi]'')
PS C:\> $DirSearcher.Filter = '(&(objectCategory=person)(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))'
PS C:\> $DirSearcher.FindAll().GetEnumerator() | %{ $_.Properties.name }
Administrator
scomnotify
SCOMuser
joakimbs
SCCMuser
tullebruker
pwdnotusr1
pwdnotusr2
pwdnotusr3
hoppla
testadmin
deploymentuser
SharePoint
SharePointServices
PS C:\>
Using Get-QADUser
Using the seemingly mature cmdlets found in Quest ActiveRoles, you can retrieve users easily. This also works against Windows Server 2003 Active Directories without Active Directory Web Services running.
First, you need to add the snap-in, unless you start Quest's separate shell:
PS C:\> Add-PSSnapin Quest.ActiveRoles.ADManagement PS C:\>
Getting Every Single User From AD
This isn't difficult using Quest ActiveRoles. By default the number of retrieved results is limited to 1000, but you can set a higher limit using the -SizeLimit parameter, or set it to 0, which disables the limit.
PS C:\> Get-QADUser -SizeLimit 0 | Select -Exp Name Guest krbtgt Administrator scomnotify SCOMuser joakimbs SCCMuser tullebruker pwdnotusr1 pwdnotusr2 pwdnotusr3 hoppla testadmin deploymentuser SharePoint SharePointServices PS C:\>
Getting Disabled AD Users
This is a breeze with the -Disabled parameter for Get-QADUser:
PS C:\> Get-QADUser -SizeLimit 0 -Disabled | Select -Exp Name Guest krbtgt PS C:\>
Targeting A Specific OU With Get-QADUser
Use the -SearchRoot parameter:
PS C:\> Get-QADUser -SizeLimit 0 -SearchRoot svendsen.local/Bruker Name Type DN ---- ---- -- pwdnotusr1 user CN=pwdnotusr1,OU=Bruker,DC=svendsen,DC=local pwdnotusr2 user CN=pwdnotusr2,OU=Bruker,DC=svendsen,DC=local pwdnotusr3 user CN=pwdnotusr3,OU=Bruker,DC=svendsen,DC=local
Get-QADUser Example With LastLogonTimestamp
Here's an example where I include the LastLogonTimestamp property. Unlike with Get-ADUser from Microsoft, it's automatically converted to a human-readable date for you.
PS C:\> Get-QADUser -SizeLimit 0 -IncludedProperties LastLogonTimestamp | Select Name,LastLogonTimestamp Name LastLogonTimestamp ---- ------------------ Guest krbtgt Administrator 3/3/2012 12:00:00 AM scomnotify 3/13/2012 3:25:16 AM SCOMuser 3/7/2012 1:15:40 AM joakimbs 3/17/2012 7:14:01 AM SCCMuser 3/26/2011 2:04:12 PM tullebruker pwdnotusr1 pwdnotusr2 9/25/2011 4:25:12 AM pwdnotusr3 hoppla testadmin 12/16/2011 3:10:29 PM deploymentuser SharePoint 3/14/2012 1:15:34 AM SharePointServices
