Hey, Scripting Guy! How Can I Use Windows PowerShell to Identify Inactive User Accounts in Active Directory Domain Services?


Hey, Scripting Guy! Question Hey, Scripting Guy! I need to use Windows PowerShell to identify inactive user accounts in Active Directory Domain Services (AD DS). I used to have a VBScript script that I would use, but I would like to be able to use Windows PowerShell 2.0 and the new Active Directory cmdlets that come with Windows Server 2008 R2. Is this something that can easily be accomplished?

— GJ

Hey, Scripting Guy! Answer Hello GJ,

Microsoft Scripting Guy Ed Wilson here. I believe the weather person made a mistake. In fact, I am nearly positive. The weather forecast for the entire week is exactly the same as yesterday’s weather forecast—hot, humid, and a chance of afternoon thundershowers. Dude, Craig and I could never get away with posting the same Hey, Scripting Guy! Blog post for seven days in a row. Where is the weather guesser’s manager? Where is the person in charge of quality control? Who monitors the incoming email for the department of redundancy department? They never make a mistake like this when the weather is mild and sunny with low humidity—it is not fair!

GJ, luckily we have air conditioning, and because it is too hot and humid to be outside in my woodworking shop, I decided to come in and check the email sent to scripter@microsoft.com. By using the Active Directory cmdlets that come with Windows Server 2008 R2, it is easy to query for information about user accounts. The Get-ADUser Windows PowerShell cmdlet is fairly intuitive and actually quite fun to use.

The first thing you will need to do is to import the ActiveDirectory module into the current Windows PowerShell session. To quickly obtain a listing of all the users in Active Directory, supply a wildcard character to the -Filter parameter of the Get-ADUser cmdlet, as shown in the following image.

Image of obtaining a list of all users in Active Directory

If you wish to change the base of the search operations, use the SearchBase parameter. The SearchBase parameter accepts an LDAP style of naming. The following command changes the search base to the hsg_TestOU:

Get-ADUser -Filter * -SearchBase “ou=hsg_TestOU,dc=nwtraders,dc=com”

When using the Get-ADUser cmdlet, only a certain subset of user properties is displayed (10 properties, to be exact). These properties will be displayed when you pipe the results to Format-List and use a wildcard character and the -Force parameter as shown here:

PS C:> Get-ADUser -Identity bob | format-list -Property * -Force 
DistinguishedName : CN=bob,OU=HSG_TestOU,DC=NWTraders,DC=Com 
Enabled : True 
GivenName : bob 
Name : bob 
ObjectClass : user 
ObjectGUID : 5cae3acf-f194-4e07-a466-789f9ad5c84a 
SamAccountName : bob 
SID : S-1-5-21-3746122405-834892460-3960030898-3601 
Surname : 
UserPrincipalName : bob@NWTraders.Com 
PropertyNames : {DistinguishedName, Enabled, GivenName, Name…} 
PropertyCount : 10 
PS C:>

Anyone who knows very much about Active Directory Domain Services (AD DS) knows there are certainly more than 10 properties associated with a user object. Does this mean we need to use the Get-ADObject cmdlet that was examined yesterday?

If I try to display a property that is not returned by the Get-ADUser cmdlet, such as the whenCreated property, an error is not returned. The value of the property is not returned. This is shown here:


PS C:> Get-ADUser -Identity bob | Format-List -Property name, whenCreated 
name : bob 
whencreated :

I used the whenCreated property for the user object because I know that it has a value. But suppose I was looking for users that had never logged onto the system? Suppose I used a query such as the one shown here, and I was going to base a delete operation upon the results. The results could be disastrous.


PS C:> Get-ADUser -Filter * | Format-Table -Property name, LastLogonDate 
name LastLogonDate 
—- ————- 
<results truncated>

To retrieve a property that is not a member of the default 10 properties, you must select it by using the –property parameter. The reason that Get-ADUser does not automatically return all properties and their associated values is because of performance reasons on large networks—there is no reason to return a large dataset when a small dataset will perfectly suffice. To display the name and the whenCreated date for the user named “bob,” the following command can be used:


PS C:> Get-ADUser -Identity bob -Properties whencreated | Format-List -Property name 
, whencreated 
name : bob 
whencreated : 6/11/2010 8:19:52 AM 
PS C:>

To retrieve all of the properties associated with a user object, use the wildcard character “*” for the Properties parameter value. You would use a command similar to the one shown here:


Get-ADUser -Identity bob -Properties

The results of this command are shown in the following image.

Image of results of command

To produce a listing of all the users and their last logon date, you can use a command similar to the one shown here. This is a single command that might wrap the line, depending on your screen resolution:


Get-ADUser -Filter * -Properties “LastLogonDate” | 

sort-object -property lastlogondate -descending | 

Format-Table -property name, lastlogondate -AutoSize

The output produces a nice table that is shown in the following image.

Image of table produced

GJ, that is all there is to using Active Directory cmdlets to work with user objects. Active Directory Week will continue tomorrow when we will talk about working with computer objects.

We invite you to follow us on Twitter or Facebook. If you have any questions, send email to us at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum.. See you tomorrow. Until then, peace.


Ed Wilson and Craig Liebendorfer, Scripting Guys