/\/\o\/\/ PowerShelled

This blog has moved to http://ThePowerShellGuy.com Greetings /\/\o\/\/
$AtomFeed = ("Atom.xml")
$PreviousItems = (" PowerShell and Active Directory Part 6 "," Windows PowerShell Video: Next Generation Command ... "," PowerShell and Active Directory Part 5 "," PowerShell and Active Directory Part 4 (TypeData) "," PowerShell and MOM2005 part 2 : Updating Settings "," PowerShell Boolean FileMode "," Working with Fixed Length delimited Text files in ... "," PowerShell and Active Directory Part 3 (UserProper... "," PowerShell and MOM 2005 "," PowerShell and Active Directory Part 2 "," ")

Wednesday, August 09, 2006

 


PowerShell and Active Directory Part 7



*Warning* As you have RC2 Installed all my AD posts will not work anymore, it is verry confusing, but fixable if you read explaination here PowerShell RC2 and Active Directory :


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.


In this seventh part of this AD series, we will expand the filter a little,but first we need to provide the properties,so we need to fill the CSV file a bit more with the fields needed.
You can just start-up excel to edit it but here I will use some more powershell onliners to fill them from the results of the export I did of some of the users I created from the adventureworks sample DB for my demosetup and did export in in PowerShell and Active Directory Part 5 , I did place get content to show what the current content is and will go on from there, using the onliners on the commandline to fill them, but you can also use the Ken Meyer user we created also in that post with the MMC and exported that onle is allready complete(for now). for more about CSV handling see more Monad scripts, and a bit more CSV and the links there for my CSV series.

# use invoke-item (ii) to invoke Excel to edit 

PoSH>ii modUsers.csv

# the file with six test users i have now

PoSH>cat modUsers.csv
Name,displayName,Description,Room,Telephone,FirstName,Initials,LastName,Department,Company,HomeDir,HomeDrive,LogonScript,Accountname,Mai

l,OU
NewUser0003,"Roberto  Tamburello","Engineering - Roberto  Tamburello",,,Roberto,,Tamburello,Engineering,,,,,,,
NewUser0009,"Gail A Erickson","Engineering - Gail A Erickson",,,Gail,,Erickson,Engineering,,,,,,,
NewUser0011,"Jossef H Goldberg","Engineering - Jossef H Goldberg",,,Jossef,,Goldberg,Engineering,,,,,,,
NewUser0012,"Terri Lee Duffy","Engineering - Terri Lee Duffy",,,Terri,,Duffy,Engineering,,,,,,,
NewUser0267,"Michael I Sullivan","Engineering - Michael I Sullivan",,,Michael,,Sullivan,Engineering,,,,,,,
NewUser0270,"Sharon B Salavaria","Engineering - Sharon B 

Salavaria",,,Sharon,,Salavaria,Engineering,,,,,,,"OU=MowOtherOU,DC=mow,DC=local"

# set some properties

PoSH>$newusers |% {$_.HomeDir = "H:"}
PoSH>$newusers |% {$_.Company = "PoSH works"}
PoSH>$newusers |% {$_.LogonScript = "Logon.cmd"}
PoSH>$newusers |% {$_.HomeDrive = "H:"}
PoSH>$newusers |% {$_.HomeDir = "\\mowdc001\home$\$($_.name)"}

# show first user

PoSH>$newusers[0]


Name        : NewUser0003
displayName : Roberto  Tamburello
Description : Engineering - Roberto  Tamburello
Room        :
Telephone   :
FirstName   : Roberto
Initials    :
LastName    : Tamburello
Department  : Engineering
Company     : PoSH works
HomeDir     : H:
HomeDrive   : \\mowdc001\home$\NewUser0003
LogonScript : Logon.cmd
Accountname :
Mail        :
OU          :

# fill some rooms

PoSH>1..3 |% {$newUsers[$_].room = "room $_"}

# try some formating on the mailaddress

PoSH>$newUsers |% {"{0}.{1}@Mowmail.com" -f $_.Firstname,$_.LastName}
Roberto.Tamburello@Mowmail.com
Gail.Erickson@Mowmail.com
Jossef.Goldberg@Mowmail.com
Terri.Duffy@Mowmail.com
Michael.Sullivan@Mowmail.com
Sharon.Salavaria@Mowmail.com

PoSH>$newUsers |% {"{0}.{1}@Mowmail.com" -f $_.Firstname.Substring(0,1),$_.LastName}
R.Tamburello@Mowmail.com
G.Erickson@Mowmail.com
J.Goldberg@Mowmail.com
T.Duffy@Mowmail.com
M.Sullivan@Mowmail.com
S.Salavaria@Mowmail.com

# fill that also

PoSH>$newUsers |% {$_.mail = ("{0}.{1}@Mowmail.com" -f $_.Firstname.Substring(0,1),$_.LastName)}

PoSH>$newUsers | ft name,room,mail -a

Name        Room   Mail
----        ----   ----
NewUser0003        R.Tamburello@Mowmail.com
NewUser0009 room 1 G.Erickson@Mowmail.com
NewUser0011 room 2 J.Goldberg@Mowmail.com
NewUser0012 room 3 T.Duffy@Mowmail.com
NewUser0267        M.Sullivan@Mowmail.com
NewUser0270        S.Salavaria@Mowmail.com


Ok enough CSV handling and looping tricks, lets get back AD that we are here fore and to the script to create.

In the following script I addded the following :

- Displayname
I did work out 3 possiblities for that,
1 it was given in the CSV file, so we just fill it
2 It was not given but we have a firstname and lastname so we generate it (as the MMC does)
3 displayname first and last name or not given set it to the name
- Some other otional properties
- if homeDirectory is given the Creating of homedirectories (as the MMC does)
- setting the initial password
- useraccount control to 512 (default) to setenabled (see former posts)

the filter now looks like this :

filter new-AdUser ([System.DirectoryServices.DirectoryEntry]$importOU){ 

  # check for name field : 

  if ($_.Name) {$CN= $_.name} Else {throw "Name is Mandatory"

  # Use default OU or connect to OU given in CSV file  

  if ($_.OU) { 
      $OU = new-object System.DirectoryServices.DirectoryEntry("LDAP://$($_.OU)"
  }  
  Else { 
      $OU = $ImportOU 
  } 

  # create the new user : 
  Write-host -fore "Yellow" "Creating $($_.name)"

  $NewUser = $ou.get_Children().add("CN=$($_.name)",'user'
  $NewUser.commitChanges() 

  # If accountname is not given make it same as CN 

  if ($_.Accountname) {$newUser.sAMAccountName = $_.Accountname} Else {$newUser.sAMAccountName = $_.name} 
  $NewUser.commitChanges() 

  # Process DisplayName

  if ($_.DisplayName) {
    # displayname given so use that
    $newUser.DisplayName = $_.DisplayName
  }
  ElseIf ($_.firstname -and $_.lastname) {
    # no displayname but lastname and firstname given generate Displayname
    $newUser.DisplayName = "$($_.LastName), $($_.FirstName) $($_.Initials)"
  }
  Else {
    # just use the UserName
    $newUser.DisplayName = $_.Name
  }

  # Fill Other Properties if given :

  if ($_.Firstname) {$newUser.GivenName = $_.Firstname}
  if ($_.Lastname) {$newUser.SN = $_.LastName}
  if ($_.Initials) {$newUser.Initials = $_.Initials}

  if ($_.Description) {$newUser.Description = $_.Description}
  if ($_.Room) {$newUser.physicalDeliveryOfficeName = $_.Room}
  if ($_.Telephone) {$newUser.telephoneNumber = $_.Telephone}
  if ($_.Department) {$newUser.Department = $_.Department}
  if ($_.Mail) {$newUser.Mail = $_.Mail}
  if ($_.HomeDrive) {$newUser.HomeDrive = $_.HomeDrive}
 
  # Fill HomeDir and try to create the folder

  if ($_.HomeDir) {
    $newUser.homeDirectory = $_.HomeDir

    # check if homeDir does exist, and if its possible to create

    if (Test-Path $_.HomeDir) {
      "HomeDir Does Exist"
    }
    Else {
      if (split-Path $_.HomeDir -Parent) {
        "Parent Found, Share $($_.HomeDir) can be created"
        $ud = md $_.HomeDir
        $ar = new-object Security.AccessControl.FileSystemAccessRule($_.name,'Modify, Synchronize','ContainerInherit, ObjectInherit','none','Allow')
        $ac = $ud.GetAccessControl()
        $ac.AddAccessRule($ar)
        Set-Acl $ud $ac
      }
      Else{
        "$(split-Path $_.HomeDir -Parent) not Found, Create share Manual"
      }
    }
  }

  if ($_.LogonScript) {$newUser.scriptPath = $_.LogonScript}

  # set initial password and force user to change it at first logon

  $newUser.Invoke("SetPassword","P@ssW0Rd")
  $newUser.pwdLastSet = 0

  # Enable User
  $newUser.userAccountControl = 512

}


note that as this is a filter not a script or function yet so all the code gets executed for every record,
we will change that in next post as for the other things I want to do I want to add some code that will only run once,
and we will add some more properties and errorhandling you will see the differance and use of this in next post also and work on the output.

the output looks like this :

PoSH>$mowou.get_Children() |? {$_.name -like "NewUser*"} |% {$mowou.get_Children().Remove($_)}
PoSH>$newusers | new-aduser $mowou

Creating NewUser0003
Parent Found, Share \\mowdc001\home$\NewUser0003 can be created
Creating NewUser0009
Parent Found, Share \\mowdc001\home$\NewUser0009 can be created
Creating NewUser0011
Parent Found, Share \\mowdc001\home$\NewUser0011 can be created
Creating NewUser0012
Parent Found, Share \\mowdc001\home$\NewUser0012 can be created
Creating NewUser0267
Parent Found, Share \\mowdc001\home$\NewUser0267 can be created
Creating NewUser0270
Parent Found, Share \\mowdc001\home$\NewUser0270 can be created

# only the basic errorhandling (270 user allready exists)

PoSH>$mowou.get_Children() |? {$_.name -like "NewUser*"} |% {$mowou.get_Children().Remove($_)}
PoSH>$newusers | new-aduser $mowou

Creating NewUser0003
HomeDir Does Exist
Creating NewUser0009
HomeDir Does Exist
Creating NewUser0011
HomeDir Does Exist
Creating NewUser0012
HomeDir Does Exist
Creating NewUser0267
HomeDir Does Exist
Creating NewUser0270
Exception calling "CommitChanges" with "0" argument(s): "The object already exists. (Exception from HRESULT: 0x80071392
)"
At line:14 char:25
+   $NewUser.commitChanges( <<<< )
Exception setting "sAMAccountName""A constraint violation occurred. (Exception from HRESULT: 0x8007202F)"
At line:16 char:81
+   if ($_.Accountname) {$newUser.sAMAccountName = $_.Accountname} Else {$newUser.s <<<< AMAccountName = $_.name}
Exception calling "CommitChanges" with "0" argument(s): "A constraint violation occurred. (Exception from HRESULT: 0x80
07202F)"
At line:17 char:25
+   $NewUser.commitChanges( <<<< )
Exception setting "DisplayName""A constraint violation occurred. (Exception from HRESULT: 0x8007202F)"
At line:21 char:14
+     $newUser.D <<<< isplayName = $_.DisplayName
Exception setting "GivenName""A constraint violation occurred. (Exception from HRESULT: 0x8007202F)"
At line:32 char:31
+   if ($_.Firstname) {$newUser.G <<<< ivenName = $_.Firstname}
Exception setting "SN""A constraint violation occurred. (Exception from HRESULT: 0x8007202F)"
At line:33 char:30
+   if ($_.Lastname) {$newUser.S <<<< N = $_.LastName}

# and the result 

PoSH>$mowou.get_Children() |? {$_.cn -match 'NewUser'} | format-aduser | ft

Name        displayName Description Room        Telephone   FirstName   Initials    LastName    Department  Company
----        ----------- ----------- ----        ---------   ---------   --------    --------    ----------  -------
NewUser0003 Roberto ... Engineer... {}          {}          Roberto     {}          Tamburello  Engineering {}
NewUser0009 Gail A E... Engineer... room 1      {}          Gail        {}          Erickson    Engineering {}
NewUser0011 Jossef H... Engineer... room 2      {}          Jossef      {}          Goldberg    Engineering {}
NewUser0012 Terri Le... Engineer... room 3      {}          Terri       {}          Duffy       Engineering {}
NewUser0267 Michael ... Engineer... {}          {}          Michael     {}          Sullivan    Engineering {}


PoSH>($mowou.get_Children() |? {$_.cn -match 'NewUser'} | format-aduser)[0]

Name        : NewUser0003
displayName : Roberto  Tamburello
Description : Engineering - Roberto  Tamburello
Room        : {}
Telephone   : {}
FirstName   : Roberto
Initials    : {}
LastName    : Tamburello
Department  : Engineering
Company     : {}
HomeDir     : \\mowdc001\home$\NewUser0003
HomeDrive   : H:
LogonScript : Logon.cmd
Accountname : NewUser0003
Mail        : R.Tamburello@Mowmail.com


Note that I made one user in another OU and did not delete that user, every line will give his own error and everything is still triedand will fail we work on that also in next post, as for large numbers this is not handy but for a couple of users this doable.
I think all the AD stuff was covert in former posts, so I won't explain that again here and the rest of the filter is straight forward I think, except for setting the security on the directory I covert this before in this post :Adding a Simple AccesRule to a file ACL in MSH and see the links in there for more info, so this is it for now.

Enjoy,

greetings /\/\o\/\/
Tags :


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