• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 192
  • Last Modified:

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.
0
carbonbase
Asked:
carbonbase
  • 10
  • 5
2 Solutions
 
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
Who's Defending Your Organization from Threats?

Protecting against advanced threats requires an IT dream team – a well-oiled machine of people and solutions working together to defend your organization. Download our resource kit today to learn more about the tools you need to build you IT Dream Team!

 
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
 
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

Featured Post

Evaluating UTMs? Here's what you need to know!

Evaluating a UTM appliance and vendor can prove to be an overwhelming exercise.  How can you make sure that you're getting the security that your organization needs without breaking the bank? Check out our UTM Buyer's Guide for more information on what you should be looking for!

  • 10
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now