JeffHicks

13   8   7

  • TEC 2010 USA Alumni
  • Watchman
  • Debater
  • Fanboy
  • Helper
  • Instigator
  • Participant

Get AD User Password Expiration


LIKED BY
0
PEOPLE

Last week I came across a post on the Microsoft Active Directory team blog about finding when a user password expires. The blog posted a PowerShell script that uses the ActiveDirectory cmdlets. The function takes a user name you pass it, get's password information and lets you know if the password has expired or when it is going to expire. It works and gets the job done. However, I decided to take it a step further.

One of my concerns with the original version is that it can't be used in the pipeline. What if you want to get password information for a group of users, but sort them by the password expiration date or only select those that will expire within a certain number of days? The existing function can't do any of that since all it does is write a string message to the pipeline. There is no object. So I revised the function to write a custom object to the pipeline that shows the user name, distinguishedname, whether the password is expired, when it will expire, if it can expire, the password age and when it was last set.  Yes, I could probably write an expression using Get-ADUser to return the same results, but since the AD post was already written I decided to start with it. I always encourage people to think "object"-ively.  Here's ;my version with a slightly different name.

function Get-ADUserPwdExpiration{
#requires -version 2.0

[cmdletbinding()]

      Param ([Parameter(Mandatory=$true, 
      Position=0, 
      ValueFromPipeline=$true,
      HelpMessage="Identity of the User Account")]
      [Alias("name")]
      [string] $accountIdentity)

         PROCESS {

         Trap {
            Write-warning "An error occured on this account"
            write-warning $accountObj
            #$accountobj | select *
            write-warning $_.exception.Message
            continue
         }

          $accountObj = Get-ADUser $accountIdentity -properties PasswordExpired, PasswordNeverExpires, PasswordLastSet
          #enable the following line for debugging
          #$accountobj | select *
         
          #verify an account was found
         
          if ($accountObj) {         
            #set some default values
           
            $NeverExpires=$False        
            #default value indicates the account has expired      
            [datetime]$ExpiresOn="1/1/0001"
           
            if ($accountObj.PasswordExpired) {
                 $expired=$True
               }
             else {
                $Expired=$False
            }
                      
            #verify there is a PasswordLastSet value
            if ($accountObj.PasswordLastSet) {
                 $pwdLastSet=$accountObj.PasswordLastSet
            }
            else {
                #password has likely never been set
                $pwdLastSet=$False
                [timespan]$passwordAge=0
                #Write-warning "password last set is null"
            }
          
             If ($pwdLastSet) {
               #get password details
              
                #get password age
                [timespan]$passwordAge=(get-date) - $pwdLastSet
               
                 if ($accountObj.PasswordNeverExpires) {                   
                    $NeverExpires=$True
                    [datetime]$ExpiresOn="9/9/9999"
                }
                else {
                 #get dfl
                   $maxPasswordAgeTimeSpan = $null
                   $dfl = (get-addomain).DomainMode

                      if ($dfl -ge 3) {
                            ## Greater than Windows2008 domain functional level

                            $accountFGPP = Get-ADUserResultantPasswordPolicy $accountObj

                            if ($accountFGPP -ne $null) {
                                $maxPasswordAgeTimeSpan = $accountFGPP.MaxPasswordAge

                            }
                            else {
                                $maxPasswordAgeTimeSpan = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge
                             }

                        } #if $dfl -ge 3
                         else {
                            $maxPasswordAgeTimeSpan = (Get-ADDefaultDomainPasswordPolicy).MaxPasswordAge
                        }

                        if ($maxPasswordAgeTimeSpan -eq $null -or $maxPasswordAgeTimeSpan.TotalMilliseconds -eq 0) {
                            write-warning "MaxPasswordAge is not set for the domain or is set to zero!"

                        } else {
                          
                            $pwdLastSet=$accountObj.PasswordLastSet
                            [datetime]$ExpiresOn=$pwdLastSet + $maxPasswordAgeTimeSpan
                        }
                    } #else get dfl
            }
            #Write a custom object to the pipeline
            new-object PSObject -Property @{
                Name=$accountObj.name
                DN=$accountObj.DistinguishedName
                SAM=$accountObj.SAMAccountName
                NeverExpires=$neverExpires
                Expired=$expired
                ExpiresOn=$expiresOn
                PasswordLastSet=$pwdLastSet
                PasswordAge=$passwordAge
                Enabled=$accountobj.Enabled
            }
          } #end If $accountobj
          else {
            write-warning "Failed to find a user account for $accountIdentity"
          }
        } #end Process

    } #end function

My version also includes some error handling so that if you specify a user account that doesn't exist, a warning message is displayed. After you download the script file you can dot source it in your PowerShell session. The script also defines an alias, gupe, for the function which makes it easier to use.

PS S:\> . .\Get-ADUserPwdExpiration.ps1
PS S:\> gupe a.beebe


PasswordLastSet : 3/4/2010 1:26:04 PM
SAM             : A.Beebe
ExpiresOn       : 4/15/2010 1:26:04 PM
Enabled         : True
Name            : Ann Beebe
NeverExpires    : False
DN              : CN=Ann Beebe,OU=HR,OU=Employees,DC=jdhlab,DC=local
Expired         : False
PasswordAge     : 6.01:26:29.9648862

 

I'll be the first to admit it isn't a perfect script or function. But it can be used in the pipeline so you can sort, filter, export, group or do whatever you want with the resulting object. I changed some values to True/False or other values that can be sorted or at least consisten. When I work with PowerShell, this is what I'm after. You'll have to let me know what you think.,

Replies

None, yet.

Post a Reply

Click here for help with the editor.



Load a new image
 

You are posting anonymously.
Please enter the five characters
shown to the left:

Save Your Reply