10

I am curious if someone can describe how to enumerate ADSI methods available via a bound instance as [ADSI]$instance.psbase.Invoke()?

Research has turned up "refer to the docs for the ADSI interface". but I am not particularly happy with that answer.

If I instantiate with:

[ADSI]$lhost_group="WinNT://./Administrators,group"

Then attempt:

@($lhost_group.psbase.Invoke("Members")) | foreach-object {$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}

Powershell will return the out of GetProperty("Name") for each object contained in the group.

How do I enumerate all of the available methods and properties that would be available via any given ADSI interface?

This answer from Shay Levy is another example of syntax where [ADSI]$_.GetTypes().InvokeMember() and [ADSI]$_.psbase.Invoke() are used.

Community
  • 1
  • 1
brandeded
  • 2,080
  • 6
  • 25
  • 52
  • I'd like to add my own bounty to this question but i dont know how ? – Loïc MICHEL Sep 10 '13 at 13:50
  • I don't think you can add additional bounty. Check with the guys in the most populated room in chat (at the top toolbar). – brandeded Sep 10 '13 at 13:57
  • ok i've read the doc ^^, must wait the end of bounty before starting a new one ... too bad – Loïc MICHEL Sep 10 '13 at 14:03
  • 1
    interesting reading : http://pathologicalscripter.wordpress.com/2006/09/28/invisible-methods-for-adsi/ – CB. Sep 11 '13 at 14:20
  • Ancient, I know but still useful for reading local group info. The Scriptingguy article has some details on psbase info: https://devblogs.microsoft.com/scripting/hey-scripting-guy-how-can-i-use-windows-powershell-to-add-a-domain-user-to-a-local-group/ – uSlackr Aug 12 '21 at 21:39

2 Answers2

7

The answer is 'no' and it is unlikely to change. I share your unhappiness with that answer, but I can provide some technical background to support and explain it.

The core problem is that the native-code ADSI objects must implement the COM interface IDispatch [which allows late-bound methods to be called], but they don't necessarily implement ITypeInfo [which allows reflection-like behavior]. In PowerShell, a COM object that implements IDispatch but not ITypeInfo results in odd set of restrictions, which is what you are noticing.

The WinNT ADSI provider is at least 15 years old, and it was never a strong feature. It was a placeholder written before Active Directory shipped (way before the CLR or PowerShell.) Back then, 'scripting' at Microsoft meant early versions of VBScript, with with some support for JScript, both of which relied on IDispatch and never used ITypeInfo.

This was a topic of discussion early in PowerShell's life, when one of the PowerShell team member said:

14 Jul 2006

... The PowerShell can't show the methods of COM objects if the ITypeInfo interface is not provided. This will be fixed soon. The workaround is to use Type.InvokeMethod().

There have been improvements in PowerShell's support of COM objects, but a complete fix never materialized. I think the team member may have over-promised what is technically possible. This may have confused people. I asked a developer lead friend of mine on the team about this a couple of years ago; he was clearly familiar with the issue and indicated that the use-case wasn't a high-priority and mentioned the workaround too.

The PowerShell team has been shipping impressive features and some bug-fixes, but frankly I don't think this issue will ever make the bug bar.

Burt_Harris
  • 6,415
  • 2
  • 29
  • 64
  • Thank you for the info. I really think it leaves a hole, but heavy lifting to achieve the same goal is already around in others' work. It would be nice for MSFT to put the little bit of effort to knock this off the list though. One of the great talks at TechEd was basically about learning PowerShell through banging around in it; this is a brick wall I hit within my first two weeks of my dive. – brandeded Jul 16 '14 at 23:53
  • 1
    I understand, but personally I think it would be much nicer (and more realistic) to have Microsoft publish a complete set of local account manipulation Cmdlets rather than flogging the ADSI/WinNT provider horse. Cmdlets are always more discover-able than methods on objects, for people banging around, have well established naming conventions, help files, etc. – Burt_Harris Jul 17 '14 at 05:34
2

Not exactly sure if this answers your question, but what about the following?

$lhost_group.getType().DeclaredMembers | where { $_.MemberType -eq "Method" -or $_.MemberType -eq "Property" }

  • `$lhost_group.getType().DeclaredMembers | measure`. Results in a `Count: 0`. Did you have any luck on your local system? – brandeded Sep 10 '13 at 20:33
  • Yeah it worked in PoSH v3 but not v1/2. Try `$lhost_group.getType().GetProperties()` and `$lhost_group.getType().GetMethods()`. Is that the information your looking for? – The Unique Paul Smith Sep 10 '13 at 20:47
  • No, I am looking for the methods and properties exposed by the ADSI interface, not the methods and properties exposed by `System.DirectoryServices.DirectoryEntry`. That's what makes this so much fun. :) – brandeded Sep 10 '13 at 20:52