SearchFAQMemberlist Log in
Reply to topic Page 1 of 1
Windows: backing up files the administrator cant read
Author Message
Post Windows: backing up files the administrator cant read 
Hello all,

I'm hoping to use rdiff-backup to perform backups on Windows retaining
full ACLs, including for files which the administrator cannot access.
Unlike on a POSIX system in which the superuser can access any files
regardless of the permissions set, on Windows it is possible to
restrict any user from accessing a file (though they can still take
ownership and obliterate the ACLs, so this provides no real security).

Since this makes backing up a multi-user system problematic, there is
also an option to have all files treated as readable regardless of the
actual ACLS, and this is enabled by default for Administrators.
Unfortunately, it doesn't work transparently in that it requires that
the program first request backup privileges, and then pass the right
flag to NtCreateFile.

On Cygwin (as of 1.7 at least) file access is wrapped to use the
backup permission all the time, restoring some level of sanity[0].
This allows all files to be backed up using rdiff-backup in Cygwin,
but Windows ACLs aren't preserved, and Windows ACLs don't map directly
onto POSIX ACLs so it looks like this won't be possible in Cygwin. The
native build of rdiff-backup seems to be able to backup and restore
ACLs, but it can't access quite a lot of my users' files, even when
run as the SYSTEM user.

Has anyone come across this issue before, and found a solution?
Alternatively, is there something I'm missing? If, as it seems, this
feature isn't present, is it something that could be added to
rdiff-backup itself (even via an ugly hack - I'm not picky Razz) or
would it require a custom Python build? I've had a quick look at the
code but it's fairly overwhelming at first glance, and I'm not sure at
what level the actual file opening is even done.

Thanks for your time,
Nye

[0] http://cygwin.com/ml/cygwin/2008-03/msg00663.html

_______________________________________________
rdiff-backup-users mailing list at rdiff-backup-users < at > nongnu.org
http://lists.nongnu.org/mailman/listinfo/rdiff-backup-users
Wiki URL: http://rdiff-backup.solutionsfirst.com.au/index.php/RdiffBackupWiki

Post Windows: backing up files the administrator cant read 
On Thu, May 20, 2010 at 15:02, Aneurin Price <aneurin.price < at > gmail.com> wrote:

I'm hoping to use rdiff-backup to perform backups on Windows retaining
full ACLs, including for files which the administrator cannot access.

...

On Cygwin (as of 1.7 at least) file access is wrapped to use the
backup permission all the time, restoring some level of sanity[0].
This allows all files to be backed up using rdiff-backup in Cygwin,
but Windows ACLs aren't preserved, and Windows ACLs don't map directly
onto POSIX ACLs so it looks like this won't be possible in Cygwin. The
native build of rdiff-backup seems to be able to backup and restore
ACLs, but it can't access quite a lot of my users' files, even when
run as the SYSTEM user.

Has anyone come across this issue before, and found a solution?

I didn't find a direct solution to this problem, however I found a
decent workaround: Windows versions since server 2003 SP2 come with a
utility called icacls[0] which can be used to back up and restore the
ACLs of a full filesystem tree, or whatever subset you specify -
rather like metastore[1] for Windows.

Nye

[0] http://support.microsoft.com/kb/919240
[1] http://david.hardeman.nu/software.php

_______________________________________________
rdiff-backup-users mailing list at rdiff-backup-users < at > nongnu.org
http://lists.nongnu.org/mailman/listinfo/rdiff-backup-users
Wiki URL: http://rdiff-backup.solutionsfirst.com.au/index.php/RdiffBackupWiki

Post Windows: backing up files the administrator cant read 
On Mon, May 24, 2010 at 11:59, Aneurin Price <aneurin.price < at > gmail.com> wrote:
On Thu, May 20, 2010 at 15:02, Aneurin Price <aneurin.price < at > gmail.com> wrote:

I'm hoping to use rdiff-backup to perform backups on Windows retaining
full ACLs, including for files which the administrator cannot access.

...

On Cygwin (as of 1.7 at least) file access is wrapped to use the
backup permission all the time, restoring some level of sanity[0].
This allows all files to be backed up using rdiff-backup in Cygwin,
but Windows ACLs aren't preserved, and Windows ACLs don't map directly
onto POSIX ACLs so it looks like this won't be possible in Cygwin. The
native build of rdiff-backup seems to be able to backup and restore
ACLs, but it can't access quite a lot of my users' files, even when
run as the SYSTEM user.

Has anyone come across this issue before, and found a solution?

I didn't find a direct solution to this problem, however I found a
decent workaround: Windows versions since server 2003 SP2 come with a
utility called icacls[0]  which can be used to back up and restore the
ACLs of a full filesystem tree, or whatever subset you specify -
rather like metastore[1] for Windows.


Aaaaand disregard that. This suffers from the same problem of not
being able to access certain files. It looks like the solution is
going to be to write (or find, though that's not going so well) a
custom tool to duplicate the behaviour of icacls but using backup
permissions.

_______________________________________________
rdiff-backup-users mailing list at rdiff-backup-users < at > nongnu.org
http://lists.nongnu.org/mailman/listinfo/rdiff-backup-users
Wiki URL: http://rdiff-backup.solutionsfirst.com.au/index.php/RdiffBackupWiki

Post This worked for me 
The only thing I found to work was SubInACL. Make sure that you have the 5.2.3790.1180 version because the earlier versions are broken and it must be run on a 32 bit environment. This means on 64 bit windows, run it in the 32 bit Powershell. This will allow you to take ownership of the file and change permissions. Here is a Powershell script I wrote to help copy some really messy directories.


#==============================================================================================
# NAME:    Copy-DirWithPerms.ps1
# AUTHOR:   Don Hess
# DATE:    2010-04-08
# REV:      1.0.0
# COMMENT: 
#
# REVISION:
# 1.0.0      Release
#
# TODO:
# SubinACL needs to have the output log file changed so that when you play it back, the perms
# are applied to the destination directory
# Simplify and compartmentalize so you can run robocopy or subinacl.
# More switches to allow subinacl to do backup and restore one directory or recursively.
#==============================================================================================

param   ( [string] $s       = "NA"
      , [string] $d       = "NA"   
      , [switch] $perms    = [switch]::$false
      , [switch] $rc       = [switch]::$false
      , [switch] $f       = [switch]::$false
      , [switch] $h       = [switch]::$false)   
      

[string] $strScriptName   = 'Copy-DirWithPerms.ps1';
[string] $script:datetimecolon   = Get-Date -uformat "%Y-%m-%d %I:%M:%S %p  TZ(%Z)";   # YYYY-MM-DD HH-MM-SS AM/PM  note the Powershell Get-Help Get-Date -full has the wrong letter abreviations to get the date we want, this will work instead
[string] $script:datetimeunder = Get-Date -uformat "%Y-%m-%d %I_%M_%S %p";   # YYYY-MM-DD HH-MM-SS AM/PM  note the Powershell Get-Help Get-Date -full has the wrong letter abreviations to get the date we want, this will work instead
[string] $script:cname    = ( Get-Content env:computername );
[string] $script:strUserPrincipalName = $env:USERNAME + "@" + $env:USERDNSDOMAIN;   # Get current user principal name

# Turn both switches on by default if nothing is specified.
if ( ($perms -eq $false) -and ($rc -eq $false) )
{   $perms = $true;  $rc = $true; }

# -h  help output
function helpme()
{   
    
    
     Write-Host "";
     Write-Host "     Copy a directory to a destination with all permissions intact.";
     Write-Host "";
     Write-Host "     Usage:";
     Write-Host "     $strScriptName -s <string> -d <string> [-rc] [-h]";
     Write-Host "";
     Write-Host "     Switches:";
     Write-Host "      -s       Source directory.  Required";
     Write-Host "      -d       Destination directory.  Required";
     Write-Host "      -perms   Run permission fix only, take owership and full control via user ";
     Write-Host "                 running the script to make sure everything can be copied.";
     Write-Host "      -rc      Run robocopy only";
     Write-Host "      -f       Force run.  Used with -rc for the second run when the destination";
     Write-Host "                 directory is already present.";
     Write-Host "      -h       This Help.";
     Write-Host "";
     Write-Host "     Examples:";
     Write-Host "      Copy-DirWithPerms.ps1 -s `"\\server\d$\dir1`" -d `"\\server\e$\dir2`" ";
     Write-Host "";
     Write-Host "      Do not run subinACL, run just robocopy";
     Write-Host "      Copy-DirWithPerms.ps1 -s `"\\server\share1`" -d `"\\server\e$\dir2`" -rc";
     Write-Host "       ";
     Write-Host "      Run just subinACL to fix permissions";
     Write-Host "      Copy-DirWithPerms.ps1 -s `"\\server\share1`" -perms";
     Write-Host "       ";
     Write-Host "     Notes:";
     Write-Host "     The user running this script must be able to take ownership of directories";
     Write-Host "        and files.  This applies for the -perms and -rc switches and is usually for";
     Write-Host "        a domain admin.";
     Write-Host "     The destination directory sharing is not set up, you must do that manually";
     Write-Host "     Robocopy will create a missing destination directory when using -rc but will ";
     Write-Host "        not do the sharing permissions.";
     Write-Host "     You can copy network shares but the destination should really be specified  ";
     Write-Host "        to the admin share (\\server\d$\dir) instead of the network share to ";
     Write-Host "        eliminate any potential permission issues. ";
    

}

if ( $h.isPresent ) { helpme; Return;}

[string] $script:log = "NA"
# Set output switch "$l" so the funcOutputResult funtion work correctly
if ( $log -ne "NA" )
{ [switch] $script:l = $true; }
else
{ [switch] $script:l = $false; }


##### Check logging capability #####
# Check if path is something other than ending in a file.
if ( $l.isPresent -and (-not (Test-Path -path "$log" -pathType Leaf)) ) 
{
   $null = New-Item -Path "$log" -ItemType file -ErrorVariable $evar -ErrorAction SilentlyContinue
   if ( $? -eq $false ) { Write-Host "Cannot write to log file location: `'$log`' " -Backgroundcolor red; Return 3; }
}
# Check if path ends in a file
if ( $l.isPresent -and (Test-Path -path "$log" -pathType Leaf) )
{
   # test of permissions on log file
   Out-File -Filepath "$log" -Inputobject " " -Append -ErrorVariable $evar -ErrorAction SilentlyContinue
   # if log file test of write fails, yell and bail out.
   if ( $? -eq $false ) { Write-Host "  Cannot write to log file location: `'$log`' " -Backgroundcolor red; Return 3; }
}


# This will output text to the screen or file
function funcOutputResult ( [switch] $d, [switch] $ft, [switch] $fl, [switch] $all, [object] $textobj, [string] $strBColor, [string] $strFColor )
{
   # -textobj can be a string object, datetime, array, or may other objects that
   #    need to looped through to get their output.
   # -d will display to screen
   # -l will log to file.  This is a script wide switch set outside this function. 
   #    You need to make sure the $log file location is specified as a param.
   # -fl is Format-List
   # -ft is Format-Table
   # -all is to show all attibutes of the Format-List or Format-Table
   # -strBColor is background color
   # -strFColor is forground color
   
   # -fl and -ft overrides -strBColor and -strFColor
   
   # check if log file path has been passed to us.
   if ( $l.IsPresent -and $log -eq "NA" )
   { Write-Host "Log file doesn't exist" -BackgroundColor Red; Return; }
   
   if ( $ft.IsPresent -or $fl.IsPresent )
   {
      if ( $l.IsPresent )
      {
         # if display is present output that next and when done do the logging   
         if ( $d.IsPresent )
         {   
            if ( $fl.IsPresent )
            { if ( $all.IsPresent )
               { $textobj | ForEach-Object { $_ | Format-List * | Out-Host; }; }
              else
                 { $textobj | ForEach-Object { $_ | Format-List | Out-Host; }; }
            }
            if ( $ft.IsPresent )
            { if ( $all.IsPresent )
               { $textobj | ForEach-Object { $_ | Format-Table * | Out-Host; }; }
              else
                 { $textobj | ForEach-Object { $_ | Format-Table | Out-Host; }; }
            }
         } # Done writing to display
         
         # Now write to log file
         if ( $fl.IsPresent )
         {   # Write list formated output to file
            if ( $all.IsPresent )
            {   $textobj | ForEach-Object { $_ | Format-List * | Out-File -Filepath "$log" -Append -ErrorVariable $evar -ErrorAction SilentlyContinue; };
               # check if write failed
               if ( $? -eq $false )
               {    $textout = "Failed to write to log file: $log." ;
                  Write-Host $textout -BackgroundColor Red;
               }
            }
            else # -all is not present
            {
               $textobj | ForEach-Object { $_ | Format-List | Out-File -Filepath "$log" -Append -ErrorVariable $evar -ErrorAction SilentlyContinue; };
               # check if write failed
               if ( $? -eq $false )
               {    $textout = "Failed to write to log file: $log." ;
                  Write-Host $textout -BackgroundColor Red;
               }
            }
         }
         if ( $ft.IsPresent )
         {   # Write list formated output to file
            if ( $all.IsPresent )
            {   $textobj | ForEach-Object { $_ | Format-Table * | Out-File -Filepath "$log" -Append -ErrorVariable $evar -ErrorAction SilentlyContinue; };
               # check if write failed
               if ( $? -eq $false )
               {    $textout = "Failed to write to log file: $log." ;
                  Write-Host $textout -BackgroundColor Red;
               }
            }
            else # -all is not present
            {
               $textobj | ForEach-Object { $_ | Format-Table | Out-File -Filepath "$log" -Append -ErrorVariable $evar -ErrorAction SilentlyContinue; };
               # check if write failed
               if ( $? -eq $false )
               {    $textout = "Failed to write to log file: $log." ;
                  Write-Host $textout -BackgroundColor Red;
               }
            }
         }
      } # End logging of -fl and -ft
      else # No logging
      {
         if ( $d.IsPresent )
         {   
            if ( $fl.IsPresent )
            { if ( $all.IsPresent )
               { $textobj | ForEach-Object { $_ | Format-List * | Out-Host; }; }
              else
                 { $textobj | ForEach-Object { $_ | Format-List | Out-Host; }; }
            }
            if ( $ft.IsPresent )
            { if ( $all.IsPresent )
               { $textobj | ForEach-Object { $_ | Format-Table * | Out-Host; }; }
              else
                 { $textobj | ForEach-Object { $_ | Format-Table | Out-Host; }; }
            }
         } # Done writing to display
      } # End just display of -fl and -ft
   } # End -fl and -ft
   
   else # $ft and $fl are not present
   {
      if ( $l.IsPresent )
      {
         # if display is present output that next and when done do the logging   
         if ( $d.IsPresent )
         {   
            if ( $strBColor -ne "" )
            {
               if ( $strFColor -ne "" ) # bg=y, fg=y
               { $textobj | ForEach-Object { Write-Host $_ -BackgroundColor $strBColor -ForegroundColor $strFColor; }; }
               else # bg=y, fg=n
               { $textobj | ForEach-Object { Write-Host $_ -BackgroundColor $strBColor; }; }
            }
            else
            {
               if ( $strFColor -ne "" ) # bg=n, fg=y
               { $textobj | ForEach-Object { Write-Host $_ -ForegroundColor $strFColor; }; }
               else # bg=n, fg=n
               { $textobj | ForEach-Object { Write-Host $_; }; }
            }
         }
         
         # Now write to log file
         $textobj | ForEach-Object { $_ | Out-File -Filepath "$log" -Append -ErrorVariable $evar -ErrorAction SilentlyContinue; };
         # check if write failed
         if ( $? -eq $false )
         {    $textout = "Failed to write to log file: $log." ;
            Write-Host $textout -BackgroundColor Red;
         }
      } # End plain logging
      else # No logging
      {
         if ( $d.IsPresent )
         {   
            if ( $strBColor -ne "" )
            {
               if ( $strFColor -ne "" ) # bg=y, fg=y
               { $textobj | ForEach-Object { Write-Host $_ -BackgroundColor $strBColor -ForegroundColor $strFColor; }; }
               else # bg=y, fg=n
               { $textobj | ForEach-Object { Write-Host $_ -BackgroundColor $strBColor; }; }
            }
            else
            {
               if ( $strFColor -ne "" ) # bg=n, fg=y
               { $textobj | ForEach-Object { Write-Host $_ -ForegroundColor $strFColor; }; }
               else # bg=n, fg=n
               { $textobj | ForEach-Object { Write-Host $_; }; }
            }
         }
      } # End of logging for "$ft and $fl are not present"
   } # End $ft and $fl are not present
}


function funcSanityChecks()
{
   # Check for multiple issues with inputs
   #
   # Inputs:    Just the params passed in script execution
   #
   # Returns:   1 if something is wrong, 0 if everything is OK.

   #   what version of subinacl is needed?   subinacl version 5.2.3790.1180
   #   what version of robocopy is needed? robocopy Version XP010
   
   #   need to be in a 32 bit environment.  $env:PROCESSOR_ARCHITECTURE  =  "x86" if we are on 32 bit, else is is AMD64
   if ( ($env:PROCESSOR_ARCHITECTURE -ne "x86") -and ($perms.isPresent))
   {
      $textobj = "  This script must be run in a 32 bit environment because of the subinacl program.";
      funcOutputResult -d -textobj "$textobj" -strFColor "Red";
      Return 1;
   }
   
   #$subvercheck = (( subinacl \? ) | Where-Object { $_ -cmatch "SubInAcl version 5.2.3790.1180"; } );
   #if (  )
   #{
   #   $textobj = "  This script must be run in a 32 bit environment because of the subinacl program.";
   #   funcOutputResult -d -textobj "$textobj" -strFColor "Red";
   #   Return 1;
   #}
   
   if ( (Test-Path -PathType Container "$strSource") -and ($perms.isPresent -or $rc.isPresent) )
   {
      Out-Null; # Everything is fine.
   }
   else # Doesn't exist
   {
      $textobj = "  Please input the source path directory";
      funcOutputResult -d -textobj "$textobj" -strFColor "Red";
      Return 1;
   }

   if  ( $rc.isPresent )
   {
      # Check if parent directory exits
      [string] $f1 = Split-Path  "$strDest";      # Gives us the parent
      
      if ( Test-Path -PathType Container "$f1" )
      {
         Out-Null; # Everything is fine.
      }
      else
      {
         $textobj = "  The parent directory does not exist for: `'$strDest`' ";
         funcOutputResult -d -textobj "$textobj" -strFColor "Red";
         Return 1;
      }
   
      # Check if destination directory already exists, and user is not looking to run robocopy only
      # Robocopy will create the directory if it is missing, this is to prevent overwrite of existing files.
      if ( (Test-Path -PathType Container "$strDest") -and ($f -eq $false) )
      {
         $textobj = "  The destination directory `'$strDest`' `n  is already present.  This script does not allow merging of directories. ";
         funcOutputResult -d -textobj "$textobj" -strFColor "Red";
         $textobj = "  Please rename the existing destination directory and try again.  ";
         funcOutputResult -d -textobj "$textobj" -strFColor "Red";
         Return 1;
      }
   }

   Return 0;
} # End funcSanityChecks



############################### MAIN ###############################
####################################################################

# Note that file logging is handled by the funcOutputResult function automatically
$textobj = "------------------ $datetimecolon ------------------";
funcOutputResult -d -textobj "$textobj";

$textobj = "  Computer name: $cname";
funcOutputResult -d -textobj "$textobj";

# Set to more readable variables
[string] $script:strSource = $s;
[string] $script:strDest   = $d;

[array] $arrSanityResult = funcSanityChecks;

switch ( $arrSanityResult[0] )
{
   0 {
      # Everything is fine
      Out-Null;
   }
   1 {
      $textobj = ( "  Error in funcSanityChecks function." );
      funcOutputResult -d -textobj "$textobj" -strFColor "Red";
      Return;
   }
   default {
      $textobj = ( "  Weird error `'" + $arrSanityResult[0].tostring() + "`' was returned from the sanity checks." );
      funcOutputResult -d -textobj "$textobj" -strFColor "Red";
      Return;
   }
}


if ( $perms.isPresent )
{
#   # Get permissions of from source directory via subinacl, store to log file
#   [string] $suboutputlog = "$env:TEMP" + '\permsfile-' + "$datetimeunder" + '.txt';
#   [string] $args2 = '/noverbose /outputlog="' + $suboutputlog + '" /subdirectories "' + $strSource + '" /display';
#   [Diagnostics.Process]::Start("subinacl", "$args2").WaitForExit();
#   if ( $? )
#   {    $textobj = "  Subinacl perm backup to `'$outputlog`' completed ";
#      funcOutputResult -d -textobj "$textobj";
#   }
#   else
#   {   $textobj = "***** Subinacl perm backup to `'$outputlog`' FAILED. ***** ";
#      funcOutputResult -d -textobj "$textobj" -strBColor "Red";
#      Return 3;
#   }
#   
#   
#   # Create destination directory, note that parent dir was checked for
#   # and an existing destination directory in funcSanityChecks
#   New-Item -ItemType Directory -Path "$strDest" -ErrorAction SilentlyContinue | Out-Null;
#   if ( $? )
#   {    $textobj = "  Create destination `'$strDest`' completed ";
#      funcOutputResult -d -textobj "$textobj";
#   }
#   else
#   {   $textobj = "***** Create destination `'$strDest`' FAILED. ***** ";
#      funcOutputResult -d -textobj "$textobj" -strBColor "Red";
#      Return 3;
#   }
#   
#   
#   # Set permissions of to destination directory via subinacl
#   [string] $args2 = '/playfile "' + $suboutputlog + '"';
#   [Diagnostics.Process]::Start("subinacl", "$args2").WaitForExit();
#   if ( $? )
#   {    $textobj = "  Subinacl perm restore from `'$outputlog`' completed ";
#      funcOutputResult -d -textobj "$textobj";
#   }
#   else
#   {   $textobj = "***** Subinacl perm restore from `'$outputlog`' FAILED. ***** ";
#      funcOutputResult -d -textobj "$textobj" -strBColor "Red";
#      Return 3;
#   }


   function funcTakeOwnershipFullAccess ( [string] $path1 )
   {   
      # To set ownership on <FolderPath>:
      # subinacl /subdirectories <FolderPath> /setowner=<DomainName\UserName>
      # To set ownership for all the <FolderPath> objects:
      # subinacl /subdirectories <FolderPath>\*.* /setowner=<DomainName\UserName>
      [string] $suboutputlog = "$env:TEMP" + '\permschange-' + "$datetimeunder" + '.txt';
   
      
      Get-ChildItem $path1 | ForEach-Object {
         $strCurrentFullName = $_.FullName;
         if ( $_.psIsContainer -eq $false )
         {
            # Set the owner to who we are so we can get and set permissions as needed later.
            #[string] $args2 = '/outputlog="' + $suboutputlog + '" /subdirectories "' + $strCurrentFullName + '" /setowner="' + $strUserPrincipalName + '"' ;
            [string] $args2 = '/noverbose /subdirectories "' + $strCurrentFullName + '" /setowner="' + $strUserPrincipalName + '"' ;
            [Diagnostics.Process]::Start("subinacl", "$args2").WaitForExit();
            if ( $? )
            {    $textobj = "  Ownership of $strCurrentFullName completed ";
               funcOutputResult -d -textobj "$textobj";
            }
            else
            {   $textobj = "***** Ownership of $strCurrentFullName completed ***** ";
               funcOutputResult -d -textobj "$textobj" -strBColor "Red";
               Return 3;
            }
            
            # Allow full access so we can copy the file.
            $aclCurrent = Get-Acl -path "$strCurrentFullName"
            $Ar = New-Object  system.security.accesscontrol.filesystemaccessrule("$strUserPrincipalName","FullControl","Allow")
            $aclCurrent.AddAccessRule($Ar)
            Set-Acl -path "$strCurrentFullName" -aclObject $aclCurrent
            if ( $? )
            {    $textobj = "  Full control of $strCurrentFullName completed ";
               funcOutputResult -d -textobj "$textobj";
            }
            else
            {   $textobj = "***** Full control of $strCurrentFullName completed ***** ";
               funcOutputResult -d -textobj "$textobj" -strBColor "Red";
               Return 3;
            }
         }
         
         if ( $_.psIsContainer -eq $true )
         {
            # Set the owner to who we are so we can get and set permissions as needed later.
            #[string] $args2 = '/outputlog="' + $suboutputlog + '" /subdirectories "' + $strCurrentFullName + '" /setowner="' + $strUserPrincipalName + '"' ;
            [string] $args2 = '/noverbose /subdirectories "' + $strCurrentFullName + '" /setowner="' + $strUserPrincipalName + '"' ;
            [Diagnostics.Process]::Start("subinacl", "$args2").WaitForExit();
            if ( $? )
            {    $textobj = "  Ownership of $strCurrentFullName completed ";
               funcOutputResult -d -textobj "$textobj";
            }
            else
            {   $textobj = "***** Ownership of $strCurrentFullName completed ***** ";
               funcOutputResult -d -textobj "$textobj" -strBColor "Red";
               Return 3;
            }
            
            # Allow full access so we can copy the file.
            $aclCurrent = Get-Acl -path "$strCurrentFullName"
            $Ar = New-Object  system.security.accesscontrol.filesystemaccessrule("$strUserPrincipalName","FullControl","Allow")
            $aclCurrent.AddAccessRule($Ar)
            Set-Acl -path "$strCurrentFullName" -aclObject $aclCurrent
            if ( $? )
            {    $textobj = "  Full control of $strCurrentFullName completed ";
               funcOutputResult -d -textobj "$textobj";
            }
            else
            {   $textobj = "***** Full control of $strCurrentFullName completed ***** ";
               funcOutputResult -d -textobj "$textobj" -strBColor "Red";
               Return 3;
            }
            
            # call ourselves to go through this directory
            funcTakeOwnershipFullAccess "$strCurrentFullName";
         }
      
      }
   }

   # call our function to get everything started.
   funcTakeOwnershipFullAccess "$strSource";

} # End of if ( $rc -eq $false )


if ( $rc.isPresent )
{
   # Run robocopy to copy contents from source to destination with all permissions
   # Note you need to have the Manage Auditing user right for robocopy to work.
   [string] $roboutputlog = "$env:TEMP" + '\robocopylog-' + "$datetimeunder" + '.txt';
   [string] $args2 = '"' + $strSource + '" ' + '"' + $strDest + '" /V /NP /E /COPYALL /B /IPG:3 /R:10 /W:30 /TEE /LOG:"' + $roboutputlog + '"';
   [Diagnostics.Process]::Start("robocopy", "$args2").WaitForExit();
   if ( $? )
   {    $textobj = "  Robocopy copy from `'$strSource`' `n  to `'$strDest`' completed ";
      funcOutputResult -d -textobj "$textobj";
   }
   else
   {   $textobj = "***** Robocopy copy from `'$strSource`' to `'$strDest`' FAILED. ***** ";
      funcOutputResult -d -textobj "$textobj" -strBColor "Red";
      Return 3;
   }
      # Robocopy switch descriptions:
      # /V       :: produce Verbose output, showing skipped files.
      # /NP       :: No Progress - don't display % copied.
      # /E       :: copy subdirectories, including Empty ones.
      # /COPYALL    :: COPY ALL file info (equivalent to /COPY:DATSOU).
      # /B       :: copy files in Backup mode.
      # /IPG:n    :: Inter-Packet Gap (ms), to free bandwidth on slow lines.
      # /R:n       :: number of Retries on failed copies: default 1 million.
      # /W:n       :: Wait time between retries: default is 30 seconds.
      # /TEE       :: output to console window, as well as the log file.
      # /LOG:file :: output status to LOG file (overwrite existing log).
      
      # Other useful switches
      # Do not use the mirror feature (/MIR), it will delete on the source if you run into problems
      # /MON:n    :: MONitor source; run again when more than n changes seen.
      # /MOT:m    :: MOnitor source; run again in m minutes Time, if changed.
      # /LOG+:file :: output status to LOG file (append to existing log).
   
   
   $textobj = "`n  You can now rerun robocopy to make sure nothing has been changed on the source while you were copying it. `n  You should check the robocopy log file `'$roboutputlog`' `n  for anything that your user did not have permission to read.`n  You may also manually delete the source directory. `n";
   funcOutputResult -d -textobj "$textobj";
}




View user's profile Send private message
Display posts from previous:
Reply to topic Page 1 of 1
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
  


Magic SEO URL for phpBB