Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

System.DirectoryServices.DirectoryEntry & the accountExpires property

1,361 views
Skip to first unread message

Clint Bergman

unread,
Apr 25, 2007, 6:14:28 PM4/25/07
to
I'm trying to set an account expiration date for an AD user and cannot deduce how to get at the accountexpires property to set it.

The property can be retrieved like so (thank you everyone who has tackled getting at this info):

PS H:\ # $searcher = New-Object DirectoryServices.DirectorySearcher
PS H:\ # $searcher.filter = "(&(samaccountname=testuser))"
PS H:\ # $results = $searcher.findone()
PS H:\ # $results.properties.accountexpires
128246364000000000
PS H:\ # [datetime]::fromfiletime($results.properties.accountexpires[0])

Saturday, May 26, 2007 12:00:00 AM

However, as $results is of type System.DirectoryServices.SearchResult the property cannot be set using this object (At least I don't think it can...)

So then:
PS H:\ # $user = $results.getdirectoryentry()
PS H:\ # $user | gm


   TypeName: System.DirectoryServices.DirectoryEntry

Name                  MemberType Definition
----                  ---------- ----------
accountExpires        Property   System.DirectoryServices.PropertyValueCollection accountExpires {get;set;}
cn                    Property   System.DirectoryServices.PropertyValueCollection cn {get;set;}
codePage              Property   System.DirectoryServices.PropertyValueCollection codePage {get;set;}
...


Oh good!  AccountExpires!  but...

PS H:\ # $user.accountexpires | gm

   TypeName: System.__ComObject

Name                      MemberType Definition
----                      ---------- ----------
CreateObjRef              Method     System.Runtime.Remoting.ObjRef CreateObjRef(Type requestedType)
Equals                    Method     System.Boolean Equals(Object obj)
GetHashCode               Method     System.Int32 GetHashCode()
GetLifetimeService        Method     System.Object GetLifetimeService()
GetType                   Method     System.Type GetType()
InitializeLifetimeService Method     System.Object InitializeLifetimeService()
ToString                  Method     System.String ToString()

and...

PS H:\ # [datetime]::fromfiletime($user.accountexpires[0])
Cannot convert argument "0", with value: "System.__ComObject",
for "FromFileTime" to type "System.Int64": "Cannot convert "System.__ComObject" to "System.Int64"."
At line:1 char:25
+ [datetime]::fromfiletime( <<<< $user.accountexpires[0])

PS H:\ # [datetime]::fromfiletime($user.accountexpires)
Cannot convert argument "0", with value: "System.DirectoryServices.PropertyValueCollection", for "FromFileTime" to type
 "System.Int64": "Cannot convert "System.DirectoryServices.PropertyValueCollection" to "System.Int64"."
At line:1 char:25
+ [datetime]::fromfiletime( <<<< $user.accountexpires)

The answer may be here:
http://mow001.blogspot.com/2006/01/msh-snap-in-to-translate.html

but I'm no programmer, & can't find any Interop anything in a new VS C# 2005 project & just get lost.  Hopefully I'm just making this way too complicated & there's something simple.  Thanks for any help and time you can afford!

~Clint

Brandon Shell

unread,
Apr 25, 2007, 7:03:13 PM4/25/07
to
I dont see why you cant set the property... DirectorySearcher erturns DirectoryEntry.
 
That aside... I am on a bus atm so I can't test this, but I remember having to do something like
$user.properties.accountexpires[0]
or
$user.properties['accountexpires'].value
I'm trying to set an account expiration date for an AD user and cannot deduc$usere how to get at the accountexpires property to set it.
for "FromFileTime" to type "System.Int64": "Cannot convert "System.__ComObject" to "System.Int64"."

Brandon Shell

unread,
Apr 25, 2007, 7:11:41 PM4/25/07
to
oh... btw I also recall having to use psbase to set it.
 
i.e. $user.psbase.accountexpires = $dateUTC
or
     $user.psbase.invoke("put","accountexpires",$date)

Clint Bergman

unread,
Apr 26, 2007, 11:46:28 AM4/26/07
to
Thanks Brandon, but I must be missing something still...
 
Using just those methods works great for properties that are of a type Powershell or .NET can understand/convert, but the accountexpires (along with lastlogon,pwdlastset,uSNCreated...) property shows as type System.__ComObject & I don't know how to interact with it.  How did you get it to work?

Brandon Shell

unread,
Apr 26, 2007, 3:02:04 PM4/26/07
to
Well.. bad news... I remembered.. I used VBScript (its like three lines.)
 
If someone else can show me a simple way to do this in powershell it would be great, but the problem is that DirectoryEntry object has a known qwerk on properties with int64 values that require you use IADsLargeInteger which is a big pain to try to use.
 
vbscript code

Set objUser = GetObject("LDAP://cn=Jim Smith,ou=Sales,dc=MyDomain,dc=com")

objUser.AccountExpirationDate = #04/22/2007 15:30#

objUser.SetInfo

 

Clint Bergman

unread,
Apr 26, 2007, 7:18:21 PM4/26/07
to
Bummer.  Oh Well, thanks for the vbScript solution!
 
^_^ ~Clint
"Brandon Shell" <tshel...@gmail.com> wrote in message news:eGjUmWDi...@TK2MSFTNGP03.phx.gbl...

Marcel J. Ortiz [MSFT]

unread,
Apr 27, 2007, 1:39:44 PM4/27/07
to
Hmm... I did something similar not long ago for setting the expiration date on a local user.  Here is the PowerShell script:
 
$user = [adsi] "WinNT://${env:computername}/TestUser"
$expirationDate = [datetime] "5/5/2008"
$user.psbase.InvokeSet('AccountExpirationDate', $expirationDate)
$user.psbase.CommitChanges()
And now to check that it worked:
 
PS C:\tools> $user.psbase.properties['AccountExpirationDate']
 
Monday, May 05, 2008 12:00:00 AM
 

PS C:\tools>
 
I can't try it here but I'm sure you can do something similar for LDAP.
 
--
Marcel Ortiz [MSFT]
Windows PowerShell
Microsoft Corporation
This posting is provided "AS IS" with no warranties, no confers rights.
 
"Brandon Shell" <tshel...@gmail.com> wrote in message news:eGjUmWDi...@TK2MSFTNGP03.phx.gbl...

Clint Bergman

unread,
Apr 27, 2007, 6:37:40 PM4/27/07
to
So using some vbscript embedding it is possible to get the job done in powershell.  The names are ridiculously long but anyway:
 
function Get-VBFunctionsForADUsers {
 $sc = New-Object -ComObject ScriptControl
 $sc.Language = 'VBScript'
 $sc.AddCode('
  Function get_AccountExpires(ByRef objUser)
  End Function
  Function set_AccountExpires(ByVal strUser,ByVal strDate)
   expDate = DateValue(strDate)
 
   Set objUser = GetObject(strUser)
   objUser.AccountExpirationDate = expDate
   objUser.SetInfo
  End Function
 ')
 $sc.CodeObject
}
 
PS C:\data\Temp # $vb = Get-vbFunctionsForADUsers
PS C:\data\Temp # $vb | gm
 

   TypeName: System.__ComObject#{c59c6b12-f6c1-11cf-8835-00a0c911e8b2}
 
Name               MemberType Definition
----               ---------- ----------
get_AccountExpires Method     Variant get_AccountExpires (Variant)
set_AccountExpires Method     Variant set_AccountExpires (Variant, Variant)
 
and assuming that $user is a DirectoryEntry object:
 
PS C:\data\Temp # $vb.set_AccountExpires("LDAP://$($user.distinguishedname)", "09/01/2007")
 
Or for some pipeline action:

PS C:\data\Temp # $user | % { $vb.set_AccountExpires("LDAP://$($_.distinguishedname)", "09/15/2007") }
 
I'm certain that foreach loops would work just as well.  Good enough!
Happy Friday!
(^_^)~Clint
"Brandon Shell" <tshel...@gmail.com> wrote in message news:eGjUmWDi...@TK2MSFTNGP03.phx.gbl...

Brandon Shell

unread,
Apr 30, 2007, 10:29:33 AM4/30/07
to
Marcel, I believe the problem is that ADSI wrapper is the problem. It doesnt seem to work against  LDAP.
 
"Marcel J. Ortiz [MSFT]" <mos...@online.microsoft.com> wrote in message news:4CFAB471-F34A-46E5...@microsoft.com...
0 new messages