I am trying to emulate the following PowerShell Concept
Add-Type -AssemblyName System.DirectoryServices.AccountManagement
$ctype = New-Object System.DirectoryServices.AccountManagement.ContextType "Machine"
$context = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext -ArgumentList $ctype, $computer
$user = [System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity($context, $id)
Note if you create the Object [System.DirectoryServices.AccountManagement.UserPrincipal] without using that method, the method does not exist. It can only be called at the moment of creation
ObjectClrOption ("use","System.DirectoryServices.AccountManagement, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
MACHINECONSTANT = 0
NAMEOFSOMECOMPUTER = "zzz.abc.loc"
CType = ObjectClrNew("System.DirectoryServices.AccountManagement.ContextType",MACHINECONSTANT)
Context = ObjectClrNew("System.DirectoryServices.AccountManagement.PrincipalContext",CType,NAMEOFSOMECOMPUTER)
ThisUser = ObjectClrNew("System.DirectoryServices.AccountManagement.UserPrincipal", .............. and this is where i get stuck
Aaron
Sticking to the ADSI extender or regular COM AD objects will save you a bunch of typing but to use CLR hosting you need to pass the context as a parameter to the constructor.
Context = ObjectClrNew("System.DirectoryServices.AccountManagement.PrincipalContext",CType,NAMEOFSOMECOMPUTER)
ThisUser = ObjectClrNew("System.DirectoryServices.AccountManagement.UserPrincipal", Context ) ; <--------- here
Quote from: td on July 13, 2015, 07:43:51 PM
Sticking to the ADSI extender or regular COM AD objects will save you a bunch of typing but to use CLR hosting you need to pass the context as a parameter to the constructor.
Context = ObjectClrNew("System.DirectoryServices.AccountManagement.PrincipalContext",CType,NAMEOFSOMECOMPUTER)
ThisUser = ObjectClrNew("System.DirectoryServices.AccountManagement.UserPrincipal", Context ) ; <--------- here
Hmm doesnt meet the goal.. I NEED to call the Method FindByIdentity the moment I create the Variable ThisUser
you code creates a UserPrincipal Object, but after that object is created you cannot call the method FindByIdentity
again looking at the powerShell:
$user = [System.DirectoryServices.AccountManagement.UserPrincipal]
::FindByIdentity($context, $id)
The Effect of this "style" is to create a UserPrincipal Object that already has the Context of the User I am interested in.
I could then for instance change the user givenname, "save" the change from the cached Object to AD, and done.
Aaron
Hmm maybe i misread your response.. I'll try to execute the method after I close the ClrNew paranthesis and let you know how it goes.
As far as .net versus com versus winbatch adsi extender.
I didn't delve into COM much (i'm more familiar with Winbatch and Powershell, so .NET was more appealing)
At least as far as the extender is concerned it can't keep up with the performance.
My application searches for about 10000 objects a day
it then interrogates about 30 attributes each.
The Extender was just much slower than the .NET objects that both search and return properties in one call (now one call to me, admittedly on the wire it might be several calls)
Also the .NET objects can return the objects presorted based on any Property...
Aaron
Ok I cant figure it out
Here is a workign Powershell
[System.Reflection.Assembly]::LoadWithPartialName("System.DirectoryServices")
[System.Reflection.Assembly]::LoadWithPartialName("System.DirectoryServices.AccountManagement")
#there are easier ways to do this in powershell, however i choose this because it calls constructors just like winbatch would.. 1 is the Constant For ContextType.Domain
$context = New-Object -TypeName System.DirectoryServices.AccountManagement.PrincipalContext(1,"corp.xxxxxxxx.loc")
$thisuser = [System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity($context, "a_valid_samaccountname")
PS C:\Windows\system32> $thisuser
GivenName : -----n
MiddleName :
Surname : ------h
EmailAddress : -------h@b-------.com
VoiceTelephoneNumber : ###-####
EmployeeId : ####
AdvancedSearchFilter : System.DirectoryServices.AccountManagement.AdvancedFilters
Enabled : True
AccountLockoutTime :
LastLogon : 7/8/2015 4:59:26 PM
PermittedWorkstations : {}
PermittedLogonTimes : {255, 255, 255, 255...}
AccountExpirationDate :
SmartcardLogonRequired : False
DelegationPermitted : True
BadLogonCount : 0
HomeDirectory : \\XXXXX\Home\Security\XXXXX
HomeDrive : X:
ScriptPath :
LastPasswordSet : 7/9/2015 6:18:29 PM
LastBadPasswordAttempt : 7/14/2015 5:32:55 PM
PasswordNotRequired : False
PasswordNeverExpires : False
UserCannotChangePassword : False
AllowReversiblePasswordEncryption : False
Certificates : {[Subject]
CN=XXXX XXXXX
[Issuer]
CN=XXXXXXXXXXXXXXXXXXX
[Serial Number]
613CB5130002000073F7
[Not Before]
4/17/2015 3:10:58 PM
[Not After]
4/16/2017 3:10:58 PM
[Thumbprint]
D461734FA0019FBF8AD4C2DEAC939730F6DE8352
}
Context : System.DirectoryServices.AccountManagement.PrincipalContext
ContextType : Domain
Description : XX - XXXXX
DisplayName : AXXXX GXXXX
SamAccountName : gXXXXX
UserPrincipalName : gXXXXXX@XXXXXX.com
Sid : S-1-5-21-2795705288-3334924005-23762XXXXX-1XXXX
Guid : cb96a1cf-d6bb-43ad-XXXX-1693cf439a5a
DistinguishedName : CN=AXXXXXXX,OU=Users,OU=Information Services,OU=Divisions,DC=XXXX,DC=XXXX,DC=XXXXX
StructuralObjectClass : user
What i tried in WinBatch
;ObjectClrOption("version","v4.0.30319")
ObjectClrOption ("use","System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
ObjectClrOption ("use","System.DirectoryServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
ObjectClrOption ("use","System.DirectoryServices.AccountManagement, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
ObjectClrOption ("use","System.Net, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
ObjectClrOption ("use","System.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
ObjectClrOption ("use","System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
ObjectClrOption ("use","System.IO, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
;ObjectClrOption ("use","System.Numerics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
;BigInteger
MACHINECONSTANT = 0
DOMAINCONSTANT = 1
CType = ObjectClrNew("System.DirectoryServices.AccountManagement.ContextType",MACHINECONSTANT) ; i know this works from other code
DType = ObjectClrNew("System.DirectoryServices.AccountManagement.ContextType",DOMAINCONSTANT) ; i know this works from other code
ThisContext = ObjectClrNew("System.DirectoryServices.AccountManagement.PrincipalContext",DType,"corp.xxxxxxx.loc"); i know this works from other code
;ThisUser = ObjectClrNew("System.DirectoryServices.AccountManagement.UserPrincipal",ThisContext)(::FindByIdentity(ThisContext,"a_valid_samaccountname"))
;ThisUser = ObjectClrNew("System.DirectoryServices.AccountManagement.UserPrincipal",ThisContext)::FindByIdentity(ThisContext,"a_valid_samaccountname")
;ThisUser = ObjectClrNew("System.DirectoryServices.AccountManagement.UserPrincipal",ThisContext)(FindByIdentity(ThisContext,"a_valid_samaccountname"))
;ThisUser = ObjectClrNew("System.DirectoryServices.AccountManagement.UserPrincipal",ThisContext)FindByIdentity(ThisContext,"a_valid_samaccountname")
;ThisUser = ObjectClrNew("System.DirectoryServices.AccountManagement.UserPrincipal",ThisContext).FindByIdentity(ThisContext,"a_valid_samaccountname")
;ThisUser = ObjectClrNew("System.DirectoryServices.AccountManagement.UserPrincipal",ThisContext),FindByIdentity(ThisContext,"a_valid_samaccountname")
;ThisUser = ObjectClrNew("System.DirectoryServices.AccountManagement.UserPrincipal")(::FindByIdentity(ThisContext,"a_valid_samaccountname"))
;ThisUser = ObjectClrNew("System.DirectoryServices.AccountManagement.UserPrincipal")::FindByIdentity(ThisContext,"a_valid_samaccountname")
;ThisUser = ObjectClrNew("System.DirectoryServices.AccountManagement.UserPrincipal")(FindByIdentity(ThisContext,"a_valid_samaccountname"))
;ThisUser = ObjectClrNew("System.DirectoryServices.AccountManagement.UserPrincipal",ThisContext)FindByIdentity(ThisContext,"a_valid_samaccountname")
;ThisUser = ObjectClrNew("System.DirectoryServices.AccountManagement.UserPrincipal").FindByIdentity(ThisContext,"a_valid_samaccountname")
;ThisUser = ObjectClrNew("System.DirectoryServices.AccountManagement.UserPrincipal"),FindByIdentity(ThisContext,"a_valid_samaccountname")
;ThisUser = ObjectClrNew("System.DirectoryServices.AccountManagement.UserPrincipal",'FindByIdentity(ThisContext,"a_valid_samaccountname")')
;ThisUser = ObjectClrNew("System.DirectoryServices.AccountManagement.UserPrincipal",'FindByIdentity',ThisContext,"a_valid_samaccountname")
ThisUser = ObjectClrNew("System.DirectoryServices.AccountManagement.UserPrincipal",'FindByIdentity(' : ThisContext : ',"a_valid_samaccountname")')
Could not get it to work
FindByIdentity is a static method but you still have to have an object to call it in WinBatch CLR hosting. This work just fine on our test server:
enuDsContex = ObjectClrNew("System.DirectoryServices.AccountManagement.ContextType")
dsDomain = ObjectClrType("System.DirectoryServices.AccountManagement.ContextType", enuDsContex.Domain)
objPrContext = ObjectClrNew("System.DirectoryServices.AccountManagement.PrincipalContext",dsDomain,"testingserver","me","*topsecret*")
objUser = ObjectClrNew("System.DirectoryServices.AccountManagement.UserPrincipal", objPrContext)
objUser2 = objUser.FindByIdentity(objPrContex, 'rrabbit') ; Roger Rabbit user...
Message("User Name", objUser2.DistinguishedName)
And this will work depending on server directory security setting and the relationship between the client and server.
enuDsContex = ObjectClrNew("System.DirectoryServices.AccountManagement.ContextType")
dsDomain = ObjectClrType("System.DirectoryServices.AccountManagement.ContextType", enuDsContex.Domain)
objPrContex = ObjectClrNew("System.DirectoryServices.AccountManagement.PrincipalContext",dsDomain,"TestServer")
objUser = ObjectClrNew("System.DirectoryServices.AccountManagement.UserPrincipal", objPrContex)
objUser2 = objUser.FindByIdentity(objPrContex, 'rrabbit') ; Yes we have a test user named Roger Rabbit.
Message("User Name", objUser2.DistinguishedName)
Thank you..
I have a program written in-house that helps me navigate .NET objects, i guess i believed it too much when it told me that method was not exposed after the object was created, and didnt try.
Quote from: galaara98 on July 15, 2015, 08:28:43 AM
I have a program written in-house that helps me navigate .NET objects, i guess i believed it too much when it told me that method was not exposed after the object was created, and didnt try.
If your internal program is dependent upon instantiating an object, I suspect that it will miss static methods, because they belong not to an object, but to the class of which it is an instance. For example, there is no
Console object as such; hence,
Console.WriteLine is a static method, because you don't (can't, really), instantiate a
Console object. Likewise,
string.IsNullOrEmpty is a static method on the
System.string class, whereas
strMyStrng.Split is an instance method of
strMyStrng, which is an instance of
System.string.
Quote from: DAG_P6 on July 15, 2015, 03:55:21 PM
Quote from: galaara98 on July 15, 2015, 08:28:43 AM
I have a program written in-house that helps me navigate .NET objects, i guess i believed it too much when it told me that method was not exposed after the object was created, and didnt try.
If your internal program is dependent upon instantiating an object, I suspect that it will miss static methods, because they belong not to an object, but to the class of which it is an instance. For example, there is no Console object as such; hence, Console.WriteLine is a static method, because you don't (can't, really), instantiate a Console object. Likewise, string.IsNullOrEmpty is a static method on the System.string class, whereas strMyStrng.Split is an instance method of strMyStrng, which is an instance of System.string.
Again, this is not correct for WinBatch CLR hosted objects. You will
not 'miss static methods' just because you attempt to call a static method using the dotted instantiated object syntax on an actual instantiated object.
Be interesting to see the effects of just calling the PS directly from WB. Return value could be passed to clipboard then return control of script to WB. But then if the intent is to change the value or make other AD changes then Tony's original suggestion to stay with ADSI Extender and COM makes more sense.