Friday, September 30, 2011

PowerShell for Creating Secure User Folders via AD

Today I needed to create a user folder structure for every non-disabled user in a specific Active Directory OU (and sub-OUs).  The folders needed to match the username exactly, and have security so that the user has modify permissions, and Domain Admins have full control - no other permissions!  Sounds simple, until you consider that there are hundreds of users.

I found a few PowerShell examples online, but nothing that I found could do everything I needed, so I tweaked and modified until I came up with these two simple scripts.

To start with, I manually created a base folder (in my example, named PSTs, sigh..).  I gave Domain Users read-only permission and Domain Admins full control of this folder.  No other permissions were present on this folder - if there are other permissions on your base folder, the permissions portion of this script will not work properly for you.

The first script just prints a list of usernames found in Active Directory (under the OU you specify) to the screen:


$strFilter = "(&(objectCategory=User)(!userAccountControl:1.2.840.113556.1.4.803:=2))"


$objDomain = New-Object System.DirectoryServices.DirectoryEntry("LDAP://OU=YourOU,dc=YourDomain,dc=local")


$objSearcher = New-Object System.DirectoryServices.DirectorySearcher
$objSearcher.SearchRoot = $objDomain
$objSearcher.PageSize = 1000
$objSearcher.Filter = $strFilter
$objSearcher.SearchScope = "Subtree"


$colProplist = "samaccountname"
foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)}


$colResults = $objSearcher.FindAll()


foreach ($objResult in $colResults)
    {$objItem = $objResult.Properties; $objItem.samaccountname}

This first script searches all OUs underneath the OU specified by the LDAP:// line for user accounts that are not disabled (the userAccountControl:1.2.840.113556.1.4.803:=2 identifier specifies disabled users), then pulls the sAMAccountName attribute and prints it to the screen.  This gives us a list of all the non-disabled usernames we need.


Copy this list and paste it into a text file, so that there is one username per line (just a simple copy paste).


Run the following script against the text file, and your directories will be created with the permissions discussed above:



$users = Get-Content "C:\userlist.txt"
ForEach ($user in $users)
{
$newPath = Join-Path "C:\PSTs" -childpath $user
New-Item $newPath -type directory


$acl = Get-Acl $newpath
$acl.SetAccessRuleProtection($true,$true)
$acl | Set-Acl $newpath


$acl = Get-Acl $newPath
# This removes all access for the group in question
$group = "YourDomain\Domain Users"
$acl.Access |where {$_.IdentityReference -eq $group} |%{$acl.RemoveAccessRule($_)}


$account="POMONACH.LOCAL\$user"
$rights=[System.Security.AccessControl.FileSystemRights]::Modify
$inheritance=[System.Security.AccessControl.InheritanceFlags]"ContainerInherit,ObjectInherit"
$propagation=[System.Security.AccessControl.PropagationFlags]::None
$allowdeny=[System.Security.AccessControl.AccessControlType]::Allow

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


$acl.SetAccessRule($accessRule)
$acl | Set-Acl $newpath
}

This will set create the user folders, remove security inheritance, and remove Domain Users from the security tab.  It will also add the user to the security tab with modify permissions.  I'm not a PowerShell expert, so there are some parts here that I don't quite "get", even though I wrote some of it, but I get the general idea and it worked for me!