setting accountExpires using PowerShell

Let’s take a look at how to set the accountExpires property on a user in Active-Directory. First bind to a user using [adsi] (You can use the Quest AD cmdlets or the AD cmdlets available in Server2008 R2, but in this post we’ll stick to [adsi])


PS > $user = [adsi]"LDAP://CN=Niklas Goude,CN=Users,DC=POWERSHELL,DC=NU"

Setting the account to never expire is easy, simply set the value to 0 as shown below.


PS > $user.accountExpires = 0
PS > $user.setInfo()

Setting account expires to a specific date is a little trickier, if we try to type a date (1/1/2010) an error occurs.


PS > $user.accountExpires = "1/1/2010"
PS > $user.setInfo()

Exception calling "setInfo" with "0" argument(s): "The attribute syntax specified to the directory service is invalid.
"
At line:1 char:14
+ $user.setInfo <<<< ()
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : CatchFromBaseAdapterMethodInvokeTI

Instead, we have to convert the date to a Windows File Time using the ToFileTime() method supported by DateTime.


PS > (Get-Date 1/1/2010).ToFileTime()
129068064000000000

The method returns a 64-bit integer which we use when setting a specific date as demonstrated below.


PS > $user.accountExpires = [string](Get-Date 1/1/2010).ToFileTime()
PS > $user.setInfo()

What about finding out which date an account expires? if we try to retrieve the value of the accountExpires property
from an object of the type DirectoryEntry “System.__ComObject” is returned


PS > $user = [adsi]"LDAP://CN=Niklas Goude,CN=Users,DC=POWERSHELL,DC=NU"
PS > $user.accountExpires
System.__ComObject

What we want to do is to use the DirectorySearcher class to retrieve a specific user.


$SearchRoot = [adsi]"LDAP://DC=POWERSHELL,DC=NU"
$searcher = New-Object System.DirectoryServices.DirectorySearcher($searchRoot)
$searcher.Filter = "(&(objectClass=user)(sAMAccountName=nigo))"
$user = $searcher.FindOne()

The SearchResult object returned displays the value of the accountexpires property.


PS > $user.Properties.accountexpires
129068064000000000

The numeric values returned from the accountexpires property is a little hard to read so let’s convert it to an object of the type System.DateTime.


PS > [dateTime]::FromFileTime($($user.Properties.accountexpires))

Friday, January 01, 2010 12:00:00 AM

Finally, let’s take a look at comparing dates. Just to make it a little more fun lets say that the input string contains numeric values in the following form: YYYYMMDD.


PS > "20090101"
20090101

The string above represents January 01, 2009. A fun (and cool) way of working with strings is by using the -match operator. The –match and –notmatch operators try to match one or more of the set of string values on the left side of the operation using regular expressions. In the example below we match the first 4 numeric values and assign them to a property named Year, the following two digits are assigned to Month and the last two are assigned to Day.


PS > "20090101" -match "(?^\d{4})(?\d{2})(?\d{2})" | Out-Null
PS > $Matches

Name                           Value
----                           -----
Year                           2009
Day                            01
Month                          01
0                              20090101

We can retrieve the specific matches using the $Matches automatic variable.


PS > $Matches.Year
2009
PS > $Matches.Day
01
PS > $Matches.Month
01

Next we use the Get-Date cmdlet to retrieve an object of the type DateTime.


PS > $dateOfExpiration = (Get-Date -year $matches.Year -month $matches.Month -day $matches.Day)
PS > $dateOfExpiration

Thursday, January 01, 2009 5:43:03 PM

We also store the users account expire date in a variable


PS > $currentDateOfExpiration = [dateTime]::FromFileTime($($user.Properties.accountexpires))
PS > $currentDateOfExpiration

Friday, January 01, 2010 12:00:00 AM

Now we can compare the dates. Since we don’t know the exact time we use the ToShortDateString() method.
The example below returns.


PS > $dateOfExpiration.ToShortDateString() -eq $currentDateOfExpiration.ToShortDateString()
False

Here’s what happens if the dates are the same.


PS > $dateOfExpiration = Get-Date 1/1/2010
PS > $dateOfExpiration.ToShortDateString() -eq $currentDateOfExpiration.ToShortDateString()
True

Rating 4.33 out of 5
[?]
  1. Stef
    November 28th, 2011 at 15:47 | #1

    PS > $user = [adsi]“LDAP://CN=Niklas Goude,CN=Users,DC=POWERSHELL,DC=NU”
    PS > $user.accountExpires
    System.__ComObject

    You can use the ConvertLargeIntegerToInt64 method of DirectoryEntry object to convert Large Integer to Int64

    [DateTime]::FromFileTime($user.ConvertLargeIntegerToInt64($user.accountExpires.Value))

    [DateTime]::FromFileTime method returns the following error when no expire date is defined (value = 9223372036854775807)
    Exception calling “FromFileTime” with “1″ argument(s): “Not a valid Win32 FileTime.
    Parameter name: fileTime”
    At line:1 char:25
    + [DateTime]::FromFileTime <<<< ($user.Properties.accountexpires.Item(0))
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

  1. No trackbacks yet.

Comment Spam Protection by WP-SpamFree