У меня есть рабочий сценарий PS, который используется для сравнения содержимого двух каталогов и сообщения о любых отсутствующих файлах или файлах с различным содержанием. Вот что он делает в данный момент:
- Занимает два конкретных каталога.
- Извлекает все файлы из каждого каталога (за исключением исключенных путей / файлов).
- Проверяет, отсутствуют ли какие-либо файлы в одном или другом файле.
- Для каждого файла, который находится в обоих каталогах, он выполняет сравнение хеш-содержимого этого файла.
- Размещает результаты в переменных на основе файлов в источнике, но не в месте назначения и наоборот, а также в файлах, которые находились как в источнике, так и в месте назначения, но имели различное содержимое.
Ниже приведен основной фрагмент кода, который делает все это. Что мне нужно изменить / добавить, так это возможность перечислять ТОЛЬКО конкретные пути, которые я хочу сравнивать между двумя серверами. Например, скажем, я хочу, чтобы для сравнения использовались следующие пути:
- D: \ Files \ Материал
- D: \ Files \ Содержание \ Папки \ MoreStuff
- D: \ Files \ Архив
Я бы хотел, чтобы каждый из этих каталогов сравнивался между их аналогами на другом сервере. Это означает, что он будет сравнивать путь D:\Files\Stuff
между server 1
и server 2
. Это НЕ сравнивало бы пути друг с другом. То есть я НЕ хочу, чтобы он сравнивал D:\Files\Stuff
с D:\Files\Archive
, независимо от сервера.
Как мне лучше всего этого достичь?
$SourceDir = "\\12345-serverP1\D$\Files";
$DestDir = "\\54321-serverP2\D$\Files";
#The excluded array holds all of the specific paths, files, and file types you don't want to be compared.
$ExcludedPaths = @(Import-Csv -LiteralPath 'D:\ExclusionList.csv') |Select-Object -Expand ExcludedPaths;
$ExcludedFiles = @(Import-Csv -LiteralPath 'D:\ExclusionList.csv') |Select-Object -Expand ExcludedFiles;
#Script block which stores the filter for the Where-Object used to exclude chosen paths.
#This script is called with the -FilterScript parameter below.
$Filter = {
$FullName = $_.FullName
-not($ExcludedPaths | Where-Object {$FullName -like "$_*";})
}
#Grabs all files from each directory, minus the excluded paths and files, and assigns them to variables based on Source and Destination.
try {$SourceFiles = Get-ChildItem -Recurse -Path $SourceDir -Exclude $ExcludedFiles -Force -ErrorAction Stop | Where-Object -FilterScript $Filter;}
catch {Write-Output "$(Get-Date) The following Source path was not found: $SourceDir" | Out-File $ErrorLog -Append;}
try {$DestFiles = Get-ChildItem -Recurse -Path $DestDir -Exclude $ExcludedFiles -Force -ErrorAction Stop | Where-Object -FilterScript $Filter;}
catch {Write-Output "$(Get-Date) The following Destination path was not found: $DestDir" | Out-File $ErrorLog -Append;}
#Pulls the name of each file and assigns it to a variable.
$SourceFileNames = $SourceFiles | % { $_.Name };
$DestFileNames = $DestFiles | % { $_.Name };
#Empty variables to be used in the loops below.
$MissingFromDestination = @();
$MissingFromSource = @();
$DifferentFiles = @();
$IdenticalFiles = @();
#Iterates through each file in the Source directory and compares the name against each file in the Destination directory.
#If the file is missing from the Destination, it is added to the MissingFromDestination variable.
#If the file appears in both directories, it compares the hash of both files.
#If the hash is the same, it adds it to the IdenticalFiles variable. If the hash is different, it adds the Source file to the DifferentFiles variable.
try {
foreach ($f in $SourceFiles) {
if (!$DestFileNames.Contains($f.Name)) {$MissingFromDestination += $f;}
elseif ($DestFileNames.Contains($f.Name)) {$IdenticalFiles += $f;}
else {
$t = $DestFiles | Where { $_.Name -eq $f.Name };
if ((Get-FileHash $f.FullName).hash -ne (Get-FileHash $t.FullName).hash) {$DifferentFiles += $f;}
}
}
}
catch {Write-Output "$(Get-Date) The Destination variable is null due to an incorrect path." | Out-File $ErrorLog -Append;}
#Iterates through each file in the Destination directory and compares the name against each file in the Source directory.
#If the file is missing from the Source, it is added to the MissingFromSource variable.
try {
foreach ($f in $DestFiles) {
if (!$SourceFileNames.Contains($f.Name)) {$MissingFromSource += $f;}
}
}
catch {Write-Output "$(Get-Date) The Source variable is null due to an incorrect path." | Out-File $ErrorLog -Append;}