Home > Uncategorized > Part 3: An “introduction” to Powershell: The .NET class strikes back

Part 3: An “introduction” to Powershell: The .NET class strikes back

Make sure you are supplying the ADSI path correctly. I just learned that, oddly, you can not supply the “.” alias for the local host within the ADSI WinNT interfaces. This could be why I was having so much odd trouble previously.

Okay, so my star wars references are a little weak. In fact, I’m not even sure a new hope is “part 2”, and the empire strikes back is “part 3.”

So, we just went through pulling out information from our localhost by utilizing ADSI interfaces. It was tiring to say the least.

Type Accelerators are for the lazy!
While I was researching adding a user, I came across three posts that reminded me of something I saw (and wrote about) last week: Type Accelerators. Jaykul wrote a function to set and get typeaccelerators, but it is also covered in a blog post.

You can see:
[ADSI] = System.DirectoryServices.DirectoryEntry

The following two statements declare objects of the same type:

$lhost_bindta = [ADSI]"WinNT://" + $env:computername + "/.,computer"
$lhost_bind = [System.DirectoryServices.DirectoryEntry]"WinNT://" + $env:computername


Tab expansion:
Knowing this, we can actually have some tab expansion driven methods that are revealed via the .NET classes.

$lhost_bind | gm

   TypeName: System.Management.Automation.PSMemberSet

Name                      MemberType Definition
----                      ---------- ----------
Disposed                  Event      System.EventHandler Disposed(System.Object, System.EventArgs)
Close                     Method     System.Void Close()
CommitChanges             Method     System.Void CommitChanges()
CopyTo                    Method     adsi CopyTo(adsi newParent), adsi CopyTo(adsi newParent, string newName)
CreateObjRef              Method     System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)
DeleteTree                Method     System.Void DeleteTree()
Dispose                   Method     System.Void Dispose()
Equals                    Method     bool Equals(System.Object obj)
GetHashCode               Method     int GetHashCode()
GetLifetimeService        Method     System.Object GetLifetimeService()
GetType                   Method     type GetType()
InitializeLifetimeService Method     System.Object InitializeLifetimeService()
Invoke                    Method     System.Object Invoke(string methodName, Params System.Object[] args)
InvokeGet                 Method     System.Object InvokeGet(string propertyName)
InvokeSet                 Method     System.Void InvokeSet(string propertyName, Params System.Object[] args)
MoveTo                    Method     System.Void MoveTo(adsi newParent), System.Void MoveTo(adsi newParent, string newName)
RefreshCache              Method     System.Void RefreshCache(), System.Void RefreshCache(string[] propertyNames)
Rename                    Method     System.Void Rename(string newName)
ToString                  Method     string ToString()
AuthenticationType        Property   System.DirectoryServices.AuthenticationTypes AuthenticationType {get;set;}
Children                  Property   System.DirectoryServices.DirectoryEntries Children {get;}
Container                 Property   System.ComponentModel.IContainer Container {get;}
Guid                      Property   System.Guid Guid {get;}
Name                      Property   System.String Name {get;}
NativeGuid                Property   System.String NativeGuid {get;}
NativeObject              Property   System.Object NativeObject {get;}
ObjectSecurity            Property   System.DirectoryServices.ActiveDirectorySecurity ObjectSecurity {get;set;}
Options                   Property   System.DirectoryServices.DirectoryEntryConfiguration Options {get;}
Parent                    Property   System.DirectoryServices.DirectoryEntry Parent {get;}
Password                  Property   System.String Password {set;}
Path                      Property   System.String Path {get;set;}
Properties                Property   System.DirectoryServices.PropertyCollection Properties {get;}
SchemaClassName           Property   System.String SchemaClassName {get;}
SchemaEntry               Property   System.DirectoryServices.DirectoryEntry SchemaEntry {get;}
Site                      Property   System.ComponentModel.ISite Site {get;set;}
UsePropertyCache          Property   System.Boolean UsePropertyCache {get;set;}
Username                  Property   System.String Username {get;set;}

Considering ADSI acts as a tree, like LDAP, the parent/child relationship dominants the organization.

[system.directoryservices.DirectoryEntries]$lhost_bindchildren = $lhost_bind.psbase.children
$lhost_bindchildren.psbase | gm

   TypeName: System.Management.Automation.PSMemberSet

Name          MemberType Definition
----          ---------- ----------
Add           Method     adsi Add(string name, string schemaClassName)
Equals        Method     bool Equals(System.Object obj)
Find          Method     adsi Find(string name), adsi Find(string name, string schemaClassName)
GetEnumerator Method     System.Collections.IEnumerator GetEnumerator()
GetHashCode   Method     int GetHashCode()
GetType       Method     type GetType()
Remove        Method     System.Void Remove(adsi entry)
ToString      Method     string ToString()
SchemaFilter  Property   System.DirectoryServices.SchemaNameCollection SchemaFilter {get;}

Very cool! So, now we know which methods we’re looking at!

Let’s try to add a user with the system.directoryservices.DirectoryEntries method Add().


distinguishedName :
Path              : WinNT://DOMAIN/./localuser

Silly Powershell. Get down from there. That’s not the path where I told you to bind!

Hmm… research has lead me to a blog post that is this exact blog post, but by an expert. So, create two objects… okay…

More research lead me to this C# example… which lead me to get this working!

[ADSI]$lhost_bind = ("WinNT://" + $env:computername + ",Computer")
[ADSI]$newuser = $lhost_bind.children.add("localuser","user")
$newuser.psbase.invoke("SetPassword", "Test1234$")

Which leads me back to the fact that you must always user Invoke() to deal with internal ADSI interface methods! :(

  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: