Advanced Windows PowerShell Scripting Video Training

Advanced Windows PowerShell Scripting Video Training
Advanced Windows PowerShell Scripting Video Training

Monday, August 5, 2013

Changing the Account Expiration Date on all Users with PowerShell

This is a question that I took from PowerShell.com and presented to my PowerShell class.  My intent was to demonstration some research methods using MSDN.  In truth, I had no idea how complicated that this could be.

The user needed to advance all user account expiration dates by 90 days from the current date. 

image

Take a look at the AccountExpires property.  I did a little internet research on the properties of an Active Directory User Object. Here is what I found out about the AccountExpires attribute.  It is the number of 100-nanosecond intervals from January 1, 1601.  OK, who thinks of this stuff?  I was hoping this would be a System.DateTime object, but we are not so lucky.  So, I set off to make it one.

Another issue is once I have it in a DateTime object, how do I change it back into this 100-nanosecond format? Doing a little research of the DateTime object on MSDN gave me the class information for this object.   Clicking on the Ticks property gave me the answer that I was hoping for.

The value of this property represents the number of 100-nanosecond intervals that have elapsed since 12:00:00 midnight, January 1, 0001, which represents DateTime.MinValue. It does not include the number of ticks that are attributable to leap seconds.

I’m assuming that the year 0001 is a typo or the 1601 from the other documentation is a typo.  With this information in hand, off to coding I go.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

ForEach ($User in (Get-ADUser -filter * -Properties AccountExpires))

{

    # Retrive the date that a user account will Expire as a DateTime object.

    $User |

    Select-Object -ExpandProperty AccountExpires |

    ForEach-Object {

 

        # If the account is set to never expire, then do not change the date.

        If (([double]$User.AccountExpires -ne 9223372036854775807) –and

            ($User.AccountExpires -gt 0))

            {

                $Date = [DateTime]$_

                Write-output $Date.AddYears(1600).ToLocalTime()

               

                # Set the expiration date for 90 days into the future

                $User |

                Set-ADUser -AccountExpirationDate ((Get-Date).AddDays(90)).Ticks   

            }

        }  # End ForEachObject Loop

} # End ForEach ($User in (Get-ADUser -filter * -Properties AccountExpires))

Lines 1 – 20 contain a ForEach loop that pulls one user object at a time and stores the object in the variable $User.

Line 4 starts a PowerShell pipeline that runs all the way to line 19.  Line 4 Pass the $User object into the pipeline.

Line 5 Extracts out the AccountExpires property value.

Line 6 starts a ForEach loop that runs until line 19.

Lines 9 and 10 makes sure that we do not touch any user object that is either the built in administrator or has an account that is set to never expire.  The value 9223372036854775807 is the content for “Account Never Expires”. Current Windows 8 clients have a maximum date of of 3155378975999999999, or December 31, 9999 12:00:00 AM.  I guess this will be the new Mayan end of the world date for a future generation.

Line 12 utilizes the .NET class [DateTime] to great a DateTime object out of the AccountExpires information.  Fortunately, it accepts the 100-nanosecond format.

Line 13 can be removed.  It will display what the accounts are being set to in case you are interested.

Line 16 pipes the current user object to the pipeline and sends it to Set-ADUser.

Line 17 sets the AccountExpires property to 90 days in the future using the DateTime objects AddDays() method and then extracting the number of Ticks this new date represents.

No comments: