This blog has moved to http://ThePowerShellGuy.com
Greetings /\/\o\/\/
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 StringsI 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 : Monad msh PowerShell