Solved

update folder permissions from CSV file

Posted on 2014-10-02
15
168 Views
Last Modified: 2014-11-14
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.
0
Comment
Question by:carbonbase
  • 10
  • 5
15 Comments
 
LVL 39

Expert Comment

by:footech
ID: 40358521
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
 

Author Comment

by:carbonbase
ID: 40363454
Thanks for this, I'll test and let you know.
0
 

Author Comment

by:carbonbase
ID: 40377252
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
 
LVL 39

Accepted Solution

by:
footech earned 500 total points
ID: 40377497
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
 

Author Comment

by:carbonbase
ID: 40379568
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
 

Author Comment

by:carbonbase
ID: 40379636
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
 

Author Comment

by:carbonbase
ID: 40379923
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
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 39

Assisted Solution

by:footech
footech earned 500 total points
ID: 40380365
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
 

Author Closing Comment

by:carbonbase
ID: 40386729
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
 
LVL 39

Expert Comment

by:footech
ID: 40387014
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
 

Author Comment

by:carbonbase
ID: 40399606
Great, thanks again for the info.
0
 

Author Comment

by:carbonbase
ID: 40442427
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
 

Author Comment

by:carbonbase
ID: 40442431
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
 
LVL 39

Expert Comment

by:footech
ID: 40442488
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
 

Author Comment

by:carbonbase
ID: 40442566
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

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Synchronize a new Active Directory domain with an existing Office 365 tenant
This article explains how to prepare an HTML email signature template file containing dynamic placeholders for users' Azure AD data. Furthermore, it explains how to use this file to remotely set up a department-wide email signature policy in Office …
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now