update folder permissions from CSV file

Hi I'm migrating home drives from one of our legacy Domains to our new Domain.  I have made a copy of the data to the new file server (Netapp) and am keeping the data in sync until we start cutting over users to use the new environment.

The problem I have is that the user accounts in the old environment don't match the user accounts in the new environment.  In the old Domain the user accounts are first name followed by first initial of surname; whereas in the new environment accounts are the first name and surname of the user in full.

I have been provided a CSV file with the following information:

Old Domain Account                                     Full Name        Staff ID
            
Joe Bloggs (oldDomain\Joeb)                    Joe Bloggs        1234
John Smith (oldDomain\johns)                John Smith        1235


I would like to use this information to do a powershell script to add the user accounts from the new domain for each user to their respective home drive folder.

I think the logic would go something like this:

1. each user home folder has the same name as the users account in the old domain.
2. for each user home folder, see if there is a match in the "old domain account" column of my CSV file.
3. if a match is found grant full control permissions to the user listed in the "full name" column, prefix'd with the name of my new domain (e.g. newDomain\Joe Bloggs)
 4.  finally rename users home folder to match their Staff ID.

So far all I've managed to do is read the names of the user home folders:

Get-ChildItem \\my file server\user_folders -Name -Attributes D

Open in new window


and read the "old domain account" column from the CSV file:

 
$sheetRead = Import-Csv -Path H:\Scripts\data_migration\Homedrive.csv | Select-Object "old domain accountt" | Out-String

Open in new window


Any help appreciated.  Thanks.
carbonbaseAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

footechCommented:
Give this a shot.  I haven't tested but I think it's all correct.  I included a minimum of Write-Host commands to output values to verify their value, but more could be added as necessary.
$rights = [System.Security.AccessControl.FileSystemRights]::FullControl
$inheritance = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit,ObjectInherit"
$propagation = [System.Security.AccessControl.PropagationFlags]::None
$allowdeny = [System.Security.AccessControl.AccessControlType]::Allow

# Customize the domain name
$newDomain = "domain"

$sheetRead = Import-Csv -Path H:\Scripts\data_migration\Homedrive.csv
$oldNames = $sheetRead | % { (($_."Old Domain Account") -split "\\").TrimEnd(")") }
Get-ChildItem "\\my file server\user_folders" -Name -Attributes D | Where { $oldNames -contains $_.Name } | ForEach `
{
    $sheetRead | ForEach `
    {
        $oldUserName = ((($_."Old Domain Account") -split "\\").TrimEnd(")"))
        If ( $oldUserName -eq $_.Name )
        {
            $newUserName = (($_."Full Name") -split " ") -join ""
            Write-Host "New user name is: $newUserName" -ForegroundColor Yellow
            $Account = [System.Security.Principal.NTAccount]"$newDomain\$newUserName"
            $Acl = Get-Acl $_.FullName
            $Ace = New-Object System.Security.AccessControl.FileSystemAccessRule ($Account,$rights,$inheritance,$propagation,$allowdeny)
            $Acl.AddAccessRule($Ace)
            Write-Host "Setting permission for folder: $($_.FullName)" -ForegroundColor Yellow
            Set-Acl $_.FullName -AclObject $Acl
            Write-Host "Renaming folder to: $($_."Staff ID")" -ForegroundColor Yellow
            Rename-Item -Path $_.FullName -NewName $_."Staff ID"
        }
    }
}

Open in new window

0
carbonbaseAuthor Commented:
Thanks for this, I'll test and let you know.
0
carbonbaseAuthor Commented:
Hi footech,

Sorry it's taken me so long to get back to you.  I've tried the script but it doesn't seem to run the foreach loop.  

I'm not sure about these statements:

$oldNames = $sheetRead | % { (($_."Old Domain Account") -split "\\").TrimEnd(")") }

and

$oldUserName = ((($_."Old Domain Account") -split "\\").TrimEnd(")"))
        If ( $oldUserName -eq $_.Name )

The statements above appear to be reading the first column of the CSV file "Old Domain Account" and removing the close bracket ")" from the end

e.g Joe Bloggs (oldDomain\Joeb)  becomes Joe Bloggs (oldDomain\Joeb

Shouldn't  these statements  remove everything apart from the username?
e.g. Joe Bloggs (oldDomain\Joeb)  becomes Joeb ?

Then the if statement can be used to match the username taken from the spreadsheet to a folder in the specified path with the same name?
0
Creating Active Directory Users from a Text File

If your organization has a need to mass-create AD user accounts, watch this video to see how its done without the need for scripting or other unnecessary complexities.

footechCommented:
Yes that what the statements should do.  That's the purpose of the -split and trimend together.  The statements are successful in getting just the username, but also the first part before the backslash.  So using the sample in your original question, the output from $oldNames would be
Joe Bloggs (oldDomain
Joeb
John Smith (oldDomain
johns

This part shouldn't actually impact the function of the script, but to make it cleaner the statement should be
$oldNames = $sheetRead | % { (($_."Old Domain Account") -split "\\")[-1].TrimEnd(")") }

Open in new window


Line 15 should be modified similarly (it would impact the function of the script).  I did spot some other problems later in the script which would cause it not to work.  Corrections below:
$rights = [System.Security.AccessControl.FileSystemRights]::FullControl
$inheritance = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit,ObjectInherit"
$propagation = [System.Security.AccessControl.PropagationFlags]::None
$allowdeny = [System.Security.AccessControl.AccessControlType]::Allow

# Customize the domain name
$newDomain = "domain"

$sheetRead = Import-Csv -Path H:\Scripts\data_migration\Homedrive.csv
$oldNames = $sheetRead | % { (($_."Old Domain Account") -split "\\")[-1].TrimEnd(")") }
Get-ChildItem "\\my file server\user_folders" -Name -Attributes D | Where { $oldNames -contains $_.Name } | ForEach `
{
    $folder = $_
    $sheetRead | ForEach `
    {
        $oldUserName = ((($_."Old Domain Account") -split "\\")[-1].TrimEnd(")"))
        If ( $oldUserName -eq $folder.Name )
        {
            $newUserName = (($_."Full Name") -split " ") -join ""
            Write-Host "New user name is: $newUserName" -ForegroundColor Yellow
            $Account = [System.Security.Principal.NTAccount]"$newDomain\$newUserName"
            $Acl = Get-Acl $folder.FullName
            $Ace = New-Object System.Security.AccessControl.FileSystemAccessRule ($Account,$rights,$inheritance,$propagation,$allowdeny)
            $Acl.AddAccessRule($Ace)
            Write-Host "Setting permission for folder: $($folder.FullName)" -ForegroundColor Yellow
            Set-Acl $folder.FullName -AclObject $Acl
            Write-Host "Renaming folder $($folder.Name) to: $($_."Staff ID")" -ForegroundColor Yellow
            Rename-Item -Path $folder.FullName -NewName $_."Staff ID"
        }
    }
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
carbonbaseAuthor Commented:
I don't think:

Get-ChildItem "\\my file server\user_folders" -Name -Attributes D | Where { $oldNames -contains $_.Name }

Open in new window


is returning anything.  

I'm not sure where the value for "$_.Name" is coming from?
0
carbonbaseAuthor Commented:
I think I understand now... "$_.Name" is supposed to be a value returned from "Get-ChildItem"

Doesn't look like the statement is working, even though I can see a folder called "joe bloggs" in the path "\\my file server\user_folders"

so if I run:

Get-ChildItem "\\my file server\user_folders" -Name -Attributes D

it returns a collection of folders including "joe bloggs" and the output of "$oldNames" is "joe bloggs"

but if I run:

Get-ChildItem "\\my file server\user_folders" -Name -Attributes D | Where { $oldNames -contains $_.Name }

nothing is returned
0
carbonbaseAuthor Commented:
if I change:

Where { $oldNames -contains $_.Name } 

Open in new window


to

Where { $oldNames -match $_.Name } 

Open in new window


the script gets further, but returns the name of all the folders from Get-ChildItem not just the name of the folder we are testing for.
0
footechCommented:
Ahh, I missed that you had the -Name parameter with Get-ChildItem when I copied that bit from your original question.  You will need to remove that.
0
carbonbaseAuthor Commented:
Works great now thanks!

I'm a little unclear about the reason for removing the "-Name" parameter.  Is that "-Attributes D" returns a number of parameters relating to the folder object which is then stored in an array and then the name of the folder is then accessed by calling "$_.Name"?  So what does "get-ChildItem <path> -Name" return?
0
footechCommented:
When you use the -Name parameter, all that is returned are names.  It is the same as
gci c:\ | Select -expandProperty Name
# or
gci c:\ | % { $_.Name }

Since we want to make use of more than just the "name" property of each folder, it's better to return the full System.IO.DirectoryInfo object (with all of it's properties).
0
carbonbaseAuthor Commented:
Great, thanks again for the info.
0
carbonbaseAuthor Commented:
Hi, how do I check to see whether a user already has permission to the folder?  I need to run the script multiple times but I don't want the script to try and add permission to the user if the user already has permission to the folder.

I thought about maybe putting in an "if" statement around the line

$Acl = Get-Acl $folder.FullName

Open in new window


but haven't been able to work out how to do this.
0
carbonbaseAuthor Commented:
If I output the result of $Acl I can see a property call "Access" which lists all the user accounts that have access to the folder but I can't work out how access this property.
0
footechCommented:
You really should open a new question if you have any more questions regarding this.  When doing so, you can include a link to this question in the new one for reference.

This'll be the last time I make any modifications to the script in this question.  Thanks for understanding.
The following should work.
$rights = [System.Security.AccessControl.FileSystemRights]::FullControl
$inheritance = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit,ObjectInherit"
$propagation = [System.Security.AccessControl.PropagationFlags]::None
$allowdeny = [System.Security.AccessControl.AccessControlType]::Allow

# Customize the domain name
$newDomain = "domain"

$sheetRead = Import-Csv -Path H:\Scripts\data_migration\Homedrive.csv
$oldNames = $sheetRead | % { (($_."Old Domain Account") -split "\\")[-1].TrimEnd(")") }
Get-ChildItem "\\my file server\user_folders" -Attributes D | Where { $oldNames -contains $_.Name } | ForEach `
{
    $folder = $_
    $sheetRead | ForEach `
    {
        $oldUserName = ((($_."Old Domain Account") -split "\\")[-1].TrimEnd(")"))
        If ( $oldUserName -eq $folder.Name )
        {
            $newUserName = (($_."Full Name") -split " ") -join ""
            Write-Host "New user name is: $newUserName" -ForegroundColor Yellow
            $Account = [System.Security.Principal.NTAccount]"$newDomain\$newUserName"
            $Acl = Get-Acl $folder.FullName
            $Acl.Access | ForEach `
            {
                If ( $_.IdentityReference -like "*$newUserName" )
                { $exists = $true }
            }
            If ( !($exists) )
            {
                $Ace = New-Object System.Security.AccessControl.FileSystemAccessRule ($Account,$rights,$inheritance,$propagation,$allowdeny)
                $Acl.AddAccessRule($Ace)
                Write-Host "Setting permission for folder: $($folder.FullName)" -ForegroundColor Yellow
                Set-Acl $folder.FullName -AclObject $Acl
                Write-Host "Renaming folder $($folder.Name) to: $($_."Staff ID")" -ForegroundColor Yellow
                Rename-Item -Path $folder.FullName -NewName $_."Staff ID"
            }
            Else
            { Write-Host "Skipping folder $($folder.Name)" -ForegroundColor Cyan }
        }
    }
}

Open in new window

0
carbonbaseAuthor Commented:
Yes I'm sorry I should have done that, wasn't deliberate, was just in a hurry and and couldn't work out how to ask a follow up question without copying the background again.  

Thanks for getting back so quickly with a solution.  I've also cobbled together something which seems to work as well:

$Acl = Get-Acl $folder.FullName 

            $newAcl = @((Get-Acl $folder.FullName).Access | Select-Object -ExpandProperty IdentityReference)

            If ($newAcl -Contains $Account)    
            {
                Write-Host  "User account already has permission: " $Account
            }         
            Else
           {
              # Continue to run my code....
           }

Open in new window


Powershell can be such hard work sometimes.... :-(
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.