FamilyTechYmas

viernes, 27 de agosto de 2021

Backup all GPO and links and restore via PowerShell - Ready for automation

 This time, I bring this script that will help you backup all the GPO's and links in the environment.

To use it properly, you must use this code (which is built over codes from other people.):


<#

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



.DESCRIPTION

This script creates a backup of all the GPO's and their links in the domain and stores them 

into a folder you specify

This script is not meant to be used by running scriptname.ps1 but loading the functions and 

executing the one you want at the moment


.AUTHOR

Cristian Marius Precub


.NOTES


.DATE

24-MAY-2021


.EXAMPLE

To backup all GPOs and Links: backup-allgpo

To restore all GPOs and links: restore-gpoandlinks

#>


Import-Module ActiveDirectory

Import-Module GroupPolicy

if (-not(test-path "C:\temp")) {

    try{

    #create temp folder

    new-item "C:\temp" -Type Directory -ErrorAction Stop

    } catch {"Error creating folder: $($PSItem.ToString())" >> $log }

}

$log = "C:\temp\GPO_Activity.log"


function Get-Gplink  {


<# 

.SYNOPSIS

return and decode content of gplink attribut


.DESCRIPTION

This function purpose is to list the gplink attribut of an OU, Site or DomainDNS.

It will return the following information for each linked GPOs:


    - Target: DN of the targeted object

    - GPOID: GUID of the GPO

    - GPOName: Friendly Name of the GPO

    - GPODomain: Originating domain of the GPO

    - Enforced: <Yes|No>

    - Enabled:  <Yes|No>

    - Order: Link order of the GPO on the OU,Site,DomainDNS (does not report inherited order)


.PARAMETER Path: Give de Distinguished Name of object you want to list the gplink



.INPUTS

DN of the object with GLINK attribut


.OUTPUTS

Target: DC=fourthcoffee,DC=com

GPOID: 31B2F340-016D-11D2-945F-00C04FB984F9

GPOName: Default Domain Policy

GPODomain: fourthcoffee.com

Enforced: <YES - NO>

Enabled: <YES - NO>

Order: 1


.EXAMPLE

get-gplink -path "dc=fourthcoffee,dc=com"


This command will list the GPOs that are linked to the DomainDNS object "dc=fourthcoffee,dc=com" 


.EXAMPLE

get-gplink -path "dc=child,dc=fourthcoffee,dc=com" -server childdc.child.fourthcoffee.com


This command will list the GPOs that are linked to the DomainDNS object "dc=child,dc=fourthcoffee,dc=com". You need to specify a

target DC of the domain child.fourthcoffee.com in order for the command to work.



.EXAMPLE

Get-Gplink -site "CN=Default-First-Site-Name,CN=Sites,CN=Configuration,DC=fourthcoffee,DC=com"


This command will list the GPOs that are linked to site "Default-First-Site-Name"


.EXAMPLE

get-gplink -path "dc=fourthcoffee,dc=com" | export-csv "gplink.csv"


This command will list the GPOs that are linked to the DomainDNS object "dc=fourthcoffee,dc=com" and export them to a csv file.

The csv file can be used as an input to the cmdlet new-gplink 



.EXAMPLE

get-adobject -filter {(objectclass -eq "DomainDNS") -or (objectclass -eq "OrganizationalUnit")} | foreach {get-gplink -path $_.distinguishedname} | export-csv "gplinksall.csv"


This command will list all objects of type "DomainDNS" and "OrganizationalUnit" that have GPOs linked and will list those GPOs, their status and link order.


#>


[cmdletBinding()]

param ([string]$path,[string]$server,[string]$site)


#Import AD and GPO modules

Import-Module activedirectory

Import-Module grouppolicy

# get the DN to te configuration partition

$configpart=(Get-ADRootDSE).configurationNamingContext


#get content of attribut gplink on site object or OU

if ($site)

    {

        $gplink=Get-ADObject -Filter {distinguishedname -eq $site} -searchbase $configpart -Properties gplink

        $target=$site

    }

elseif ($path)

    {

        switch ($server)

            {

             "" {$gplink=Get-ADObject -Filter {distinguishedname -eq $path} -Properties gplink}

             default {$gplink=Get-ADObject -Filter {distinguishedname -eq $path} -Properties gplink -server $server     

                      }

            }

    $target=$path

    }


    


#if DN is not valid return" Invalide DN" error


if ($gplink -eq $null)

    {

        write-host "Either Invalide DN in the current domain, specify a DC of the target DN domain or no GPOlinked to this DN"

    }


# test if glink is not null or only containes white space before continuing. 


if (!((($gplink.gplink) -like "") -or (($gplink.gplink) -like " ")))

    {


        #set variale $o to define link order

        $o=0    

    

        #we split the gplink string in order to seperate the diffent GPO linked


        $split=$gplink.gplink.split("]")

    

        #we need to do a reverse for to get the proper link order


         for ($s=$split.count-1;$s -gt -1;$s--)

            {

          

                #since the last character in the gplink string is a "]" the last split is empty we need to ignore it

           

                if ($split[$s].length -gt 0)

                    {

                        $o++

                        $order=$o            

                        $gpoguid=$split[$s].substring(12,36)

            $gpodomainDN=($split[$s].substring(72)).split(";")

            $domain=($gpodomaindn[0].substring(3)).replace(",DC=",".")

    $checkdc=(get-addomaincontroller -domainname $domain -discover).name

                                 

                        #we test if the $gpoguid is a valid GUID in the domain if not we return a "Oprhaned GpLink or External GPO" in the $gponname

                        

        $mygpo=get-gpo -guid $gpoguid -domain $domain -server "$($checkdc).$($domain)" 2> $null

                    

        if ($mygpo -ne $null )

              {

               $gponame=$MyGPO.displayname

               $gpodomain=$domain

              }

                  

            else

              {

              $gponame="Orphaned GPLink" 

                              $gpodomain=$domain   

              }

   

                        #we test the last 2 charaters of the split do determine the status of the GPO link

           

    

                        if (($split[$s].endswith(";0")))

                            {

                                $enforced= "No"

                                $enabled= "Yes"

                            }

                        elseif (($split[$s].endswith(";1")))

                            {

                                $enabled= "No"

                                $enforced="No"

                            }

                        elseif (($split[$s].endswith(";2")))

                            {

                                $enabled="Yes"

                                $enforced="Yes"

                            }

                        elseif (($split[$s].endswith(";3")))

                            {

                                $enabled="No"

                                $enforced="Yes"

                            }


                         #we create an object representing each GPOs, its links status and link order


                        $return = New-Object psobject 


                        $return | Add-Member -membertype NoteProperty -Name "Target" -Value $target 


                        $return | Add-Member -membertype NoteProperty -Name "GPOID" -Value $gpoguid


                        $return | Add-Member -membertype NoteProperty -Name "DisplayName" -Value $gponame

 

            $return | Add-Member -membertype NoteProperty -Name "Domain" -Value $gpodomain

 

                        $return | Add-Member -membertype NoteProperty -Name "Enforced" -Value $enforced


                        $return | Add-Member -membertype NoteProperty -Name "Enabled" -Value $enabled


                        $return | Add-Member -membertype NoteProperty -Name "Order" -Value $order

                        $return

                    }

         

            }

         

    }

   

    


 }

    




<#

----------------------------------------

File: backup-gplink.ps1

Version: 1.1

Author: Thomas Bouchereau

-----------------------------------------


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 

 #>




function backup-gplink 

{


<# 

.SYNOPSIS

backup gplink of a specified GPO to a CSV file


.DESCRIPTION

This function purpose is to backup gplinks of a specified GPO to a CSV file



.INPUTS

Name of the GPO you want to backup the links


.OUTPUTS

a CSV file name <gponam>_gplinksbackup.csv


.EXAMPLE

backup-gpo -name "test1" -path $pwd\bck


This command will backup the gplinks for the GPO Test1 on the folder bck under the present at the same level as the prompt.


#>


[cmdletBinding()]


param

($gponame,

[string]$path)


$domaindn=(get-addomain).distinguishedname


[xml]$xmlreport=Get-GPOReport -Name $gponame -ReportType xml


    foreach ($som in ($xmlreport.gpo.linksto.SOMPath))

        {

            $target=$null

            $splits=$som.split("/")


            for ($s=$splits.count-1;$s -gt 0;$s--)

                {

                    $target+="OU="+$splits[$s]+","

                }

            $target+=$domaindn

            #$path

            Get-Gplink -path "$($target)" | ?{$_.displayname -eq $gponame} |Export-Csv -UseCulture -NoTypeInformation -Path "$($path)\$($gponame)_gplinksbackup.csv" -Append

        }

}


function restore-gplink

    {



<# 

.SYNOPSIS

restore gplink of a specified GPO using the output of the backup-gplink function


.DESCRIPTION

This function purpose is to restore the gplinks of a specified GPO using the configuration that was saved by the backup-gplink.

If the GPlink is still present, it will reset it to the value present in the backup.



.INPUTS

Name of the CSV file you want to use to restore the gplink


.OUTPUTS

None


.EXAMPLE

restore-gpo  -path "test1_gplinksbackup.cvs"


This command will restore the gplinks for the GPO Test1 to locations present in the  backup file.

Depeding on the links found on the SOM the restore link might be in disable to prevent negative impact on the production environment.


#>


[cmdletBinding()]

param(

[string]$path,

[boolean]$force=$false)


$targets=import-csv -Path $path -UseCulture


    foreach($t in $targets)

            {

                Write-host "Linking GPO $($t.displayname) to $($t.target)" -ForegroundColor Green


                [array]$gplinks=get-gplink -path $t.target

                

                if ($gplinks.count -eq 0)

                    {

                    new-GPLink -Target $t.target -Name $t.displayname -LinkEnabled "no" -Enforced $t.enforced

                    Write-host "Link for GPO $($t.displayname) on SOM $($t.target) has been restored based on your backup file but in a DISABLED state. Check it and if valide re-enable the link" -ForegroundColor Yellow

                    }

                else

                    {

                      if ($t.order -ge $gplinks.count)

                        {

                            try

                                {

                                new-GPLink -Target $t.target -Name $t.displayname -LinkEnabled $t.enabled -Order $($gplinks.count + 1) -Enforced $t.enforced -ErrorAction stop -ErrorVariable linkerr

                                Write-host "Link for GPO $($t.displayname) on SOM $($t.target) has been restored based on your backup file in it's original state." -ForegroundColor Yellow

                                }

                            catch

                                {

                                Write-host "GPO already linked at $($t.target)" -ForegroundColor yellow

                                }


                            if ($linkerr -and $force)

                            {

                            

                            Write-host "Forcing GPO link as in backup file" -ForegroundColor Yellow

                            set-GPLink -Target $t.target -Name $t.displayname -LinkEnabled $($t.enabled) -Order $gplinks.count -Enforced $t.enforced

                            }

                         

                         }

                       else

                         {

                            try

                                {

                                new-GPLink -Target $t.target -Name $t.displayname -LinkEnabled $($t.enabled) -Order $t.order -Enforced $t.enforced -ErrorAction stop -ErrorVariable linkerr

                                Write-host "Link for GPO $($t.displayname) on SOM $($t.target) has been restored based on your backup file in it's original state." -ForegroundColor Yellow

                                }

                            catch

                                {

                                Write-host "GPO already linked at $($t.target)" -ForegroundColor Yellow

                                }


                            if ($linkerr -and $force)

                            {

                            Write-host "Forcing GPO link as in backup file" -ForegroundColor Yellow

                            set-GPLink -Target $t.target -Name $t.displayname -LinkEnabled $t.enabled -Order $t.order -Enforced $t.enforced

                            }

                         

                         }



                        

                    }

            "======================="      

            }

            

        

    }


#Hacer backup de todas las GPO

function backup-allgpo {

#adjust to your scenario the next line

$Backuplocation="C:\temp\GPOBackup"

$secondpart=(get-date).ToString('dd-MMM-yyyy')

$completepath="$Backuplocation\$secondpart"

if (-not(test-path $Backuplocation\$secondpart)) {

    try{

    #create folder

    new-item $Backuplocation\$secondpart -Type Directory -ErrorAction Stop

    } catch {"Error creating folder $($PSItem.ToString())" >> $log}

}

$path=$completepath

get-gpo -all | foreach {

Backup-GPO -name $_.displayname -Path $path

backup-gplink -gponame $_.displayname -path $path

}


$Folders=Get-ChildItem -Path $path -Directory

    foreach ($one in $Folders){

    [xml]$manifest = Get-Content ($one.FullName+"\"+"bkupinfo.xml")

        Rename-Item -Path $one.FullName -NewName $manifest.BackupInst.GPODisplayName.'#cdata-section'

    }

}


#Restaurar copias de seguridad de las GPO

function restore-gpoandlinks {

$app = new-object -com Shell.Application

$folder = $app.BrowseForFolder(0, "Select folder from where backups should be imported", 1)

$GPOFolderName = $folder.Self.Path

$files=Get-ChildItem -Path $folder.self.path -File


$Folders=Get-ChildItem -Path $GPOFolderName -Directory

    foreach ($one in $Folders){

    [xml]$manifest = Get-Content ($one.FullName+"\"+"bkupinfo.xml")

        Rename-Item -Path $one.FullName -NewName $manifest.BackupInst.id.'#cdata-section'

        }


    try{

    $import_array = get-childitem $GPOFolderName -Directory | Select name

    } catch {

        (Get-Date).DateTime + " *** " + $($PSItem.ToString()) >> $log

    }

foreach ($ID in $import_array) {

    $XMLFile = $GPOFolderName + "\" + $ID.Name + "\gpreport.xml"

    $XMLData = [XML](get-content $XMLFile)

    $GPOName = $XMLData.GPO.Name

        try{

        import-gpo -BackupId $ID.Name -TargetName $GPOName -path $GPOFolderName -CreateIfNeeded

        (Get-Date).DateTime + " *** " + "$($GPOName) successfully imported." >> $log

        } catch {

        (Get-Date).DateTime + " *** " + $($PSItem.ToString()) >> $log

        }

}

#restore Links

if (($files.count) -gt "0") {

 foreach ($f in $files)

    {

    try{

    restore-gplink -path $GPOFolderName\$($f.Name) -ErrorAction Stop

    (Get-Date).DateTime + " *** " + "$($GPOName) links successfully restored." >> $log

    } catch {

    (Get-Date).DateTime + " *** " + $($PSItem.ToString()) >> $log

    }

    }

}

}


backup-allgpo

To restore, just change the last line to "restore-gpoandlinks" 

In case you want to use it for automation, you must modify the first lines of both last two functions, regarding path.

viernes, 4 de junio de 2021

Driver Network Adapter for Windows Server 2003 R2 (Hyper-V Virtualized)

 After trying to install my WS2003 for testing purposes, I noticed the network driver is failing to be installed.

Also the network adapter was missing from my internet control panel.


So after some looking on the web I found that I needed to use a Legacy Network Adapter in Hyper-V for that machine, instead of the normal one that gets created.



Another thing was then to install the driver for that.

I had to take the driver from another WS2012 R2 virtualized with Hyper-V.



DOWNLOAD the drivers below.

Here you can find that driver: Windows Server 2003 R2 Network Driver

If link is not working, leave a comment, and I´ll have it fixed.

jueves, 25 de febrero de 2021

[SOLUCION 2021] Error 80072EFE windows update Windows 7

 Bueno, antes de nada, dejar claro que lo unico que proveo aqui, es la solucion al problema, probado por mi en un Windows 7 Profesional SP1


Tras años sin usar un portatil viejo, decidi revivirlo. Intente ponerle Windows 10, pero cada vez que iniciaba desde el medio de instalacion (USB booteable) tras iniciar el instalador de windows, cuando carga la ruleta con el logo de windows, se apagaba subitamente.


Como no encontro solucion, decidi volver a Windows 7. Al hacerlo, para mi sorpresa, no podia buscar actualizaciones, porque salia el error 80072EFE. Pense que era por no activarlo, asi que lo active (oficialmente no pirateo). y aun asi no funcionaba.


Tras varios dias buscando, encontre este enlace: Código de error 80072efe, no puedo actualizar en windows 7 - Sistemas Operativos - ForoSpyware


Dentro, para ahorraros leerlo todo, tiene una herramienta (no oficial de Microsoft) con la cual podreis arreglar este problema. El enlace es este: https://github.com/aakkam22/windowsUpdateLoopFix/releases


Simplemente ejecutadla, seguid los pasos, y cuando acabe, encender la Wi-Fi y buscar actualizaciones.


En un portatil con Intel Core 2 Duo, con 2 GB de RAM, lo ha arreglado en 20 minutos.


El motivo del fallo, parece una cadena de sucesos: Certificados de Windows 7 viejos, no se autoactualuzan por no poder acceder a Windows Update, si descargas las KB manualmente, no las instala las cumulativas, por el mismo motivo. Incluso borrando los certificados "malos" tampoco los recrea y no puedes acceder.


Por lo que agradezco a aakkam22 por la solucion.

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