pwd last set; all users

Welcome Forums General PowerShell Q&A pwd last set; all users

This topic contains 8 replies, has 3 voices, and was last updated by

 
Participant
3 months, 2 weeks ago.

  • Author
    Posts
  • #103483

    Participant
    Points: 0
    Rank: Member

    I have this function that can find when a single user last changed their pwd:

    Function get-pwdset{
    Param([parameter(Mandatory=$true)][string]$user)
    $use = get-aduser $user -properties passwordlastset,passwordneverexpires
    If($use.passwordneverexpires -eq $true)
        {
     write-host $user "last set their password on " $use.passwordlastset  "this account has a non-expiring password" -foregroundcolor yellow
            }
    Else
        {
    $til = (([datetime]::FromFileTime((get-aduser $user -properties "msDS-UserPasswordExpiryTimeComputed")."msDS-UserPasswordExpiryTimeComputed"))-(get-date)).days
    if($til -lt "5")
        {
     write-host $user "last set their password on " $use.passwordlastset "it will expire again in " $til " days" -foregroundcolor red
            }
    else
        {
     write-host $user "last set their password on " $use.passwordlastset "it will expire again in " $til " days" -foregroundcolor green
            }
    }}

    ...but wanted to get ALL users last changed PWD so tried this:

    $AllUsers= Get-ADUser -Filter * | select samAccountName

    ..so that after I run the function, I type:

    get-pwdset $AllUsers

    but get the error "get-pwdset : Cannot process argument transformation on parameter 'user'"

    Which I expected but would like to know what adjustments I need to make to get this output (and dumped to a .csv) please.

    Thanks

  • #103484

    Participant
    Points: 28
    PublishedHelping Hand
    Rank: Member

    You need to loop through the user collection, you cannot pass a collection to a cmdlet, or function the way you are doing this.

    Your function is only set to ask for one user at a time.

    So, ForLoop, something this...

    # Collect all AD users then loop and run each user through the function for resultset
    (Get-ADUser -Filter * | select samAccountName) | %{get-pwdset -User $_}
    
    # Or 
    ForEach ($TargetUser in $AllUsers)
    {get-pwdset -User $TargetUser}
    
    • #103487

      Participant
      Points: 0
      Rank: Member

      both solutions more or less error out with:

      @{samAccountName=SomeUser} last set their password on   it will expire again in    days
      get-aduser : Cannot find an object with identity: '@{samAccountName=SomeOtherUser}' un
  • #103493

    Participant
    Points: 0
    Rank: Member

    I've also tried this script which was pretty slick but have a date:time error. It's not converting correctly:

    Get-ADUser -Filter * -SearchBase "dc=,dc=" -ResultPageSize 0 -Prop CN,samaccountname,lastLogonTimestamp | Select CN,samaccountname,@{n="lastLogonDate";e={[datetime]::FromFileTime  
    ($_.lastLogonTimestamp)}} | Export-CSV -NoType \

    ERROR:

    lastLogonDate
    static datetime FromFileTime(long fileTime) 
    static datetime FromFileTime(long fileTime) 
    static datetime FromFileTime(long fileTime) 
    static datetime FromFileTime(long fileTime) 
    static datetime FromFileTime(long fileTime) 
    static datetime FromFileTime(long fileTime) 
    static datetime FromFileTime(long fileTime) 131745103348330831
    static datetime FromFileTime(long fileTime) 
    static datetime FromFileTime(long fileTime) 131745107633992789
    static datetime FromFileTime(long fileTime) 
    static datetime FromFileTime(long fileTime) 
    static datetime FromFileTime(long fileTime) 131744261420866385
    • #103559

      Participant
      Points: 28
      PublishedHelping Hand
      Rank: Member

      This would be a similar thing with proper DateTime format using the LastLogon property, so no convert is needed

      Get-ADUser -Filter {Enabled -eq $true} -Properties CN,samaccountname,LastLogon | 
      Select-Object CN,samaccountname,@{n='LastLogon';e={[DateTime]::FromFileTime($_.LastLogon)}}
      
      # Or just
      Get-ADUser -Filter * -properties * | Select samAccountName,PasswordLastSet
      

      Well, minus the searchbase, and resutlpagesize

      As for the errors. This is odd since it is only asking for the one property value, which is what your function is asking for.

      So, this approach outputs what appears to be the expected results.

      Function get-pwdset
      {
          Param([parameter(Mandatory=$true)][string]$user)
      
          $use = get-aduser $user -properties passwordlastset,passwordneverexpires
      
          If($use.passwordneverexpires -eq $true)
          { write-host $user "last set their password on " $use.passwordlastset  "this account has a non-expiring password" -foregroundcolor yellow }
          Else
          {
              $til = (([datetime]::FromFileTime((get-aduser $user -properties "msDS-UserPasswordExpiryTimeComputed")."msDS-UserPasswordExpiryTimeComputed"))-(get-date)).days
              if($til -lt "5")
          { write-host $user "last set their password on " $use.passwordlastset "it will expire again in " $til " days" -foregroundcolor red }
          else
          { write-host $user "last set their password on " $use.passwordlastset "it will expire again in " $til " days" -foregroundcolor green}
          }
      }
      
      (Get-ADUser -Filter *).samAccountName | %{get-pwdset -user $_}
      
      # Results
      
      Administrator last set their password on  3/31/2017 2:34:34 PM this account has a non-expiring password
      Guest last set their password on   this account has a non-expiring password
      krbtgt last set their password on  3/31/2017 8:05:27 PM it will expire again in  -411  days
      
    • #104071

      Participant
      Points: 0
      Rank: Member

      Thanks postanote, that's very handy. How would I also get the write-host to dump the same info to a .csv?

      I tried:

      (Get-ADUser -Filter *).samAccountName | %{get-pwdset -user $_} | Export-Csv .\PWDLastSet.csv
  • #103499

    Participant
    Points: 5
    Rank: Member

    Whenever you have issues with attributes from AD, check one of the users with issues what the attributes are set to.

    Some attributes are not replicated across DC's, like lastlogontimestamp vs. lastlogondate.
    Some attributes are not set until you actually do X, like reseting the password the first time.
    Some attributes are not seen unless you run the command as administrator.
    Some attributes have a different stored format, like the date time format is in ticks instead of a date.

    • #103532

      Participant
      Points: 0
      Rank: Member

      Some attributes have a different stored format, like the date time format is in ticks instead of a date.

      I hear ya and I'm fairly certain the conversion of those ticks is whats wrong with my last example. I just don't how to fix it although I think it involves an Expression.

    • #103580

      Participant
      Points: 5
      Rank: Member

      Usually you can use Get-Date to convert from the different formats.
      Or the .Net methods if you prefer that.

      Since the numbers above is in FileTime (actually it seems to be in FileTimeUtc).

      $x = 131745103348330831
      
      (Get-date $x).AddYears(1600)
      

      The AddYears addition is because Get-Date use ticks which start counting from 1:st of January year 1.
      FileTime starts at 1:st of January year 1601.

      If there is a lot of iterations it might be worth checking the .Net methods since they are most likely faster than calling Get-Date every time.

The topic ‘pwd last set; all users’ is closed to new replies.