Powershell script to copy ACL Permission from source folder structure to target folder structure

Please provide a sample Powershell script to copy NTFS ACL Permissions from a master source folder with its subfolder structure to a target folder which has an identical subfolder structure

Source structure will have different permissions at different subfolder levels and some special permissions set on certain specific default files located in the structure

$SourceFoolder = "S:\Master Project"
$TargetFolder = "S:\3000\3010 Project"
ARamptonAsked:
Who is Participating?
 
ARamptonAuthor Commented:
I have totally failed to get robocopy to copy just permissions to target folders with /e /secfix /copy:s /is - /copyall will copy files and folders which I don't want

Thanks for the Powershell script - the one I have now used seems a little simpler and I understand its components

This copies ACL Permissions from Source to Target item by item (included folders and files)

$SFolder = "S:\SourceFolder"
$TFolder = "S:\3060\3078 Test Project 8"     'Targert Folder

$SFolderList = get-childitem -name $SFolder -recurse
foreach ($Folder in $SFolderList) {
          $SFullPath = $SFolder + "\" + "$Folder"
          $TFullPath = $TFolder + "\" + "$Folder"
      $NewACL = Get-ACL "$SFullPath"
Set-ACL "$TFullPath" $NewACL
echo "ACL copied to $TFolder $Folder"
}
0
 
SubsunCommented:
You can find the sample codes from following question. Check and let us know if you have any additional questions..
http://www.experts-exchange.com/Programming/Languages/Scripting/Powershell/Q_28305158.html

Other option which you can try is the Copy-Acl function. Please see the following article for more details..
http://blogs.msdn.com/b/powershell/archive/2009/05/11/copy-acl.aspx
0
 
ARamptonAuthor Commented:
First suggestion does not work recursively through a source structure

Second link is useful but I ma not yet skilled enough to modify this recursive script to achieve what I want
0
Simplify Active Directory Administration

Administration of Active Directory does not have to be hard.  Too often what should be a simple task is made more difficult than it needs to be.The solution?  Hyena from SystemTools Software.  With ease-of-use as well as powerful importing and bulk updating capabilities.

 
SubsunCommented:
Recursively means, you need set the permission at top level and enable the inheritance right?
0
 
ARamptonAuthor Commented:
I mean each and every source subfolder permission is mirrored to its matching target subfolder

The same with any files in the source structure
0
 
SubsunCommented:
Okie.. I didn't test the code.. Check it and let me know if it works for you..
$SourceFoolder = "S:\Master Project"
$TargetFolder = "S:\3000\3010 Project"

$TFolders = GCI $TargetFolder -Recurse | Select -ExpandProperty Fullname

GCI $SourceFoolder -Recurse | % {
	$SPath = $_.FullName
	$TPath = $_.FullName -replace "$($SourceFoolder.replace("\","\\"))","$TargetFolder"
	If ($TFolders -ccontains $TPath){
		Try{
		Set-Acl -Path $TPath -AclObject (Get-Acl $SPath) -EA Stop
		Echo "Copied permission from $SPath to $TPath"
		}Catch{
		Echo "Error on copying permission from $SPath to $TPath : $($_.Exception.Message)"
		}
	} Else{
	Echo "Unable to find destination for $SPath"
	}
}

Open in new window

0
 
ReceptCommented:
Does this solution have to be in Powershell? Robocopy will work just fine and is pre-installed on Windows Vista/2008+

robocopy.exe "S:\Master Project" "S:\3000\3010 Project" /E /COPYALL

Open in new window


Or run from within Powershell

$SourceFoolder = "S:\Master Project"
$TargetFolder = "S:\3000\3010 Project" 
&robocopy.exe $SourceFoolder $TargetFolder /E /COPYALL

Open in new window

0
 
SubsunCommented:
Looking at your script, I expect some functional problems to get expected result. But if it is working for you then good!
0
 
ARamptonAuthor Commented:
I agree my script has no error checking yet, I will learn from your sample code

Please can you explain the function/operation of your line

      $TPath = $_.FullName -replace "$($SourceFoolder.replace("\","\\"))","$TargetFolder"
0
 
SubsunCommented:
With following source and destination folders..

$SFolder = "S:\SourceFolder"
$TFolder = "S:\3060\3078 Test Project 8"

$_.FullName -replace "$($SourceFoolder.replace("\","\\"))","$TargetFolder"
The line actually take the FullName of the source  file or folder and convert it in to destination folder name..

S:\SourceFolder\folder1\test.txt will be converted to
S:\3060\3078 Test Project 8\folder1\test.txt

S:\SourceFolder\folder1\Folder2\testfolder to
S:\3060\3078 Test Project 8\folder1\Folder2\testfolder

Regarding your script, I was not talking about error control..

With our example, S:\SourceFolder\folder1\Folder2\testfolder as source folder..

In your code "$Folder" will have value 'testfolder' (Name of the folder processed by foreach), so with following code

$SFullPath = $SFolder + "\" + "$Folder"
$TFullPath = $TFolder + "\" + "$Folder"

$SFullPath will be S:\SourceFolder\testfolder  &

$TFullPath will be C:\dest\testfolder

Ideally the source is S:\SourceFolder\folder1\Folder2\testfolder and destination would be S:\3060\3078 Test Project 8\folder1\Folder2\testfolder (Since you said you have the exact same folder structure)

But it may work if you don't have more than one level deep folder structure as i mentioned in my example.. Hope it's clear..
0
 
ARamptonAuthor Commented:
Thanks for your guidance

I  think your use of the line below is very powerful so I would appreciate more information on how it actually works so I can construct similar transpositions myself

$_.FullName -replace "$($SourceFoolder.replace("\","\\"))","$TargetFolder"
0
 
SubsunCommented:
I have used -replace operator to construct the target path…

$SourceFoolder = "S:\Master Project"
$TargetFolder = "S:\3000\3010 Project"


$TPath = $_.FullName -replace "$($SourceFoolder.replace("\","\\"))","$TargetFolder"

Open in new window

So in above example, if we replace the variables with their values (just to show you how it works) then you will get the following command..
"S:\Master Project\folder1\test.txt" -replace "S:\\Master Project","S:\3000\3010 Project"

Open in new window

Hence the source file full name will be converted to
S:\3000\3010 Project\folder1\test.txt

You can refer the following article to know more about replacing strings in PowerShell..
http://blogs.technet.com/b/heyscriptingguy/archive/2011/03/21/use-powershell-to-replace-text-in-strings.aspx
0
 
ARamptonAuthor Commented:
Subsun, I understand the -replace function now but don't yet comprehend its second use ($SourceFoolder.replace("\","\\")) in the line below

$TPath = $_.FullName -replace "$($SourceFoolder.replace("\","\\"))","$TargetFolder"

I think it is trying to change "\" to "\\" but don't understand why or the .replace format

Some further guidance would be very helpful
0
 
SubsunCommented:
-Replace uses regex pattern replacement that's why first I had to convert the Source Folder name single slashes to double slashes using $SourceFoolder.replace("\","\\"). \\ is interpreted as a regex that matches a single backslash (escaped backslash).
BTB, In our scenario, I think the following code also give the same result..
$TPath = $_.FullName.replace($SourceFoolder,"$TargetFolder")

Open in new window

Let me know if you have any further questions..
0
 
ARamptonAuthor Commented:
Own solution seemed more understandable to me but much appreciate more advanced choice
0
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.

All Courses

From novice to tech pro — start learning today.