TIP: 2 Ways userAccountControl Is Easier In AD PowerShell


BackgrounduserAccountControl

Anyone who wants to write scripts for Active Directory will eventually run into the famous userAccountControl attribute.  Usually this comes up when you are searching for disabled accounts.  Actually this attribute is a bit flag for 22 different account settings!  You can find them clearly documented in KB305144.  In the GUI you find these settings represented by checkboxes in Active Directory Users and Computers (ADUC) (pictured right).

I’ve done my share of VBScripts over the last 10 years, and this always took more lines of code than I wanted to write.  In this example on the Hey Scripting Guy blog you can see it would take 14 lines of code to report on disabled accounts.  To make matters worse you had to understand LDAP bitwise filter syntax.  In an earlier post I demonstrated this syntax for querying AD based on a bit value.

The good news is that in Windows Server 2008 R2 and above we have two cmdlets that make this easy.

One Line Of PowerShell

With the Active Directory module for PowerShell and the Search-ADAccount cmdlet those 14 lines of VBScript turn into a single line:

PS C:\> Search-ADAccount -AccountDisabled

To limit the results to users or computers you can try one of these handy switches:

PS C:\> Search-ADAccount –AccountDisabled –UsersOnly

PS C:\> Search-ADAccount –AccountDisabled –ComputersOnly

The Search-ADAccount cmdlet has several switches that target the userAccountControl bit flags:

  • AccountDisabled
  • AccountExpired
  • AccountExpiring
  • LockedOut
  • PasswordExpired
  • PasswordNeverExpires
  • AccountInactive (not really UserAccountControl, but very handy!)

Now we don’t have to fuss with all of the fancy LDAP syntax.

But wait… there’s more!

The Set-ADAccountControl cmdlet gives us 12 switches to toggle these checkboxes via script:

  • AccountNotDelegated
  • AllowReversiblePasswordEncryption
  • CannotChangePassword
  • DoesNotRequirePreAuth
  • Enabled
  • HomedirRequired
  • MNSLogonAccount
  • PasswordNeverExpires
  • PasswordNotRequired
  • TrustedForDelegation
  • TrustedToAuthForDelegation
  • UseDESKeyOnly

Now you can turn the flags on and off like this:

PS C:\> Set-ADAccountControl JoeUser –PasswordNeverExpires $true

PS C:\> Set-ADAccountControl JoeUser –PasswordNeverExpires $false

Wow!  Now that was easy.

PS…

Closing reminders:

  • You’ll need the RSAT for Windows 7 or Windows 8 to get the cmdlets on your workstation.
  • Don’t forget to type Import-Module ActiveDirectory before trying these one-liners.
  • You can even run these against legacy 2003 or 2008 domain controllers using the guidance here.

Enjoy!

Comments (14)

  1. To find users with the DES flag use this:

    Get-ADUser -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=2097152)'

    or

    Get-ADUser -Filter 'userAccountControl -band 2097152'

    See this post for an explanation of LDAP bitwise filters:

    blogs.technet.com/…/rip-off-the-bandaid-with-powershell-using-bitwise-ldap-filters-to-search-and-destroy-manual-server-connection-objects.aspx

  2. Can you explain your scenario more?  I cannot reproduce that error in my lab.  What OS is your client and server?  Thanks.

  3. Hi,

    thanks for this article. It helps to get all the cool stuff sorted 🙂

  4. bs says:

    very nice and makes my life easier.

    Unfortunately i get an unspecific error if i try to search for all locket out users.(searchADAccount -lockedout):

    Invalid Win32-Filetime

    Any ideas?

  5. bs says:

    AD Domaincontrollers W2k8R2, Forest/Domain Functionlevel 2003

    I tried the command on my 2008R2 Admin Server and on the DC itsself.

    I think there are values in the lockouttime Attribute that bring an exception with this cmdlet. But i don't know wich values.

    Heres the whole errormessage:

    "

    Search-ADAccount : Ungültige Win32-FileTime.

    Parametername: fileTime

    In Zeile:1 Zeichen:1

    + Search-ADAccount -LockedOut

    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~

       + CategoryInfo          : InvalidArgument: (:) [Search-ADAccount], ArgumentOutOfRangeException

       + FullyQualifiedErrorId : Ungültige Win32-FileTime.

    Parametername: fileTime,Microsoft.ActiveDirectory.Management.Commands.SearchADAccountCmdlet

    "

  6. anonymouscommenter says:

    I am trying to search by UseDESKeyOnly.  It doesn't seem to be an option with Search-ADAccoun and there does not seem to be a Set-ADAccountControl cmdlet.  Any ideas?

  7. anonymouscommenter says:

    Hello, how do i find users who have “account is senstive and cannot be delegated” setting checked in AD?

    I m thinking one of these should tell
    get-aduser -identity “John.Doe” -properties * | ft name, useraccountcontrol, AccountNotDelegated, TrustedForDelegation, TrustedToAuthForDelegation

    If correct, can you confirm which one? Thanks.

  8. To find users who have “account is sensitive and cannot be delegated” setting checked use this:
    Get-ADUser -LDAPFilter ‘(userAccountControl:1.2.840.113556.1.4.803:=1048576)’
    or
    Get-ADUser -Filter ‘userAccountControl -band 1048576’
    See this KB for an explanation of the userAccountControl bits:
    http://support.microsoft.com/kb/305144

  9. anonymouscommenter says:

    It worked! Thank you! I had read the KB but i couldnt figure out how to put this in the script/command.

  10. anonymouscommenter says:

    Welcome! Today’s post includes demo scripts and links from the Microsoft Virtual Academy event: Using PowerShell for Active Directory . We had a great time creating this for you, and I hope you will share it with anyone needing to ramp up their

  11. anonymouscommenter says:

    I am sorry but I am a noob with Powershell. I have a list of 1200 users that I need to change the UserAccountControl flag for PasswordNotRequired to false. This is the command I am use for a single user. I have CSV with the affected users by SAMAccount
    name.

    set-ADAccountControl SAMACCOUNTNAME -PasswordNotRequired $false

    How would I be able to pipe in the CSV file into the command to get all of the users in the CSV? Thank you,

    Justin

  12. anonymouscommenter says:

    Justin, there are lots of places that show how to import and process a CSV file – Import-CSV is the command.

    Assuming your user name file has a header field of "Account", and you imported your CSV into a variable called $users ($users = Import-CSV "c:file.csv"), you’d wrap your Set-ADAccountControl command with a foreach loop:

    foreach ($u in $users) {
    set-ADAccountControl $u.Account -PasswordNotRequired $false
    }

  13. I (and others) have found that the -PasswordExpired parameter of Search-ADAccount does not work. The cmdlet can retrieve the PasswordExpired property, but the parameter returns nothing. This is probably because the parameter is based on the msDS-User-Account-Control-Computed attribute (not userAccountControl), and this attribute is operational. The PowerShell property is based on the same attribute, but retrieving the value apparently forces the domain controller to calculate the value. I am using PowerShell V2. Does this parameter work for anyone?

  14. john b says:

    Good info, thanks JB

Skip to main content