A major part of our transition at work from a Novell Netware backend to Microsoft Windows Server 2008 R2 involved provisioning user accounts in Active Directory and fleshing out all the individual accounts with profile paths and home directories.  Fortunately we didn’t have to create the accounts, as we had been running Novell Identity Manager for some time, populating AD with accounts from eDirectory, along with basic user information, but the existing home directory information was not going to be valid on the new backend filesystem (Server 2008 R2 DFS + highly-available file cluster) so we needed a way to bulk change the account information, create home directories for each user (approximately 1700 users) and assign permissions.

Time and budget didn’t allow us to bring in external parties or purchase third-party migration tools, so we made the decision to do the entire thing with PowerShell.

PowerShell is one of those things which has been kicking around for a while, but not that many Windows admins have had to get their hands dirty with it.  I certainly hadn’t, so was a complete PowerShell newbie.  As such, this is my first proper script and I’m rather stupidly proud of it.

  1. $csv=Read-Host "Enter Path to CSV"

  2. $users=Import-Csv $csv

  3. #Create Home Directories

  4. $users | ForEach-Object {mkdir($_.’HomeDirectory’)}

  5. #Assign Access Rights

  6. foreach ($user in $users)

  7. {

  8. $account="DOMAIN\"+$user.LoginName

  9. $homedir=$user.HomeDirectory

  10. $rights=[System.Security.AccessControl.FileSystemRights]::FullControl

  11. $inheritance=[System.Security.AccessControl.InheritanceFlags]"ContainerInherit,ObjectInherit"

  12. $propagation=[System.Security.AccessControl.PropagationFlags]::None

  13. $allowdeny=[System.Security.AccessControl.AccessControlType]::Allow

  14. $dirACE=New-Object System.Security.AccessControl.FileSystemAccessRule ($account,$rights,$inheritance,$propagation,$allowdeny)

  15. $dirACL=Get-Acl $homedir

  16. $dirACL.AddAccessRule($dirACE)

  17. Set-Acl $homedir $dirACL

  18. Write-Host $homedir access rights assigned

  19. }

Obviously there are bits and pieces of this script which are particular to my own environment, but it should adjust to any similar situation.  I was importing data from multiple CSVs which were populated by student year levels – we are a K-12 school so that’s fairly important information, and determines what the users have access to, and that data is easier to manipulate via CSV.  I also had to populate a lot of the home directory information so that the CSV was accurate.  The CSVs only contained login information and home directory fields from AD:

  1. Get-QADUser | Select-Object SamAccountName,HomeDirectory

So, if you don’t need to handle multiple groups of users, you could replace the $csv variables with a similar query rather than use a CSV.

In the CSV, SamAccountName and HomeDirectory were mapped to columns headed LoginName and HomeDirectory respectively.  No real reason, just what I was using at the time.  The home directory data was the full UNC path to the user’s home directory.  The assumption is that the path doesn’t already exist, but if it does then the mkdir section of the script which creates each folder will simply bring up a “file already exists” error and continue onto the next instance.

The tricky bit was assigning user permissions, which is why I needed the SamAccountName data.  The permissions are assigned using .NET security classes, but they do assume that the inherited permissions on each folder are already correct.  This script doesn’t overwrite the ACL or grant the user exclusive ownership over the home directory, but simply adds the user to the ACL with Full Control, and allows those rights to flow to child objects.  It basically replicates that same permissions you get when specifying a home directory for a user using the Active Directory Users and Computers snap-in.

For 1700 users this script took about two hours to run, but worked flawlessly and meant that when students came barrelling in the following week, they actually had somewhere to store their files :-)

Don Jones’ series of TechNet articles about automating user provisioning were invaluable in my research, as was the purchase of PowerShell Plus, at the recommendation of @leadfollowmove.  And no, I’m not getting any kickbacks from the company – I purchased it fair and square.  If you’re a PowerShell newbie, many of the problems you encounter in the early days come back to not knowing what it is that you don’t know.  PowerShell Plus gives you a really useful visual over what’s happening with your scripts and variables, as well as offering guidance on available options and query logic.  Saves a lot of hair-pulling and teeth-gnashing.

And NOW if the company would like to offer me some kickbacks, I’m sure I will be amenable…