Заметки · 01.09.2023

Зеркало от зеркала

Вот всем хороша утилита robocopy, но уж совсем не дружелюбна. Особенно к тем, кто только начал изучать параметры этой программы. Сразу подмечу, что для изучения всего арсенала из возможностей robocopy лучше использовать какую-нибудь «песочницу», а ещё лучше изолированную виртуальную машину. Так будет всем спокойнее. Нельзя просто взять и изучить функционал robocopy не потеряв пару тройку (десятков, сотен) файлов. Автор всего этого безобразия даже умудрился как-то снести всё облако, используя всего лишь рекурсивную выборку и Remove-Item. Но это уже совсем другая история…

А теперь по теме поста. Robocopy, как любая хорошая утилита, во время работы выдаёт в консоль кучу данных. Если работать с ней в среде командной строки — там ещё всё относительно читаемо и понятно, а вот при получении вывода в PowerShell придётся явно указывать используемую кодировку:

[Console]::OutputEncoding = [System.Text.Encoding]::GetEncoding("utf-8")

Да и, если подумать, можно упростить себе жизнь, заперев утилиту в Out-Null и try/catch.

Например, я делаю зеркальную синхронизацию директорий с помощью этой функции:

function SyncFolders
{
    param
    (
      # Установка параметра Source #
      [Parameter(mandatory=$true)]
      [ValidateNotNullOrEmpty()]
      [string]$Source,
	  
      # Установка параметра Destination #
      [Parameter(mandatory=$true)]
      [ValidateNotNullOrEmpty()]
      [string]$Destination
    )
	
    try
    { 
	Write-Host "Начата синхронизация..." -ForegroundColor Cyan
	robocopy $source $destination /MIR /Z /XF desktop.ini /XD System Volume Information | Out-Null
	Write-Host "Синхронизация завершена!" -ForegroundColor Cyan
    }
    catch { Write-Host "Ошибка синхронизации..." -ForegroundColor Red }
}

В идеале, конечно, нужно прикрутить и Test-Path, но мне показалось это избыточным.

В коде скрипта функция вызывается стандартно:

SyncFolders -Source "D:\Dir1" -Destination "D:\Dir2"

Если в скрипте используется только эта функция — сразу после её объявления можно прописать Sleep(10), чтобы консоль перед закрытием повисела 10 секунд и работа скрипта была наглядной.