FamilyTechYmas

jueves, 21 de enero de 2021

Robocopy - alternativa (Copy-Item) mejorada para copia de datos de un servidor a otro

Este script es un "ROBOCOPY" mejorado, permitiendo la copia de todos los ficheros de un servidor a otro, guardando un log detallado de las acciones.

Tambien mantiene las ACE del origen sobre el destino, agregando ademas el usuario $user1

Aparte del log, guarda tambien otros dos ficheros, complementarios, con mas informacion: \D$\Total_Files_and_Size.txt y \D$\User Files and Size.csv


<#

============================================================================

SCRIPT NAME     :     Detect_old_DNS_IP_and_change.ps1

 

AUTHOR          :     Cristian Marius Precub

CREATION DATE   :     2020/12/09

RELEASE         :     v1.0

USAGE SYNTAX    :    

NORMAL RETURN   :    

ERROR RETURN    :    

 

============================================================================

                - DISCLAIMER -

This sample script is not supported under any Microsoft standard support

program or service. The sample script is provided AS IS without warranty of

any kind. Microsoft further disclaims all implied warranties including,

without limitation, any implied warranties of merchantability or of fitness

for a particular purpose. The entire risk arising out of the use or

performance of the sample scripts and documentation remains with you. In no

event shall Microsoft, its authors, or anyone else involved in the creation,

production, or delivery of the scripts be liable for any damages whatsoever

(including, without limitation, damages for loss of business profits, business

interruption, loss of business information, or other pecuniary loss) arising

out of the use of or inability to use the sample scripts or documentation,

even if Microsoft has been advised of the possibility of such damages.

============================================================================

                - SCRIPT DESCRIPTION -

Script used for copying files from one computer to another, maintaining

permissions(except for NT AUTHORITY and BUILTIN accounts) from origin into the destination

This script takes ownership of any file/folder that has access denied initially.

If run entirely, it will ask for origin and destination computers to be input manually.

Script assumes that both origin server and destination have the same disk layout and

location of files is \F$\Datos, saving logs on \D$\

 

============================================================================

                - RELEASE NOTES -

v1.0 - 2020/12/09 - Cristian Marius Precub  - Script Creation

 

 

 

 

============================================================================

#Requires -version 2.0

 

 

.IMPORTANT

Please check lines commented below, for replacing username and domain as needed. (lines: 53,62,111,125)

To change the log output for the details, also modify lines 76,89.

Lines 295 to 299 are defining the origin and destination folders. Update as needed.

 

.Usage

 

 

 

.Notes

This script task ownership of any file/folder that has access denied initially.

 

 

#>

 

#------------------------------------------------------------------------------------------

 

function RobocopyFolder($BackupFrom,$BackupTo,$Logfile,$Exclutions) {

cls

    Write-Host "Making Copy of: " $BackupFrom

 

    Write-Host $Newline

    #$Newline >> $LogFile

    $(date).ToString() + " *****COPY STARTING*****" >> $Logfile

    "------------------------------------------------------------------------------------------" >> $Logfile

       $user1=read-host "Enter user in format domain\user"

try{

    #List all files and folders from origin

       $origen= gci -Path $BackupFrom -Recurse -Filter * -ErrorAction Stop | Select-Object fullname,name,length,attributes,PSParentPath,PSChildName

    Write-Host "Listed all files and folders from $BackupFrom" -ForegroundColor Cyan

} catch {

$($PSitem.tostring())

        $(date).ToString() + " !!! Unable to read $($Error[0].CategoryInfo.TargetName)" >> $Logfile

        $Var1=Get-Acl -Path $($Error[0].CategoryInfo.TargetName)

        $var2= $var1.Access | Where-Object {$_.IdentityReference -notlike "*NT AUTHORITY*"}

        $var3=$var2 | Where-Object {$_.IdentityReference -notlike "*BUILTIN*"}

        "Carpeta $($Error[0].CategoryInfo.TargetName)"

        takeown /R /F $($Error[0].CategoryInfo.TargetName) /d Y

        $(date).ToString() + " Taking Ownership of $($Error[0].CategoryInfo.TargetName)" >> $Logfile

        Start-Sleep -Milliseconds 500

        icacls $($Error[0].CategoryInfo.TargetName) /reset /t /c /l /q

        $(date).ToString() + " ACL Reset for $($Error[0].CategoryInfo.TargetName)" >> $Logfile

        $AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($user1,"FullControl","ContainerInherit,ObjectInherit","None","Allow")

        $var1.SetAccessRule($AccessRule)

        Start-Sleep -Milliseconds 500

        foreach ($1 in $var3) {

        $AccessRule2 = New-Object System.Security.AccessControl.FileSystemAccessRule($1.IdentityReference,$($1.FileSystemRights),"ContainerInherit,ObjectInherit","None",$($1.AccessControlType))

        $var1.SetAccessRule($AccessRule2)

        Set-Acl -Path $($Error[0].CategoryInfo.TargetName) -AclObject $var1

        $(date).ToString() + " Added previously granted permissions, via explicit for: $($Error[0].CategoryInfo.TargetName)" >> $Logfile

        }

        icacls $($Error[0].CategoryInfo.TargetName) /setowner $user1 /T

        $(date).ToString() + " Owner replaced by $user1 for: $($Error[0].CategoryInfo.TargetName)" >> $Logfile

        $origen= gci -Path $BackupFrom -Recurse -Filter * -ErrorAction Stop

        $(date).ToString() + " *** Fixed read permissions for $($Error[0].CategoryInfo.TargetName)" >> $Logfile

}

    #variable to ensure consistency of next line

    $mm="Microsoft.PowerShell.Core\FileSystem::$originserver\F$\Datos"

    $maindir=$origen | select attributes,PSParentPath,name,length |Where-Object {$_.Attributes -like "*Directory*"  -and $_.PSParentPath -eq $mm}

    #count all folders in origin\datos\usuarios

    $todos=$maindir.Count

    #prepare counter for later

    $count=0

    write-host "All files located :-)" -ForegroundColor Cyan

    $totalSize = ($origen | Measure-Object -Sum Length).Sum / 1GB

    $line=New-Object psobject

    $line | Add-Member -MemberType NoteProperty -name "Total User Folders" -Value $todos

    $line | Add-Member -MemberType NoteProperty -name "Total size (GB)" -Value $totalSize

    $line | Export-Csv -Append -NoTypeInformation -NoClobber -Encoding UTF8 -Path ($DestinyServer + "\D$\Total_Files_and_Size.txt")

    foreach ($X in $origen) {

    $rs="Microsoft.PowerShell.Core\FileSystem::$originserver\F$\Datos"

    if ($x.Attributes -like "*Directory*" -and $x.PSParentPath.Equals($rs)){

    get-job *

    remove-job *

    $count++

    "[$count/$todos] User folders have been copied so far ..."

    "***Getting $($x.fullname) items***" >> $Logfile

    $Job_result=Start-Job -ScriptBlock {gci -Path $args -Filter * -Recurse| Select-Object fullname,name,length,attributes,PSParentPath,PSChildName} -ArgumentList $x.fullname

    while ($NbUnfinishedJobs = (Get-Job | Where-Object {$_.State -ne 'Completed'}).count) {

        Write-Host "Waiting for $NbUnfinishedJobs job(s) to finish ..."

        Start-Sleep 2

    }

    $totalfiles_in_folder=get-job | Receive-Job -Keep

    $totalSize_user_folder = ($totalfiles_in_folder | Measure-Object -Sum Length).Sum / 1MB

    "****Total of $($totalfiles_in_folder.count) files, with size of $($totalSize_user_folder)(MB) in the user $($x.name)'s folder****" >> $Logfile

    #write to log user files and size.csv

    $line=New-Object psobject

    $line | Add-Member -MemberType NoteProperty -name "User Folder size (MB)" -Value $totalSize_user_folder

    $line | Add-Member -MemberType NoteProperty -name "User Folder Name" -Value $x.fullname

    $line | Add-Member -MemberType NoteProperty -name "Files in User folder" -Value $($totalfiles_in_folder.count)

    $line | Export-Csv -Append -NoTypeInformation -NoClobber -Encoding UTF8 -Path ($DestinyServer + "\D$\User Files and Size.csv")

    Copy-Item -Path $x.FullName -Destination $BackupTo -Recurse -ErrorAction SilentlyContinue

    if ($?){

        $(date).ToString() + " Folder $($x.fullname) copied successfully." >> $Logfile

        } else {

        if ($($error[0] -like "*Already exists*")){

        write-host "$($X.fullname) already exists. Copying only new content ..." -ForegroundColor Yellow

        $(date).ToString() + " Folder $($X.fullname) already exists: *** $($Error[0])" >> $Logfile

        $(date).ToString() + " Proceeding to copy only new contents of $($X.fullname)" >> $Logfile

        } else {

        $($Error[0])

            $(date).ToString() + " Error copying $($X.fullname): *** $($Error[0])" >> $Logfile

    }

    }

    #ACL part

    #build path for ACL consult

    $destfile=$Backupto + "\" + $x.PSChildName

    $(date).ToString() +  " Getting ACL for $($destfile)" >> $Logfile

    #get ACL from destination

    $perm1=get-acl -Path $destfile

    $(date).ToString() + " Getting ACL for $($x.fullname)" >> $Logfile

        #get acl from Origin

        $car1=Get-Acl -Path $x.FullName

        #remove spceial accounts from ACL

        $car2= $car1.Access | Where-Object {$_.IdentityReference -notlike "*NT AUTHORITY*"}

        #remove builtin accounts from ACL

        $car3=$car2 | Where-Object {$_.IdentityReference -notlike "*BUILTIN*"}

        Start-Sleep -Milliseconds 500

        #build ACE for $user1

        $AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($user1,"FullControl","ContainerInherit,ObjectInherit","None","Allow")

        $perm1.SetAccessRule($AccessRule)

        Start-Sleep -Milliseconds 500

        foreach ($1 in $car3) {

        #build ACE's from Origin to use on destination

        $AccessRule2 = New-Object System.Security.AccessControl.FileSystemAccessRule($1.IdentityReference,$($1.FileSystemRights),"ContainerInherit,ObjectInherit","None",$($1.AccessControlType))

        $perm1.SetAccessRule($AccessRule2)

        }

        try{

            #set ACL previously built

            Set-Acl -Path $destfile -AclObject $perm1 -ErrorAction Stop

            $(date).ToString() + " Setting ACL on $($destfile) maintaining origin permissions" >> $Logfile

        } catch {

            $(date).ToString() + " " + $($error[0]) >> $Logfile

        }

        try{

            icacls $destfile /setowner $user1 /T

            $(date).ToString() + " Setting $user1 as owner of $($destfile)" >> $Logfile

        } catch {

            $(date).ToString() + " " + $($error[0]) >> $Logfile

        }

    }#end of if

    } #end of foreach

    $(date).ToString() + " *****COPY FINISHED*****" >> $Logfile

    "------------------------------------------------------------------------------------------" >> $Logfile

 

}

#Remove-Variable * -ErrorAction SilentlyContinue

 

#------------------------------------------------------------------------------------------

#------------------------------------------------------------------------------------------

#------------------------------------------------------------------------------------------

#------------------------------------------------------------------------------------------

 

 

$OriginServer = Read-Host -Prompt "

 

ORIGIN Server"

 

$DestinyServer = Read-Host -Prompt "

 

DESTINY Server"

 

 

 

Write-Host ""

Write-Host ""

Write-Host ""

 

 

If (($OriginServer -eq "") -or ($DestinyServer -eq ""))

{

Write-Host "ORIGIN or DESTINY is empty" -ForegroundColor Yellow

break

}

 

 

$OriginServer = "\\" + $OriginServer

$DestinyServer = "\\" + $DestinyServer

 

 

if ((Test-Path $OriginServer\c$) -ne "True")

{

Write-Host "No Origin server :" $OriginServer "Detected ..." -ForegroundColor Red

Break

}

 

 

if ((Test-Path $DestinyServer\c$) -ne "True")

{

Write-Host "No Destiny server :" $DestinyServer "Detected ..." -ForegroundColor Red

Break

}

 

 

Write-Host "Origin Server: $OriginServer" -ForegroundColor Cyan

Write-Host "DestinyServer: $DestinyServer" -ForegroundColor Cyan

 

Write-Host ""

Write-Host ""

Write-Host ""

 

 

if ((Read-Host -Prompt "To Proceed type ""Y"" ") -ne "Y")

    {

    Write-Host "Aborted ... " -ForegroundColor Yellow

    Break

    }

   

 

#########################################################################################################

#########################################################################################################

#########################################################################################################

 

Write-Host "Starting Copy cycle" -ForegroundColor Cyan

 

#########################################################################################################

#########################################################################################################

#########################################################################################################

 

 

$Newline = "------------------------------------------------------------------------------"

 

#-------------------+++++++++++++++++++++++++++++++++++++-------------------------------

 

#<#

 

# $BackupFrom,$BackupTo,$LogFile,$Exclutions

 

$OriginPath = $OriginServer + "\F$\Datos"

 

$DestinyServerPath = $DestinyServer + "\F$\Datos"

 

$LogPath = $DestinyServer + "\D$\Datos_Copy-Item.Log"

 

 

 

Write-Host "=============================================================================================================================="  -ForegroundColor Cyan

Write-Host "----> Origin:" $OriginPath  "----> Destiny:" $DestinyServerPath "----> Log:" $LogPath -ForegroundColor Cyan

Write-Host "=============================================================================================================================="  -ForegroundColor Cyan

 

 

pause

 

 

RobocopyFolder($OriginPath)($DestinyServerPath)($LogPath)("")

 

 

#>

 

 

#-------------------+++++++++++++++++++++++++++++++++++++-------------------------------

 

 

###################################################

 

Write-Host "Copy completed !! ... " -ForegroundColor Green

 

pause


No hay comentarios:

Publicar un comentario

¡Comenta aquí!