Skip to main content

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.

Comments

Popular posts from this blog

How to list all the AD LDS instances on a server

AD LDS allows you to provide directory services to applications that are free of the confines of Active Directory.  To list all the AD LDS instances on a server, follow this procedure: Log into the server in question Open a command prompt. Type dsdbutil and press Enter Type List Instances and press Enter . You will receive a list of the instance name, both the LDAP and SSL port numbers, the location of the database, and its status.

How to run GPResult on a remote client with PowerShell

In the past, to run the GPResult command, you would need to either physically visit this client, have the user do it, or use and RDP connection.  In all cases, this will disrupt the user.  First, you need PowerShell remoting enabled on the target machine.  You can do this via Group Policy . Open PowerShell and type this command. Invoke-Command –ScriptBlock {GPResult /r} –ComputerName <ComputerName> Replace <ComputerName> with the name of the target.  Remember, the target needs to be online and accessible to you.

Error icon when creating a GPO Preference drive map

You may not have an error at all.  Take a look at the drive mapping below. The red triangle is what threw us off.  It is not an error.  It is simply a color representation of the Replace option of the Action field in the properties of the drive mappings. Create action This give you a green triangle. The Create action creates a new mapped drive for users. Replace Action The Replace action gives you a red triangle.  This action will delete and recreate mapped drives for users. The net result of the Replace action is to overwrite all existing settings associated with the mapped drive. If the drive mapping does not exist, then the Replace action creates a new drive mapping. Update Action The Update action will have a yellow triangle. Update will modify settings of an existing mapped drive for users. This action differs from Replace in that it only updates settings defined within the preference item. All other settings remain as configured on the ma...