Home > Uncategorized > Part 2: An “introduction” to Powershell: A New Hope

Part 2: An “introduction” to Powershell: A New Hope

Last we left our intrepid explorer I was empty handed, not able to enumerate anything. I did, in fact, find out that, let’s say, ADSI Interfaces do not support enumeration of contained properties and methods.

You can still, of course, refer to documentation and painfully sift until you get what you need.

What’s that you say? Use a pre-written module? How do you ever expect to learn?

Let’s figure something out:

Thanks to Shay Levy’s answer, I think the most flexible and extensible way to deal with this is by accessing the ADSI interface for the target object (in this case a computer) and enumerate levels as follows:


$lhost_bind = [ADSI]"WinNT://" + $env:computername + ""

Query for the object’s children, and then their types:

$lhost_bind.psbase.children | foreach-object { echo $_.schemaclassname } | get-unique

“SchemaClassName” you say? “Schema,” that rings a bell. Ahh hah! WinNT Schema documentation is available!
So, each of these must be an ADSI Object within the WinNT schema!

Diving into the schema:
Let’s just take one object and dive into it, grabbing stuff directly available to powershell:

$lhost_bind.psbase.children | select-object -first 1 | foreach-object { $_ | get-member } 

Here’s a list of the properties:

$lhost_bind.psbase.children | select-object -first 1 | foreach-object { $_ | select-object * }

Here’s all the group names:

$lhost_bind.psbase.children |  where-object { $_.schemaClassName -eq 'group' } | foreach-object { echo $_.name }

We already know that we are looking at a list of objects with the schemaclassname/ADSI Object type “group” within the WinNT Schema.

Into the ADSI darkness:

We already know we’re looking at Group object, which, again, is part of the ADSI WinNT interface.

In those documents, it lists supported methods and properties for the ADSI Object/Schema member “Group” as: IADs, IADsGroup, and IADsPropertyList.

Now we know how to query for members in the Group “Administrators”:

$lhost_bind.psbase.children |  where-object { $_.schemaClassName -eq 'group' -and $_.name -eq 'Administrators' } | foreach-object { $_.Invoke("Members") }

Damn it. This tells us nothing useful, but exhibits that we have dropped into the dark of the ADSI interface COM object with Invoke().

What if we get-members on the object:

$lhost_bind.psbase.children |  where-object { $_.schemaClassName -eq 'group' -and $_.name -eq 'Administrators' } | foreach-object { $_.Invoke("Members") } | foreach-object { $_ | get-member }

And if we select-object * ?

$lhost_bind.psbase.children |  where-object { $_.schemaClassName -eq 'group' -and $_.name -eq 'Administrators' } | foreach-object { $_.Invoke("Members") } | foreach-object { $_ | select-object * }

Weird. Nothing. This is a job for documentation.

Out of the ADSI darkness:

The get-member call we just performed showed us something very interesting that we’re about to use, the very powerful GetType() methods.

Let’s take a closer look at GetType():

$lhost_bind.psbase.children |  where-object { $_.schemaClassName -eq 'group' -and $_.name -eq 'Administrators' } | foreach-object { $_.Invoke("Members") } | select-object -first 1 | foreach-object { $_.GetType() | get-member }

There are several interesting looking methods available, like GetMembers and InvokeMembers.

InvokeMembers is very powerful and will be our go to method when dealing with ADSI Interface objects:

$lhost_bind.psbase.children |  where-object { $_.schemaClassName -eq 'group' -and $_.name -eq 'Administrators' } | foreach-object { $_.Invoke("Members") } | select-object -first 1 | foreach-object { $_.GetType().InvokeMember("Class", 'GetProperty', $null, $_, $null) }

Where did “Class” come from? From it’s a property of the IADsUser object.

Where did “GetProperty” come from? It is a System.Reflection.BindingFlags member, and will (likely) be the most useful out of the bunch.

Let’s get querying:
List all the values of the Name property for each returned by Members() when querying a group with the name of Administrators:

$lhost_bind.psbase.children |  where-object { $_.schemaClassName -eq 'group' -and $_.name -eq 'Administrators' } | foreach-object { $_.Invoke("Members") } | foreach-object { $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null) }

Note that all properties available to Active Directory users are not available on local user accounts.

If you want to find out where the objects are from (as in inherited from other trusted realms), try obtaining the Parent property:

$lhost_bind.psbase.children |  where-object { $_.schemaClassName -eq 'group' -and $_.name -eq 'Administrators' } | foreach-object { $_.Invoke("Members") } | foreach-object { echo $_.GetType().InvokeMember("Parent", 'GetProperty', $null, $_, $null) $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null) `r }

Add a user to the group:
Now that we have a better idea on how to interface with ADSI, it’s quite easy to figure out how to execute the Add function for the Group ADSI interface (aka IADsGroup) by using object.Invoke():

$lhost_bind.psbase.children |  where-object { $_.schemaClassName -eq 'group' -and $_.name -eq 'Administrators' } | foreach-object { $_.Invoke("Add", "WinNT://DOMAIN/user") }

Remove a user from the group:
Removing a user from a group is just as easy, utilizing the Remove function of the Group ADSI Interface:

$lhost_bind.psbase.children |  where-object { $_.schemaClassName -eq 'group' -and $_.name -eq 'Administrators' } | foreach-object { $_.Invoke("Remove", "WinNT://DOMAIN/user") }

In my next post, I’ll cover a less terrible-bo-berrible way of doing this, instantiating an object as a .NET class!

  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: