In windows powershell what is the difference between $objGroup.add($objUser.Path)) and $objGroup.PSBase.Invoke('Add',$objUser.PSBase.Path)

StackOverflow https://stackoverflow.com/questions/21400470

Question

I want to add a user to a group :

I have found it is possible in two ways. First Method :

$objGroup.add($objUser.Path))

where $objGroup is the directory entry of the group and $objUser is the directory entry of the user to be added.

Second Method :

$objGroup.PSBase.Invoke('Add',$objUser.PSBase.Path)

where $objGroup is the directory entry of the group and $objUser is the directory entry of the user to be added.

What is the difference between these two methods? Which method is preferred?

Was it helpful?

Solution

PSBase is generally used to invoke the hidden methods, if I can say that. For example, when I used [ADSI] to connect get an instance of local administrators group and then look at the members of the object, this is what I see.

PS H:\> $admGroup = [ADSI]("WinNT://./Administrators")
PS H:\> $admGroup | gm


   TypeName: System.DirectoryServices.DirectoryEntry

Name                        MemberType Definition
----                        ---------- ----------
ConvertDNWithBinaryToString CodeMethod static string ConvertDNWithBinaryToString(psobject deInstance, psobject dnWit...
ConvertLargeIntegerToInt64  CodeMethod static long ConvertLargeIntegerToInt64(psobject deInstance, psobject largeInt...
Description                 Property   System.DirectoryServices.PropertyValueCollection Description {get;set;}
groupType                   Property   System.DirectoryServices.PropertyValueCollection groupType {get;set;}
Name                        Property   System.DirectoryServices.PropertyValueCollection Name {get;set;}
objectSid                   Property   System.DirectoryServices.PropertyValueCollection objectSid {get;set;}

You don't see the add() method because it is not exposed here in PowerShell. This is where PSBase helps you access the raw object.

PS H:\> $objGroup.PSBase | gm


   TypeName: System.Management.Automation.PSMemberSet

Name                      MemberType Definition
----                      ---------- ----------
Disposed                  Event      System.EventHandler Disposed(System.Object, System.EventArgs)
Close                     Method     void Close()
CommitChanges             Method     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     void DeleteTree()
Dispose                   Method     void Dispose(), void IDisposable.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     void InvokeSet(string propertyName, Params System.Object[] args)
MoveTo                    Method     void MoveTo(adsi newParent), void MoveTo(adsi newParent, string newName)
RefreshCache              Method     void RefreshCache(), void RefreshCache(string[] propertyNames)
Rename                    Method     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   guid Guid {get;}
Name                      Property   string Name {get;}
NativeGuid                Property   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   adsi Parent {get;}
Password                  Property   string Password {set;}
Path                      Property   string Path {get;set;}
Properties                Property   System.DirectoryServices.PropertyCollection Properties {get;}
SchemaClassName           Property   string SchemaClassName {get;}
SchemaEntry               Property   adsi SchemaEntry {get;}
Site                      Property   System.ComponentModel.ISite Site {get;set;}
UsePropertyCache          Property   bool UsePropertyCache {get;set;}
Username                  Property   string Username {get;set;}

We can invoke the add method on this object using the Invoke() method. You simply pass Add as the method name and a user name as parameter.

So, in summary, the PSBase concept should be used based on the context.

OTHER TIPS

Quote from this answer:

When you use the [ADSI] type accelerator to create a DirectoryEntry object, what you get is not actually a DirectoryEntry object, rather you get a DirectoryEntry with a fine PowerShell wrapper around it. By accessing the psbase of this wrapped object, you access the raw DirectoryEntry object underneath.

.Add('..') is actually not a DirectoryEntry function, it's a function that's mapped by the type accelerator to .psbase.Invoke('Add', '..'). People suggesting that you use .psbase.Invoke() are worried about backwards and forwards compatibility and whatnot. It's entirely up to you which to use.

The type accelerators were created to speed up working with the base objects, including creating conveniences like .Add() and such. Basically if you're not going to use the type accelerator functions, there's no point using the type accelerator at all. Might as well just go the long way around and create your own DE object:

$de = New-Object System.DirectoryServices.DirectoryEntry('WinNT://./Administrators,group')
$de.Invoke('Add', '...')
$de.Close()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top