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() 129068064000000000The 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.__ComObjectWhat 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 129068064000000000The 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 AMFinally, 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" 20090101The 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 "(?We can retrieve the specific matches using the $Matches automatic variable.^\d{4})(? \d{2})(? \d{2})" | Out-Null PS > $Matches Name Value ---- ----- Year 2009 Day 01 Month 01 0 20090101
PS > $Matches.Year 2009 PS > $Matches.Day 01 PS > $Matches.Month 01Next 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 PMWe 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 AMNow 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() FalseHere’s what happens if the dates are the same.
PS > $dateOfExpiration = Get-Date 1/1/2010 PS > $dateOfExpiration.ToShortDateString() -eq $currentDateOfExpiration.ToShortDateString() True
[?]


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