/\/\o\/\/ PowerShelled

This blog has moved to http://ThePowerShellGuy.com Greetings /\/\o\/\/
$AtomFeed = ("Atom.xml")
$PreviousItems = (" PowerShell : Using IronPython to Connect to AD and... "," PowerShell Session video of Bruce Payette "," PowerShell : Active Directory Part 11 - moving - R... "," PowerShell : Learn about the HashTable Object and ... "," PowerShell : Setting SendAs permission in Exchange... "," PowerShell : Active Directory Part 10 (AD Browser)... "," PowerShell "," PowerShell : How Do I randomize a list, and remove... "," PowerShell : Can you do that less cryptic ? "," PowerShell : How can I tell whitch numbers are mis... "," ")

Wednesday, September 27, 2006

 


PowerShell RC2 and Active Directory



As you have RC2 Installed all my AD post will not work anymore, As I did switch back on all my work PC's (I did call all my colleagues not to upgrade as all our AD tools are messed up, I will not update them, as I would not recommend to upgrade to RC2 of you work with AD a lot , as it is verry confusing, but fixable if you read explaination below,

 you can get all working again be the result might be messy.

he examples in my AD series will most of the time not work, most of the things discussed will not seem to be there , so if you did not do AD in PowerShell all seem very strange, and it will be hard to follow.

I will explain what has happened and give the ways to solve this.

As  PowerShell RC2 was released, I hopefully started to explore the new AD support  :

 

PS C:\PowerShell> [ADSI]''

distinguishedName
-----------------
{DC=mow,DC=local}

PS C:\PowerShell> $root = [ADSI]''

 

Wow Cool, but then :

 

PS C:\PowerShell> $root.get_Children()
Exception calling "get_Children" with "0" argument(s): "Unknown name. (Exception from HRESULT: 0x80020006 (DISP_E_UNKNO
WNNAME))"
At line:1 char:19
+ $root.get_Children( <<<< )

Hmm, should be there, lets remove the () :

PS C:\PowerShell> $root.get_Children

MemberType : Method
OverloadDefinitions :
TypeNameOfValue : System.Management.Automation.PSMethod
Value :
Name : get_Children
IsInstance : True

bit strange output but its there

Hmm its not there.

PS C:\PowerShell> $root | gm

TypeName: System.DirectoryServices.DirectoryEntry

Name MemberType Definition
---- ---------- ----------
auditingPolicy Property System.DirectoryServices.PropertyValueCollection auditingPolicy {get;set;}
creationTime Property System.DirectoryServices.PropertyValueCollection creationTime {get;set;}
dc Property System.DirectoryServices.PropertyValueCollection dc {get;set;}
distinguishedName Property System.DirectoryServices.PropertyValueCollection distinguishedName {get;...

...

...

Ok we do not see it but let's try PSbase

PS C:\PowerShell> $root.psbase | gm

TypeName: System.Management.Automation.PSMemberSet

Name MemberType Definition
---- ---------- ----------
add_Disposed Method System.Void add_Disposed(EventHandler value)
Close Method System.Void Close()
CommitChanges Method System.Void CommitChanges()
CopyTo Method System.DirectoryServices.DirectoryEntry CopyTo(DirectoryEntry newParent), Syste...
CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObjRef(Type requestedType)
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.AuthenticationTypes get_AuthenticationType()
get_Children Method System.DirectoryServices.DirectoryEntries get_Children()
get_Container Method System.ComponentModel.IContainer get_Container()
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.ActiveDirectorySecurity get_ObjectSecurity()
get_Options Method System.DirectoryServices.DirectoryEntryConfiguration get_Options()
get_Parent Method System.DirectoryServices.DirectoryEntry get_Parent()
get_Path Method System.String get_Path()
get_Properties Method System.DirectoryServices.PropertyCollection get_Properties()
get_SchemaClassName Method System.String get_SchemaClassName()
get_SchemaEntry Method System.DirectoryServices.DirectoryEntry get_SchemaEntry()
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, Params Object[] args)
InvokeGet Method System.Object InvokeGet(String propertyName)
InvokeSet Method System.Void InvokeSet(String propertyName, Params Object[] args)
MoveTo Method System.Void MoveTo(DirectoryEntry newParent), System.Void MoveTo(DirectoryEntry...
RefreshCache Method System.Void RefreshCache(), System.Void RefreshCache(String[] propertyNames)
remove_Disposed Method System.Void remove_Disposed(EventHandler value)
Rename Method System.Void Rename(String newName)
set_AuthenticationType Method System.Void set_AuthenticationType(AuthenticationTypes value)
set_ObjectSecurity Method System.Void set_ObjectSecurity(ActiveDirectorySecurity value)
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(Boolean value)
set_Username Method System.Void set_Username(String value)
ToString Method System.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;}

 

Ahh, there are all the usefull methods and properties, hmm maybe not that bad, as this works now

 

PS C:\PowerShell> $root.psBase.children

distinguishedName
-----------------
{CN=Builtin,DC=mow,DC=local}
{CN=Computers,DC=mow,DC=local}
{OU=Domain Controllers,DC=mow,DC=local}
{CN=foo,DC=mow,DC=local}
{CN=fooBar,DC=mow,DC=local}

But then again!!!!!!

First, the PSbase is hidden, so you need to be a more advanced PoSH user and know about it.

then there is no tab completion and you need this much,

 

PS C:\PowerShell> $user.InvokeGet('AccountDisabled')
Exception calling "InvokeGet" with "1" argument(s): "Unknown name. (Exception from HRESULT: 0x80020006 (DISP_E_UNKNOWNN
AME))"
At line:1 char:16
+ $user.InvokeGet( <<<< 'AccountDisabled')


PS C:\PowerShell> $user.psbase.InvokeGet('AccountDisabled')
True

PS C:\PowerShell> $user.InvokeSet('department','foo')

Exception calling "InvokeSet" with "2" argument(s): "Unknown name. (Exception from HRESULT: 0x80020006 (DISP_E_UNKNOWNN
AME))"
At line:1 char:16
+ $user.InvokeSet( <<<< 'department','foo')

Get-member does give misleading info, I think I got the BaseObject here memberset ?. 

 

PS C:\PowerShell> $user.psbase | gm

TypeName: System.Management.Automation.PSMemberSet

Name MemberType Definition
---- ---------- ----------

...

...

But after that even worse, if you follow the series you could add Properties directly and did not need to commit them (part 3) Hence you could do this :

PS C:\PowerShell> $user.displayName = 'user'

Looks OK but ... where is it ??

PS C:\PowerShell> $user.displayName
PS C:\PowerShell>

 

Refresh or commit ?

PS C:\PowerShell> $user.psbase.RefreshCache()

PS C:\PowerShell> $user.displayName

PS C:\PowerShell> $user.psbase.CommitChanges()
PS C:\PowerShell> $user | fl *

objectClass : {top, person, organizationalPerson, user}
cn : {Ken Myer}
distinguishedName : {CN=Ken Myer,DC=mow,DC=local}
instanceType : {4}
whenCreated : {8/14/2006 7:47:24 PM}
whenChanged : {9/27/2006 8:08:22 PM}
uSNCreated : {System.__ComObject}
uSNChanged : {System.__ComObject}
department : {foo}
name : {Ken Myer}
objectGUID : {147 228 120 129 152 3 234 72 153 138 249 176 59 43 99 6}
userAccountControl : {546}
badPwdCount : {0}
codePage : {0}
countryCode : {0}
badPasswordTime : {System.__ComObject}
lastLogoff : {System.__ComObject}
lastLogon : {System.__ComObject}
pwdLastSet : {System.__ComObject}
primaryGroupID : {513}
objectSid : {1 5 0 0 0 0 0 5 21 0 0 0 94 172 186 232 167 29 117 70 12 60 36 84 68 13 0 0}
accountExpires : {System.__ComObject}
logonCount : {0}
sAMAccountName : {$4A3000-FT61QRM67UFO}
sAMAccountType : {805306368}
objectCategory : {CN=Person,CN=Schema,CN=Configuration,DC=mow,DC=local}
nTSecurityDescriptor : {System.__ComObject}

PS C:\PowerShell> $user.psbase.displayName = 'user'
Property 'displayName' cannot be found on this object; make sure it exists and is settable.
At line:1 char:14
+ $user.psbase.d <<<< isplayName = 'user'

Hmm, let go the hard way then (and again the Psbase !!!!)

PS C:\PowerShell> $user.psbase.InvokeSet('displayname','foo')
PS C:\PowerShell> $user.psbase.CommitChanges()
PS C:\PowerShell> $user | fl *

objectClass : {top, person, organizationalPerson, user}
cn : {Ken Myer}
distinguishedName : {CN=Ken Myer,DC=mow,DC=local}
instanceType : {4}
whenCreated : {8/14/2006 7:47:24 PM}
whenChanged : {9/27/2006 8:13:11 PM}
displayName : {foo}
...

...

And now it works, but you see that we seem to be back in the ADAM limits !!!,

also this is ofcourse very dangerous, as it does only work sometimes.

PS C:\PowerShell>
PS C:\PowerShell> $user.displayname = 'bar'
PS C:\PowerShell> $user

distinguishedName
-----------------
{CN=Ken Myer,DC=mow,DC=local}

PS C:\PowerShell> $user.displayname
bar

 

So you see this makes working with AD interactive very errorprone, and lots of extra troubles and gotyas to take care of, and I hope that this will be solved for RTM as I think this makes PowerShell AD support much worse opposed to better,and lots of boilercode making scripts harder to read.

I realy wonder how they came to this and if they did eat there own dogfood on this one, as I can not get what they see as improvements for this wrapper.

for WMI the ++ are mutch greater (direct method access)  as the -- (losing getInstances() e.g.)

 but for AD please give me only the [ADSI] shortcut, and remove that wrapper again, as said and shown I think this makes it even harder for starters in PowerShell to explore AD.

 

So as you could see in last post I got started with IronPython for AD management also, it is a lot more clear as current solution in RC2, as dir() does show all directly , but as PTY is limited (no tabcompletion) but we have dir() next to the PTY examples (as we have no tabcompletion and PowerShell commands(direct see PowerShell Memo links) in next post I also will work out loading the IronPython DLL to work with it from PowerShell and embed it inside a script using a here string in and add some more AD stuff, also I look into the Event Form and Thread support in IronPython and how to borrow this functionality from IronPython to extend PowerShell.

Our Japanese MVP newpops is also doing a series on doing it the other way around hosting PowerShell in IronPython PowerShell Memo:

be sure to take a look, only the code samples impressive enough and will get you going or you can use Google to translate.

[PowerShell][IronPython]PowerShell from IronPython

[PowerShell][IronPython]PowerShell from IronPython Part 2

Very Very cool also, so when we take best of all "Dynamic" worlds all will be good and PoSHy ;-)

 

Enjoy,

Greetings, /\/\o\/\/

Tags : Monad IronPython PowerShell




Comments:
Anonymous Arul Kumaravel
Mow,
We did change the ADSI implementation. Please see my blog http://blogs.msdn.com/arulk for using ADSI. The reason why methods doesn't show up is because the objec that you point might be implementing many different ADSI interfaces. WE are planning on fixing this in our next release. I will try to go through your ADSI blogs and try to show how to do it in the new syntax.

ADSI adaptation is based on how ADSI is used in existing scripting languages.

thanks
-Arul
 
Blogger /\/\o\/\/
Arul,

I did follow your blog,
and things are fixable,but much less easy as in RC1.

especialy for beginners and interactive use.

also to mimic that old scriptinglanguage, then I was so glad to leave behind, looks like a bad idea, also we had the Invoke Method for this.

this glidepath goes the wrong way, back to looking up again,also as it works different a the SDK does state, more confusion.

Greetings /\/\o\/\/
 
Anonymous Anonymous
MOW, I love your articles and turn to them for guidence in learning the power of powershell. However, sometimes you completely loose me. For example, when I do [ADSI] I only get

PS C:\Documents and Settings\seatterj> [adsi]

IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True False DirectoryEntry System.ComponentModel.Component


Nothing about a domain name for me to work with. Given that I like many SA's are scripters who learn by copying from others it would be great if you could qualify some of the leaps in knowledge for us.

Thank you
 
Blogger /\/\o\/\/
You get the output of the type.

You need to give a LDAP path to connect to, If you give an empty string it will connect to the domain

[ADSI]""


Greetings /\/\o\/\/
 
Blogger jv
I walked through much of your experience with this article. Still not sure about PsBase. It seems to be there and not there depending on the path of access. I suspect the next release will sort this out.

Anyway - WOW you are doing a great job of sorting through getting ADSI to work in PowerShell.

Thanks MOW.
 
Anonymous Anonymous
I don't care much for this implementation, either. Now I have to wonder what form the MMC generated code will take, and what consequences this may have for the promised AD Provider in V2.
 
Blogger Airshipjones
Have you figured out how to get a recursive list of computers? I can get any info from an individual user/machine if I already know the name, but that isn't very useful in a large environment.
 
Blogger /\/\o\/\/
@Airshipjones,

this will list all the Computers :

$root = [ADSI]''
$searcher = new-object System.DirectoryServices.DirectorySearcher($root)
$searcher.Filter = '(objectClass=Computer)'
$searcher.FindAll()

for more examples See also :
http://mow001.blogspot.com/2006/03/working-with-csv-files-in-msh-part-one.html
http://mow001.blogspot.com/2005/12/get-ad-info-into-nested-hashtable-from.html

Greetings /\/\o\/\/
 
Post a Comment

Links to this post:

Create a Link



<< Home

Archives

October 2005   November 2005   December 2005   January 2006   February 2006   March 2006   April 2006   May 2006   June 2006   July 2006   August 2006   September 2006   October 2006   November 2006   December 2006  

$Links = ("PowerShell RC1 Docs"," PowerShell RC1 X86"," PowerShell RC1 X64"," Monad GettingStarted guide"," Monad Progamming Guide"," Monad SDK"," Monad videos on Channel 9"," MSH Community Workspace"," scripts.readify.net "," MonadSource"," www.reskit.net"," PowerShell Blog"," Under The Stairs"," computerperformance powershell Home"," proudlyserving"," MSH on wikipedia"," MSHWiki Channel 9"," Keith Hill's Blog"," Precision Computing"," PowerShell for fun"," MSH Memo (Japanese)"," monadblog")

find-blog -about "PowerShell","Monad" | out-Technorati.
find-blog -contains "","" | out-Technorati.
Google
 
Web mow001.blogspot.com

This page is powered by Blogger. Isn't yours?