![](http://1.bp.blogspot.com/-knEi8prymAc/WABgsqi4DoI/AAAAAAAAKeM/SbY-jVvmiaQ5n4ZQPnEIFoFaLRypZQ_dgCLcB/s1600/Find-AD-Users-With-Empty-Password-Using-PowerShell-2.png)
If the PASSWD_NOTREQD flag is set in the userAccountControl attribute, the corresponding user account can have an empty password, even if the domain password policy disallows empty passwords. This presents a security risk. The PowerShell script that i will create can find users accounts in your Active Directory domain where the PASSWD_NOTREQD flag is set.
Viewing the PASSWD_NOTREQD flag in ADUC
You can view the userAccountControl attribute in Active Directory and Users (ADUC). Make sure you that you have enabled Advanced Features in ADUC in the View menu.![](http://4.bp.blogspot.com/-Fsyw1lwogOs/WABgryR4ymI/AAAAAAAAKeA/Z70ZQoBgkm4zasaPHlDuO8uAzoCo1bEEgCLcB/s1600/Find-AD-Users-With-Empty-Password-Using-PowerShell-1.png)
Enabling Advanced Features in ADUC
You can then view the value of the userAccountControl attribute in the Attribute Editor tab of the of the user account’s properties.
![](http://2.bp.blogspot.com/-knEi8prymAc/WABgsqi4DoI/AAAAAAAAKeM/SbY-jVvmiaQ5n4ZQPnEIFoFaLRypZQ_dgCLcB/s1600/Find-AD-Users-With-Empty-Password-Using-PowerShell-2.png)
userAccountAttribute in ADUC
The userAccountControl values for user account with expiring passwords is 0x200 (512 decimal).
![](http://2.bp.blogspot.com/-tYz407zE3vY/WABgslf93fI/AAAAAAAAKeQ/cnTxgslx-WwRUdkrtQWzNPbuGklV2VqawCLcB/s640/Find-AD-Users-With-Empty-Password-Using-PowerShell-3.png)
userAccountControl with NORMAL_ACCOUNT flag and expiring password
Accounts with non-expiring passwords have the value 0x10200 (66048 decimal).
![](http://4.bp.blogspot.com/-I5c2YDw_is8/WABgs6QdXOI/AAAAAAAAKeU/Ltmimw6U4YMhVBv0DQWpWnPGLAvorWJcgCLcB/s640/Find-AD-Users-With-Empty-Password-Using-PowerShell-4.png)
userAccountControl with NORMAL_ACCOUNT flag and non-expiring password
User accounts with the PASSWD_NOTREQD flag have the extra bitmask of 0x20 set and are showing as 0x220 (544 decimal) for accounts with expiring passwords.
![](http://2.bp.blogspot.com/-YdPK4L5bsy4/WABgtHBcX0I/AAAAAAAAKeY/om_LfRe1d4sjkIxQzA7L8kthxk0Hc2lwACLcB/s640/Find-AD-Users-With-Empty-Password-Using-PowerShell-5.png)
userAccountControl attribute with PASSWD_NOTREQD flag and expiring password
User accounts with non-expiring passwords have the value 0x10220 (66080 decimal).
![](http://1.bp.blogspot.com/-oHYFkO0a_Tc/WABgtLay8dI/AAAAAAAAKec/YuVUH7QoMMcALg_xwZIypP4Lk4-D97ZSACLcB/s640/Find-AD-Users-With-Empty-Password-Using-PowerShell-6.png)
userAccountControl attribute with PASSWD_NOTREQD flag and non-expiring password
As you can see in the above screenshots, the last two values correspond to the PASSWD_NOTREQD flag. The flag could have been set by manipulating the userAccountControl attribute through Attribute Editor or programmatically, for instance via PowerShell.
If the user accounts are disabled with a non-expiring password, the userAccountControl attribute is set to 0x10222 (66082 decimal).
![](http://2.bp.blogspot.com/-VXM_2akD3RE/WABgtauX5kI/AAAAAAAAKeg/HUr38hKXLJ8pAYUsRzh32NSy6oe4rnX1wCLcB/s640/Find-AD-Users-With-Empty-Password-Using-PowerShell-7.png)
userAccountControl attribute with ACCOUNTDISABLE and PASSWD_NOTREQD flags, expiring password
![](http://4.bp.blogspot.com/-NkWXsTOv8d4/WABgt69lisI/AAAAAAAAKek/Ju6Z1xfS0LkeMm_lbCK_J7d-jExjXooFgCLcB/s640/Find-AD-Users-With-Empty-Password-Using-PowerShell-8.png)
userAccountControl attribute with ACCOUNTDISABLE and PASSWD_NOTREQD flags, non-expiring password
Using PowerShell to find users with PASSWD_NOTREQD flag
First, we create a report folder named c:\admin.New-Item -Path c:\admin -ItemType directory -force
After that, we get the distinguished name of the domain and save it in the variable called $domainDN.
$domainDN = get-addomain | select -ExpandProperty DistinguishedName
Now we can use Get-ADUser with an LDAP filter to search for the affected user accounts. We use the domain DN as SearchBase and save it to a text file.
Get-ADUser -Properties Name,distinguishedname,useraccountcontrol,objectClass -LDAPFilter "(&(userAccountControl:1.2.840.113556.1.4.803:=32)(!(IsCriticalSystemObject=TRUE)))" -SearchBase "$domainDN" | select SamAccountName,Name,useraccountcontrol,distinguishedname >C:\admin\PwNotReq.txt
Get-ADUser -Properties Name,distinguishedname,useraccountcontrol,objectClass -LDAPFilter "(&(userAccountControl:1.2.840.113556.1.4.803:=32)(!(IsCriticalSystemObject=TRUE)))" -SearchBase "$domainDN" | select SamAccountName,Name,useraccountcontrol,distinguishedname | Out-GridView
This is the complete PowerShell script:
# Create admin folder
New-Item -Path c:\admin -ItemType directory -force
# Get domain dn
$domainDN = get-addomain | select -ExpandProperty DistinguishedName
# Save pwnotreq users to txt
Get-ADUser -Properties Name,distinguishedname,useraccountcontrol,objectClass -LDAPFilter "(&(userAccountControl:1.2.840.113556.1.4.803:=32)(!(IsCriticalSystemObject=TRUE)))" -SearchBase "$domainDN" | select SamAccountName,Name,useraccountcontrol,distinguishedname >C:\admin\PwNotReq.txt
# Output pwnotreq users in grid view
Get-ADUser -Properties Name,distinguishedname,useraccountcontrol,objectClass -LDAPFilter "(&(userAccountControl:1.2.840.113556.1.4.803:=32)(!(IsCriticalSystemObject=TRUE)))" -SearchBase "$domainDN" | select SamAccountName,Name,useraccountcontrol,distinguishedname | Out-GridView
New-Item -Path c:\admin -ItemType directory -force
# Get domain dn
$domainDN = get-addomain | select -ExpandProperty DistinguishedName
# Save pwnotreq users to txt
Get-ADUser -Properties Name,distinguishedname,useraccountcontrol,objectClass -LDAPFilter "(&(userAccountControl:1.2.840.113556.1.4.803:=32)(!(IsCriticalSystemObject=TRUE)))" -SearchBase "$domainDN" | select SamAccountName,Name,useraccountcontrol,distinguishedname >C:\admin\PwNotReq.txt
# Output pwnotreq users in grid view
Get-ADUser -Properties Name,distinguishedname,useraccountcontrol,objectClass -LDAPFilter "(&(userAccountControl:1.2.840.113556.1.4.803:=32)(!(IsCriticalSystemObject=TRUE)))" -SearchBase "$domainDN" | select SamAccountName,Name,useraccountcontrol,distinguishedname | Out-GridView
In this post, I only covered accounts that are not using smartcards. The table below gives an overview of the possible userAccounControl values of user accounts that use smartcards.
512 Enabled account
514 Disabled account
544 Enabled, Password Not Required
546 Disabled, Password Not Required
66048 Enabled, Password Doesn't Expire
66050 Disabled, Password Doesn't Expire
66080 Enabled, Password Doesn't Expire & Not Required
66082 Disabled, Password Doesn't Expire & Not Required
262656 Enabled, Smartcard Required
262658 Disabled, Smartcard Required
262688 Enabled, Smartcard Required, Password Not Required
262690 Disabled, Smartcard Required, Password Not Required
328192 Enabled, Smartcard Required, Password Doesn't Expire
328194 Disabled, Smartcard Required, Password Doesn't Expire
328224 Enabled, Smartcard Required, Password Doesn't Expire & Not Required
328226 Disabled, Smartcard Required, Password Doesn't Expire & Not Required
514 Disabled account
544 Enabled, Password Not Required
546 Disabled, Password Not Required
66048 Enabled, Password Doesn't Expire
66050 Disabled, Password Doesn't Expire
66080 Enabled, Password Doesn't Expire & Not Required
66082 Disabled, Password Doesn't Expire & Not Required
262656 Enabled, Smartcard Required
262658 Disabled, Smartcard Required
262688 Enabled, Smartcard Required, Password Not Required
262690 Disabled, Smartcard Required, Password Not Required
328192 Enabled, Smartcard Required, Password Doesn't Expire
328194 Disabled, Smartcard Required, Password Doesn't Expire
328224 Enabled, Smartcard Required, Password Doesn't Expire & Not Required
328226 Disabled, Smartcard Required, Password Doesn't Expire & Not Required
If the script found a user account where the PASSWD_NOTREQD flag is set, you can edit the user object in ADUC. For instance, you can change the userAccountControl attribute value from 544 to 512 (NORMAL_ACCOUNT with expiring password).
![](http://2.bp.blogspot.com/-fDS-SE4pfFQ/WABgt4wiGDI/AAAAAAAAKeo/z4BOljsF8HoQSXmiseWOaauQ8xK-ZWclACLcB/s1600/Find-AD-Users-With-Empty-Password-Using-PowerShell-9.png)
userAccountControl attribute before the change
![](http://4.bp.blogspot.com/-JD4WV9UI1Hk/WABgsHleo2I/AAAAAAAAKeI/zRyepxbkJ9EFhRe_f8b7JymZDmgiGZH0wCLcB/s1600/Find-AD-Users-With-Empty-Password-Using-PowerShell-10.png)
userAccountControl attribute after the change
$UsersNoPwdRequired = Get-ADUser -LDAPFilter "(&(userAccountControl:1.2.840.113556.1.4.803:=32)(!(IsCriticalSystemObject=TRUE)))"
foreach($user in $UsersNoPwdRequired )
{
Set-ADAccountControl $user -PasswordNotRequired $false
}
foreach($user in $UsersNoPwdRequired )
{
Set-ADAccountControl $user -PasswordNotRequired $false
}
If you want to log the corresponding user names, you can save them to a text file.
# log file
if ($logfile -eq $null)
{
$logfile = "C:\admin\ADUsersChangedPWNOTREQD.txt"
New-Item $logfile -ItemType File
}
# set flag PasswordNotRequired to false
$UsersNoPwdRequired = Get-ADUser -LDAPFilter "(&(userAccountControl:1.2.840.113556.1.4.803:=32)(!(IsCriticalSystemObject=TRUE)))"
foreach($user in $UsersNoPwdRequired )
{
Set-ADAccountControl $user -PasswordNotRequired $false
Add-Content $logfile "$User"
}
if ($logfile -eq $null)
{
$logfile = "C:\admin\ADUsersChangedPWNOTREQD.txt"
New-Item $logfile -ItemType File
}
# set flag PasswordNotRequired to false
$UsersNoPwdRequired = Get-ADUser -LDAPFilter "(&(userAccountControl:1.2.840.113556.1.4.803:=32)(!(IsCriticalSystemObject=TRUE)))"
foreach($user in $UsersNoPwdRequired )
{
Set-ADAccountControl $user -PasswordNotRequired $false
Add-Content $logfile "$User"
}
![](http://2.bp.blogspot.com/-DV51Ask1H5E/WABgsOjYjiI/AAAAAAAAKeE/TYEmIFtdgAYyvs3YWh0U2s1dOjwR6lnggCLcB/s1600/Find-AD-Users-With-Empty-Password-Using-PowerShell-11.png)
Log file with user accounts