This not as easy as one might think. the active Directory is not storing dates as a normal [datetime],it use a special a 64bit interger call an IADsLargeInterger.
This mean that you can’t simply use a $user.accountExpires property to get or set the value, this will return a System.__ComObject
To get the AccountExpires property the easiest way (I think), is to use the DirectorySearcher [ADSISearcher] . This will not return a normal DirectoryEntry but a SearchResult data type. The difference is that the accountExpires property is return as an int64 instead of a IADsLargeInterger (don’t ask me why). An int64 is much easier to handle, here’s how to do it :
$search = [ADSISearcher] "" $search.Filter = "(cn=testUser)" $user = $search.FindOne() [datetime]::fromfiletime($user.properties.accountexpires[0])
Of course you can’t set the AccoutExpires with a SearchResult data type. But you can use a special invokeSet on a DirectoryEntry that seems to convert a [datetime] to the correct format :
$user=[adsi]"LDAP://cn=testUser,dc=mycompany,dc=com" $newAccountExpires=(Get-Date).addMonths(1) $User.InvokeSet("AccountExpirationDate",$newAccountExpires)
You can also try to use an InvokeGet("AccountExpirationDate") method on a DirectoryEntry but it will throw an error if the AccountExpires attribute is not set (E_FAIL).
Update october 28th, 2013
With Powershell 2.0 and greater you can use the ConvertLargeIntegerToInt64 method :
$user=[adsi]"LDAP://cn=testUser,dc=mycompany,dc=com" [datetime]::fromfiletime($user.ConvertLargeIntegerToInt64($user.properties.lastlogon[0]))
6 comments:
Hi there,
I tried to use your Script for setting the AccountExpirationDate, but it doesn't work for me. I got: Exception calling "InvokeSet" with "2" arguments: "Unknown name. (Exception from HRESULT: 0x80020006 (DISP_E_UNKNOWNNAME))"
At C:\Script.ps1:149 char19
+ $User.Invoke( <<<< "AccountExpirationDate",$newAccountExpires)
while trying it. Which requirements do you need for this Script? Do you use any modules? May this work on "Windows Server 2008"?
Are you by any chance running this code in PowerShell 1.0 ?
It runs well with PowerShell 2.0 on my Windows 7 computer. I've tried it on a Windows 2008 with Powershell 1.0 and got the DISP_E_UNKNOWNNAME error.
I'm also getting strange behavior in PowerGUI Script Editor (don't know why yet).
This may be categorized as Epic Fail -.-
You're totally right. I wasn't thinking of this, cause every little XP-SP3 Workstation has Powershell v2 on it. I am a bit shocked. Thank you for your help.
You can use the DirectoryEntry's method ConvertLargeIntegerToInt64 to convert Large integer to Int64
[DateTime]::FromFileTime($user.ConvertLargeIntegerToInt64($user.pwdLastSet.Value))
++
Stef
Thanks Stef, didn't know about this one (ConvertLargeintegertoInt64).
I spent several hours tearing my hair out and this is the simplest solution. Thank you.
Post a Comment