/\/\o\/\/ PowerShelled

This blog has moved to http://ThePowerShellGuy.com Greetings /\/\o\/\/
$AtomFeed = ("Atom.xml")
$PreviousItems = (" PowerShel and Active Directory Part 1 "," TechEd RoundUp "," A big hurray for the Scripting Guy ! "," Teched "," PowerShell Tab Completion Part 4 "," The DFO Show - Introducing Windows PowerShell "," PowerShell Tab Completion Part 3 of more ? "," PowerShell Tab Completion Part 2 "," The Microsoft Code "," Powershell links and free E-book "," ")

Monday, June 26, 2006

 


PowerShell and Active Directory Part 2



In this second part of the PowerShell and Active Directory series, we go on from PowerShel and Active Directory Part 1 (Sorry for the Typo)
A quick refresh and commands needed to get back in that state :

# Connect to a Domain (Default Naming Context) :

$root = New-Object System.DirectoryServices.DirectoryEntry

# listing the Child Objects

$root.get_Children()

# Getting a Child Object

$mowOU = $root.get_Children().find('ou=mowOu')

# connect directly to a Active Directory Object using a path

$mowOu = New-Object DirectoryServices.DirectoryEntry("LDAP://OU=MowOu,DC=mow,DC=local")



Also we did see that we can use format-list * / format-Table * to list all the properties,
and that we can get the members and Properties by using get-member.
also you could see that the DirectoryEntry Object is a Wrapper that can contain different kinds of AD Objects, e.g. : Domain,OU,User (and if you did follow my advice and did some "browsing" on your own you could see that that goes also for Groups and other objects). We learned that its always good to check the type of the object that we get back as sometimes it's a bit different that that we expect, also we did see how to use get-member to get the methods of an object that is enumerable.

In this second part we are going to create a user.
and then create a 100 of them and set some more properties.

as in this part of the series we going to write to the ActiveDirectory it might not be a good Idea to do it in a Production environment, or you might not have an AD present and still want to follow the series, for the Demo I did use a VM with a domain controller but you can also use ADAM (AD application Mode) that you can install on your own workstation to test.

For more information about using adam and how to get and install it see this post : (link to Adam still works and looks updated to SP1)
Monad and Adam (and a preview of my to-be AD provider)

(PS nope I did not work on the AD provider anymore and it might take a while before I do, Sorry not enough insomnia time)

also you can find an example to create the MowOU in that post, from there on you can follow the series, only the "automatic" connection to the Domain will not work, you need to give the LDAP path in the DirectoryEntry Constructor, as explained that post.

So after you connected to the Test OU of your choice, let's go on Creating a User

As we have see in former post, the Get_Children() Method of Returns a DirectoryEntries Object, and as I hinted or you might have see in the get-member output this Object also has a Add Method, let's find out how that does work :


PoSH>$mowou

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


PoSH>$mowou.get_Children().add


MemberType          : Method
OverloadDefinitions : {System.DirectoryServices.DirectoryEntry Add(String name, String schemaClassName)}
TypeNameOfValue     : System.Management.Automation.PSMethod
Value               : System.DirectoryServices.DirectoryEntry Add(String name, String schemaClassName)
Name                : Add
IsInstance          : True



You call a method in PowerShell with () behind it, if you leave them away as I did above you get some info about the Method,
especially the OverloadDefinitions is very valuable, in this case it shows us that the Add method has one overload and it takes a string name and a string SchemaClassName.

# Create User

PoSH>$user = $mowou.get_Children().add("CN=Mow2",'User')

PoSH>$user

distinguishedName
-----------------
{}


PoSH>$mowou.get_Children().find("CN=Mow2")

Exception calling "Find" with "1" argument(s): "There is no such object on the server. (Exception from HRESULT: 0x80072030)"
At line:1 char:27
+ $mowou.get_Children().find( <<<< "CN=Mow2")

# Save

PoSH>$user.CommitChanges()

PoSH>$user

distinguishedName
-----------------
{CN=Mow2,OU=MowOu,DC=mow,DC=local}


PoSH>$mowou.get_Children().find("CN=Mow2")

distinguishedName
-----------------
{CN=Mow2,OU=MowOu,DC=mow,DC=local}



Note that it absolutely needed that you use a variable here as the User Will not be created until you call the CommitChanges Method, you can see that from the first output that the DN name is not yet filled, and if you throw it to the pipeline you can not call the commintChanges() Method, that why you need the variable for this.
OK, OK not completely you can do it also like this ;-) :

# Make an OU 
PoSH>($mowou.get_Children().add("OU=MowSubOu",'organizationalUnit')).CommitChanges()
PoSH>$mowou.get_Children().find("OU=MowSubOu")

distinguishedName
-----------------
{OU=MowSubOu,OU=MowOu,DC=mow,DC=local}


PoSH>



For the example above you can let PowerShell first evaluate what is in the parents and then call a method on it, also you can see how to do the same for an OU.

OK, Let's do not one user (as they still can say they do it quicker in the MMC GUI, and to have some users to test on in later parts of this series), let's do a 100 (for readability I did 5 here on the blog)and name them MowTest001 to MowTest100 and do not use a script but just go on from the commandline.

first lets count to 100, in PowerShell we have a nice range-operator ".." for this :


PoSH>1..5
1
2
3
4
5

Then we can use a pipeline and Foreach (by alias %) :

PoSH>1..5 |% {$_}
1
2
3
4
5


and then use a string and and the -F (format) operator in PowerShell, to format the numbers with trailing zeros and add them to a string, first the {0} inserts the first parameter, and then you can also use the .NET formatstrings to format them.


Jeffrey Snover did also a BlogEntry about it on the PowerShell here :
Using Format Control Strings.

For another example (formating as Percent) and some more formatting tricks in PowerShell see this post.

2006 Winter Scripting Games (part 2)

And here (as mentioned in that post also) you can find a good reference for formattingStrings in .NET :
(This is a different one from the one in Jeffrey Snovers's post with some more info !)
Standard Numeric Format Strings


I had some problems with this in the Demo (I turned string and parameter arround) so it might have not been that clear
in the Demo, on the other hand it shows how you can play with a line till you have it right by using the up arrow.( and it was cool for a time to call out : Jeffrey Help ! and he DOES show up to help me out LOL ;-))

# First insert the Number :

PoSH>1..5 |% {"MowTest{0}" -f $_}
MowTest1
MowTest2
MowTest3
MowTest4
MowTest5

# Format Number 

PoSH>1..5 |% {"MowTest{0:d3}" -f $_}
MowTest001
MowTest002
MowTest003
MowTest004
MowTest005


then if you get it right you can make a loop and use the History of your commandsettings to add former commands to the loop, it might be a bit hard to show on paper but the trick was to open the loop, and walk back with the up arrow in you history, edit add former commands you did to the loop, then close it with }[enter][enter] (you need a blank line after it).


# if you add another foreach and curly braces open and press enter you get a >> Prompt

PoSH>1..5 |% {"MowTest{0:d3}" -f $_} |% {
>>

# Walk with upArrow to former line :

PoSH>1..5 |% {"MowTest{0:d3}" -f $_} |% {
>> $user = $mowou.get_Children().add("CN=Mow2",'User')

# Change it, and use DownArrow to walk to the CommitChangesline from history.

PoSH>1..5 |% {"MowTest{0:d3}" -f $_} |% {
>> $user = $mowou.get_Children().add("CN=$_",'User')
>> $user.CommitChanges()
>> }
>>

# Now the items are created.

PoSH>$mowou.get_Children()

distinguishedName
-----------------
{CN=$_,OU=MowOu,DC=mow,DC=local}
{CN=AWu0001,OU=MowOu,DC=mow,DC=local}
{CN=AWu0290,OU=MowOu,DC=mow,DC=local}
{CN=mow,OU=MowOu,DC=mow,DC=local}
{CN=Mow2,OU=MowOu,DC=mow,DC=local}
{OU=MowSubOu,OU=MowOu,DC=mow,DC=local}
{CN=MowTest001,OU=MowOu,DC=mow,DC=local}
{CN=MowTest002,OU=MowOu,DC=mow,DC=local}
{CN=MowTest003,OU=MowOu,DC=mow,DC=local}
{CN=MowTest004,OU=MowOu,DC=mow,DC=local}
{CN=MowTest005,OU=MowOu,DC=mow,DC=local}
{CN=test,OU=MowOu,DC=mow,DC=local}



B.T.W. if you where at the demo from this output you can get what went wrong the first time trying to create them :
I made the first user like this :

$user = $mowou.get_Children().add('CN=Mow2','User')

working correct at the time, but not when I did change it to $mowou.get_Children().add('CN=$_','User') in the loop.

What went wrong ?

As we did create 100 Users, but there is a bit more work to be done (filling properties and Enable them for example),
I will get on to that in the next post, and to format and list the created objects, also You might have noticed the examples in the Adam post where a bit different, I will explain why also in the next post, after that we will look at taking import for SQL or CSV for example and searching AD.

Enjoy,

Greetings /\/\o\/\/
Tags :


Comments:
Anonymous Anonymous
Awesome stuff. Thanks MOW!

Jeffrey Snover
Windows PowerShell Architect
 
Blogger Jeffery Hicks
This is helpful and timely stuff as I'm wrapping up the new Powershell book with Don Jones. One thing I can't get to work though is setting a password. I also need to be able to set the sAMAccountname, but I think I've figured that out. Without the password and sAMAccountname an Active Directory user account doesn't do much. I know you're using ADAM but I hope you can address the password issue.
 
Blogger /\/\o\/\/
I did my Demo on a DC (VM) as ADAM is not as handy to work with as AD.

to give another preview to part 3 :

You can set the Password Like This :

$mow = $ou.get_Children().find('cn=mow')
$mow.Invoke("SetPassword","P@ssW0Rd")
$mow.CommitChanges()

Greetings /\/\o\/\/
 
Blogger Jeffery Hicks
I was using a command very much like that. I'll try it again. I was getting an error committing the change.
 
Blogger /\/\o\/\/
Did you first try the set_password method from the Directory entry.

or have you got other changes pending ?

try to get the user again and set only the password, hope this helps, I try to post the next part tomorrow.

Greetings /\/\o\/\/
 
Blogger Jeffery Hicks
It was late and I was tired when I was working on this. You were right. I hadn't comitted all the changes before setting the password. I was following the same concept as an ADSI VBScript but got a little lost in all the .NET.

Thanks.
 
Post a Comment



<< 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?