AD access change/break in RC2

26 views
Skip to first unread message

Lee Flight

unread,
Sep 27, 2006, 12:57:36 PM9/27/06
to
Hi

In powershell RC1 access to AD using:

$silva = New-Object
System.DirectoryServices.DirectoryEntry("LDAP://dc=silva,dc=net")

meant that

$silva |gm -MemberType Method

showed the available methods for the S.DS.DirectoryEntry of which one was
get_Children() and

$silva.get_Children()

returned the child entries.

In RC2 the above fails in that

$silva |gm -MemberType Method

returns nothing and so .get_Children() returns an error. If I try

$silva = [ADSI]("LDAP://dc=silva,dc=net")

the result is the same (i.e. fails). Using

$silva |gm -MemberType Property

does show properties.

Is this expected behavior/

Thanks
Lee Flight


Dan Metzler

unread,
Sep 27, 2006, 3:03:53 PM9/27/06
to
I'm just going to add a big "Me Too" here.

|gm does not return any methods to the object only properties

any attempt to use get_Children method results in an error.

Thanks,

- Dan Metzler

"Lee Flight" <l...@le.ac.uk-nospam> wrote in message
news:%23s7$JYl4GH...@TK2MSFTNGP05.phx.gbl...

/\/\o\/\/ [MVP]

unread,
Sep 27, 2006, 6:03:01 PM9/27/06
to
you need psbase now and some more is messed up I expained some here :

http://mow001.blogspot.com/2006/09/powershell-rc2-and-active-directory.html

gr /\/\o\/\/

James Truher

unread,
Sep 27, 2006, 6:10:27 PM9/27/06
to
yah - we changed our ADSI adaptation in the RC2 build. In previous builds,
we weren't really adapting the AD objects, now we are following a more
VBScript model. You can still get to the unadapted object via the psbase
property - (note that I'm using ADAM, but the point is still made):


PS> $ad = [adsi]"LDAP://localhost/DC=Fabrikam,DC=COM"
PS> $ad

distinguishedName
-----------------
{DC=Fabrikam,DC=COM}


PS> $ad|gm


TypeName: System.DirectoryServices.DirectoryEntry

Name MemberType Definition
---- ---------- ----------
dc Property
System.DirectoryServices.PropertyValueCollec...
distinguishedName Property
System.DirectoryServices.PropertyValueCollec...
instanceType Property
System.DirectoryServices.PropertyValueCollec...
msDs-masteredBy Property
System.DirectoryServices.PropertyValueCollec...
name Property
System.DirectoryServices.PropertyValueCollec...
nTSecurityDescriptor Property
System.DirectoryServices.PropertyValueCollec...
objectCategory Property
System.DirectoryServices.PropertyValueCollec...
objectClass Property
System.DirectoryServices.PropertyValueCollec...
objectGUID Property
System.DirectoryServices.PropertyValueCollec...
uSNChanged Property
System.DirectoryServices.PropertyValueCollec...
uSNCreated Property
System.DirectoryServices.PropertyValueCollec...
wellKnownObjects Property
System.DirectoryServices.PropertyValueCollec...
whenChanged Property
System.DirectoryServices.PropertyValueCollec...
whenCreated Property
System.DirectoryServices.PropertyValueCollec...


PS> $ad.whenCreated

Wednesday, July 19, 2006 8:47:34 PM


PS> $ad.psbase


AuthenticationType : Secure
Children : {HR, LostAndFound, NTDS Quotas, Roles}
Guid : eb27f119-a29d-4deb-a48a-19bbbbf91cca
ObjectSecurity : System.DirectoryServices.ActiveDirectorySecurity
Name : DC=Fabrikam
NativeGuid : 19f127eb9da2eb4da48a19bbbbf91cca
NativeObject : {System.__ComObject System.__ComObject
System.__ComObject,
, , System.__ComObject System.__ComObject
System.__ComObj
ect}
Parent : System.DirectoryServices.DirectoryEntry
Password :
Path : LDAP://localhost/DC=Fabrikam,DC=COM
Properties : {objectClass, distinguishedName, instanceType,
whenCreated
...}
SchemaClassName : domainDNS
SchemaEntry : System.DirectoryServices.DirectoryEntry
UsePropertyCache : True
Username :
Options : System.DirectoryServices.DirectoryEntryConfiguration
Site :
Container :

PS> $ad.psbase|gm


TypeName: System.Management.Automation.PSMemberSet

Name MemberType Definition
---- ---------- ----------
add_Disposed Method System.Void add_Disposed(EventHandler
v...
Close Method System.Void Close()
CommitChanges Method System.Void CommitChanges()
CopyTo Method
System.DirectoryServices.DirectoryEntry...
CreateObjRef Method System.Runtime.Remoting.ObjRef
CreateOb...
DeleteTree Method System.Void DeleteTree()
Dispose Method System.Void Dispose()
Equals Method System.Boolean Equals(Object obj)
GetHashCode Method System.Int32 GetHashCode()
GetLifetimeService Method System.Object GetLifetimeService()
GetType Method System.Type GetType()
get_AuthenticationType Method
System.DirectoryServices.Authentication...
get_Children Method
System.DirectoryServices.DirectoryEntri...
get_Container Method System.ComponentModel.IContainer
get_Co...
get_Guid Method System.Guid get_Guid()
get_Name Method System.String get_Name()
get_NativeGuid Method System.String get_NativeGuid()
get_NativeObject Method System.Object get_NativeObject()
get_ObjectSecurity Method
System.DirectoryServices.ActiveDirector...
get_Options Method
System.DirectoryServices.DirectoryEntry...
get_Parent Method
System.DirectoryServices.DirectoryEntry...
get_Path Method System.String get_Path()
get_Properties Method
System.DirectoryServices.PropertyCollec...
get_SchemaClassName Method System.String get_SchemaClassName()
get_SchemaEntry Method
System.DirectoryServices.DirectoryEntry...
get_Site Method System.ComponentModel.ISite get_Site()
get_UsePropertyCache Method System.Boolean get_UsePropertyCache()
get_Username Method System.String get_Username()
InitializeLifetimeService Method System.Object
InitializeLifetimeService()
Invoke Method System.Object Invoke(String
methodName,...
InvokeGet Method System.Object InvokeGet(String
property...
InvokeSet Method System.Void InvokeSet(String
propertyNa...
MoveTo Method System.Void MoveTo(DirectoryEntry
newPa...
RefreshCache Method System.Void RefreshCache(),
System.Void...
remove_Disposed Method System.Void
remove_Disposed(EventHandle...
Rename Method System.Void Rename(String newName)
set_AuthenticationType Method System.Void
set_AuthenticationType(Auth...
set_ObjectSecurity Method System.Void
set_ObjectSecurity(ActiveDi...
set_Password Method System.Void set_Password(String value)
set_Path Method System.Void set_Path(String value)
set_Site Method System.Void set_Site(ISite value)
set_UsePropertyCache Method System.Void
set_UsePropertyCache(Boolea...
set_Username Method System.Void set_Username(String value)
ToString Method System.String ToString()
AuthenticationType Property
System.DirectoryServices.Authentication...
Children Property
System.DirectoryServices.DirectoryEntri...
Container Property System.ComponentModel.IContainer
Contai...
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.ActiveDirector...
Options Property
System.DirectoryServices.DirectoryEntry...
Parent Property
System.DirectoryServices.DirectoryEntry...
Password Property System.String Password {set;}
Path Property System.String Path {get;set;}
Properties Property
System.DirectoryServices.PropertyCollec...
SchemaClassName Property System.String SchemaClassName {get;}
SchemaEntry Property
System.DirectoryServices.DirectoryEntry...
Site Property System.ComponentModel.ISite Site
{get;s...
UsePropertyCache Property System.Boolean UsePropertyCache
{get;set;}
Username Property System.String Username {get;set;}


PS> $ad.psbase.get_children()

distinguishedName
-----------------
{OU=HR,DC=Fabrikam,DC=COM}
{CN=LostAndFound,DC=Fabrikam,DC=COM}
{CN=NTDS Quotas,DC=Fabrikam,DC=COM}
{CN=Roles,DC=Fabrikam,DC=COM}


I hope that helps

--
--
James Truher [MSFT]
Windows PowerShell Development
Microsoft Corporation
This posting is provided "AS IS" with no warranties, and confers no rights.

"Dan Metzler" <dmet...@southslope.net> wrote in message
news:uHtwvem4...@TK2MSFTNGP06.phx.gbl...

/\/\o\/\/ [MVP]

unread,
Sep 27, 2006, 6:46:02 PM9/27/06
to
James,

as you can see in my blogpost I know about PsBase.
but that is not the only point made there.

I did a lot to show managing AD is great from PoSH, but this makes it realy
unusable. and hard to explore for a beginning AD user.

try to do the AD series on my blog in translate it into RC2 on the fly
interactive on the commandline (part 3 will be nice ;-) ) you will see what
I mean.

also remember that we did change the AD browser into you RC2 ?
was that more easy to explain?

I did want to show off at work today, and completly messed up in RC2, and
could not explain the logic.

Greetings /\/\o\/\/

Dan Metzler

unread,
Sep 27, 2006, 10:20:59 PM9/27/06
to
I appreciate the clue on the psbase part of this.

I do find myself wondering why add another level of complexity. Any clues
on this? I'm sure there must be some reason.
Is there a way to get the child objects without using psbase?


"James Truher" <jim...@news.microsoft.com> wrote in message
news:eS849Go...@TK2MSFTNGP02.phx.gbl...

Chris Warwick

unread,
Sep 28, 2006, 5:14:49 AM9/28/06
to
On Wed, 27 Sep 2006 15:03:01 -0700, /\/\o\/\/ [MVP]
<oM...@discussions.microsoft.com> wrote:

>you need psbase now and some more is messed up I expained some here :
>
>http://mow001.blogspot.com/2006/09/powershell-rc2-and-active-directory.html
>
>gr /\/\o\/\/

<...snip...>

After my original, optimistic, reply I have to say I now agree with
MOW and the other posters - this is not good in my opinion.

Nick Howell pointed me to the MSDN entries for
System.DirectoryServices.DirectoryEntry (see thread "[ADSI] Syntax")
so I went and tried the various methods and properties and couldn't
make any sense of what I was (or, rather, wasn't) seeing.

There was a simple C# sample on MSDN and I confidently converted it to
PS only to find it told me nothing and just confused the hell out of
me!

$de=[ADSI]"LDAP://OU=Harwell,dc=mydomain,dc=com"
$de.children

..didn't work, but should! I tried iterating over the object - that
didn't work either. If I hadn't read the newsgroup and seen the
articles about psbase I would have no where to go and would've just
had to give up.

This is unfortunately another example of where PS is FAILING badly in
its quest to be intuitive and to allow Jeffrey's "experimentation and
exploration" approach.

NOT good.

Regards,
Chris

Dan Metzler

unread,
Sep 28, 2006, 7:26:29 AM9/28/06
to
> I do find myself wondering why add another level of complexity. Any clues
> on this? I'm sure there must be some reason.

As I work with this a little more, I realize I should have said "another
level of abstraction" instead of "another level of complexity".
In terms of just working with the properties of an LDAP object, I like what
I see, but a way to enumerate the children of a container in an LDAP object
is not readily apparent.


"Dan Metzler" <dmet...@southslope.net> wrote in message

news:Ow6zATq4...@TK2MSFTNGP05.phx.gbl...

Dan Metzler

unread,
Sep 28, 2006, 7:40:47 AM9/28/06
to
Just a few comments here:

> Nick Howell pointed me to the MSDN entries for
> System.DirectoryServices.DirectoryEntry (see thread "[ADSI] Syntax")
> so I went and tried the various methods and properties and couldn't
> make any sense of what I was (or, rather, wasn't) seeing.

I think Nick was only pointing to the
System.DirectoryServices.DirectoryEntry documentation for specification on
the quoted string in the [ADSI]
syntax; not for the properties and methods on the resulting object.

In general, I agree that psbase and [ADSI] need to be documented somewhere
including within get-help. Perhaps an "about-ADSI" section would work?


"Chris Warwick" <ne...@remove.this.bit.nuney.com> wrote in message
news:3k4nh2t2rc9ggkh4c...@4ax.com...

Lee Flight

unread,
Sep 28, 2006, 7:40:42 AM9/28/06
to
Thanks that does help (two words "Release Notes" :), please ).

I too would like to see some info on this adaptation of types, e.g.
there's no reference to psbase that I could find in the user guide.

Why is it:

PS> $ad = [adsi]"LDAP://localhost/DC=Fabrikam,DC=COM"

PS> $ad.psbase
PS> $ad.psbase.get_children()

rather than, something like,
PS> $ad = object-type [provider] moniker
e.g.

PS> $ad = PSbase [adsi]"LDAP://localhost/DC=Fabrikam,DC=COM"
PS> $ad.get_children()

where e.g. "PSbase" means non-adapted?

Thanks!
Lee Flight

"James Truher" <jim...@news.microsoft.com> wrote in message
news:eS849Go...@TK2MSFTNGP02.phx.gbl...

Chris Warwick

unread,
Sep 28, 2006, 9:06:53 AM9/28/06
to
On Thu, 28 Sep 2006 06:40:47 -0500, "Dan Metzler"
<dmet...@southslope.net> wrote:

>Just a few comments here:
>
>> Nick Howell pointed me to the MSDN entries for
>> System.DirectoryServices.DirectoryEntry (see thread "[ADSI] Syntax")
>> so I went and tried the various methods and properties and couldn't
>> make any sense of what I was (or, rather, wasn't) seeing.
>
>I think Nick was only pointing to the
>System.DirectoryServices.DirectoryEntry documentation for specification on
>the quoted string in the [ADSI]
>syntax; not for the properties and methods on the resulting object.
>
>In general, I agree that psbase and [ADSI] need to be documented somewhere
>including within get-help. Perhaps an "about-ADSI" section would work?
>

You're right about my original query on the quoted string for [ADSI],
that was answered by Nick. But my point in the last post was to agree
with MOW and others that the way the properties and methods of the
resulting objects are hidden is not good.

It spoils the glide path that we keep hearing about too! I'd like to
look at a C# sample and convert to PS without worrying about some
spurious syntax.

Help is definitely needed - but why do this anyway? What's the
benefit to the PS user?

Thanks
Chris

Dan Metzler

unread,
Sep 28, 2006, 10:17:30 AM9/28/06
to
> Help is definitely needed - but why do this anyway? What's the
> benefit to the PS user?
>
> Thanks
> Chris

I'm still holding out hope that there is some advantage to this extra layer
of abstraction, I guess.
Because there isn't really any documentation on the abstracted layer, I
can't really say whether I think it is good or bad.
When I can't do something in the abstracted layer, I can revert to the
psbase layer and continue on.

So I really can't answer the question, "What's the benefit to the PS user?".

If this is all there is, then I agree that the extra layer of abstraction
really serves no benefit while causing some real negative affects.
I just keep thinking there must be a reason for making the change,
(therefore more to this than we have discovered), and I sure would like to
hear what direction they are trying to take with this.
Is this in preperation for some kind of file system like interface? (For
example: Change context to Active directory and use dir to list the
children, cd to change the context to one of them)

I guess we'll just have to keep waiting for some kind of response to these
questions...

- Dan


KenTay

unread,
Sep 28, 2006, 2:25:59 PM9/28/06
to
I have to agree with Mow and the others. I was navigating and
manipulating AD quite well in RC1. I don't understand the idea behind
adding psbase in order to uncover the members. I know it's been said
before, but the lack of tab completion also makes this very unworkable.
I'd love to be involved in the testing and bug fixes for RC2,
unfortunately I feel I can get more done, more quickly, with RC1. With
all that said, I still love the product, I just don't understand the
ADSI changes. Perhaps some comprehensive documentation on PSbase would
help? Thanks.

Ken

Jim Holbach

unread,
Sep 28, 2006, 4:19:01 PM9/28/06
to
I like the more comprehensive list of AD attributes that are directly
accessible now, though I haven't had much time to try them out today. I'm
just not sure that I understand why all the methods needed to disappear.

So in the "spirit of PowerShell", I’ve just extended the type definition for
DirectoryEntry so that I can still use my previous scripts, etc.

For each of the previous methods for DirectoryEntry, I’ve added a
ScriptMethod. So for example,

<ScriptMethod>
<Name>get_Children</Name>
<Script>
$this.psbase.get_Children()
</Script>
</ScriptMethod>

allows me to continue to use

$Entry.get_Children()

without the psbase “layer”.

This also allows previous code like MoW’s

<ScriptProperty>
<Name>PasswordLastChanged</Name>
<GetScriptBlock>
$this.InvokeGet(’PasswordLastChanged’)
</GetScriptBlock>
</ScriptProperty>

to work again. I put these together in a hurry and haven’t had time for much
testing so YMMV, but if this approach seems to make any sense, please help
yourself to a copy at http://pathologicalscripter.wordpress.com/?page_id=8.
(Comments are always welcome also.)

---
Jim Holbach

Arul Kumaravel[MSFT]

unread,
Sep 28, 2006, 5:57:20 PM9/28/06
to
Folks,
I know that many of you are wondering about ADSI changes in RC2. I am
currently in the process of writing a blog to explain the new ADSI
support.
People are wondering as to why methods are not showing up in GM. .Net
DirectoryService Object is wrapper around the underlying AD com object.
Based on the type of AD com object, it can have any number of interfaces
like IADs, IADsContainer, IADsNameSpaces etc. .Net DirectoryService
doesn't expose all the functionality of the underlying AD object. That is
the reason why DirectoryEntry object has property called NativeObject to
access the underlying COM object. The Native COM object doesn't have all
the metadata to determine all the methods that it provides. Faced with this
constraint, we chose a route similar to VBScript. When we decided to
support AD Scripting, we wanted to make it as simple as possible but at the
same time expose of the full functionality of AD. VBSCript provides
this functionality with set of following methods alone

Create
Put
Set
PutEx
SetEx
GetInfo
SetInfo


The above list of methods will allow you to do pretty much all ADSI
scripting tasks. We thought of exposing these set of methods as part of
Get-Member call but decided against it (In retrospect, may be we should have
exposed these). Not exposing the methods is what throws people off with the
new ADSI support.

I had written some blog posts on using new ADSI support in the following
blogs. Please take a look at it. I used ADAM to test these scripts

http://blogs.msdn.com/arulk/archive/2006/07/25/678137.aspx

http://blogs.msdn.com/arulk/archive/2006/07/28/682289.aspx

http://blogs.msdn.com/arulk/archive/2006/08/24/719241.aspx

For Advanced script users, who are still interested in access to the
DirectoryEntry object, it is available as PSBase property in the PSObject.
People who are familiar with ADSI scripting with VBScript will find the
transition much easier. If you are used to using DirectoryEntry object
then the new changes would be disruptive to existing mental model.

I will look into some of the examples people have provided in the blog
posts and convert few of this into new ADSI syntax and share it with you.


thanks

--
--
Aruk Kumaravel [MSFT]
Windows PowerShell Development Manager
Microsoft Corporation
My PowerShell Blog: http://blogs.msdn.com/arulk


This posting is provided "AS IS" with no warranties, and confers no rights.

"Jim Holbach" <JimHo...@discussions.microsoft.com> wrote in message
news:3FD61E1F-8F7D-4C97...@microsoft.com...

Dan Metzler

unread,
Sep 29, 2006, 7:11:46 AM9/29/06
to
What about getting child objects? Is this considered an advanced task that
requires the use of psbase:
$ADObject.psbase.children

or is there another unexposed property or method?

Thanks,

- Dan

"Arul Kumaravel[MSFT]" <ar...@nospam.microsoft.com> wrote in message
news:ucLsZk04...@TK2MSFTNGP02.phx.gbl...

Erich Stehr

unread,
Oct 15, 2006, 1:59:18 AM10/15/06
to
I fell behind in the newsgroup a bit, but I do also have to ask the question
"WHY???"

When I was first working on accessing a web service in RC1, the sample code
pointed at the old XMLHTTPRequest object, then I realized that the .NET
objects were accessible, and I had access to the much more reasonably useful
WebClient, and the XML wrapper had the native API tucked in as the
discoverable get_*().

When I started needing to get to ADSI, RC2 had just been released, so I
thought that I could either use the COM objects, or I could do the smart
thing and look at DirectoryEntry.... only to find that there's no
documentation, and no documented or discoverable native access on the mock
COM objects wrapper being placed around DirectoryEntry! Yes, PSBase is
there; yes, DirectoryEntry is a wrapper around the scripting objects anyway;
but why is ADSI (and only ADSI) being wrapped in a harder to use additional
interface when XML still has the capability to directly and discoverably get
to the managed interface through its wrapper?

I really have to agree with the complaints -- If you insist on doing it the
VBScript way, the old objects are still available to you (just see the
scripting center examples!), so the glide path should _always_ be toward
.NET. After all, isn't one of the PowerShell 'principles' an internal
consistency?

I have looked at the blog entries, and they just didn't help. They all did
the same thing, basic reading. When I tried to read properties from the
wrapper (pwdLastSet from the user entry, pwdMaxAge from the domain entry) I
could only get indigestible System.__ComObject's. I eventually used the
DirectorySearcher because I could actually _get_ to the properties that I
needed:

## PasswordExpiration.ps1
param ([string]$dom = 'CONTOSO', [string]$usr = 'rkelly')

# find the local domain root for its distinguishedName
$localRoot = new-object DirectoryServices.DirectoryEntry

# find the named domain in the local forest
$domainRoot = new-object DirectoryServices.DirectoryEntry
('LDAP://'+$localRoot.distinguishedName[0].Replace($localRoot.name, $dom))

$dirsrch = new-object System.DirectoryServices.DirectorySearcher $domainRoot

#$dirsrch.Filter="(&(objectCategory=person)(sAMAccountName=$([Environment]::Username)))"
$dirsrch.Filter="(&(objectCategory=person)(sAMAccountName=$usr))"
$srchres = $dirsrch.FindOne()
$pwdLastSet = [DateTime]::FromFileTime($srchres.Properties.pwdlastset[0])

$dirsrch.Filter='(objectClass=domain)'
$domRes = $dirsrch.FindOne()
$maxpwdspan = [TimeSpan]$domRes.properties.maxpwdage[0]

$expires = $pwdLastSet - $maxpwdspan
write-host $srchres.Properties.userprincipalname[0]
write-host $expires
## end

I don't really expect any changes before release, I just want to register my
disagreement of useless consistency with the old way for ADSI instead of
being consistent with the prior demonstrations of "the PowerShell way", like
XML.

Thanks
Erich Stehr

"Arul Kumaravel[MSFT]" <ar...@nospam.microsoft.com> wrote in message
news:ucLsZk04...@TK2MSFTNGP02.phx.gbl...

[deleted]


Reply all
Reply to author
Forward
0 new messages