Como muitas pessoas sabem, você pode configurar exceções na forma de máscaras de arquivos nas propriedades de pastas replicadas - e o serviço não replicará arquivos que correspondam às máscaras especificadas. Mas nem todo mundo sabe que os arquivos têm um atributo "temporário" e o DFSR não processa esses arquivos por design. E se isso não for levado em consideração, pode acontecer que o conteúdo de suas pastas DFSR fique fora de sincronia, embora tudo fique limpo e bonito nos logs de serviço, e isso possa ocorrer no momento mais inoportuno. O problema em si e sua solução foram analisados na Internet mais de uma vez. O objetivo deste artigo é finalizar a solução criada anteriormente, adicionando flexibilidade e conveniência a ele. Para quem é relevante - pergunto sob o gato.
O tópico foi abordado na Internet mais de uma vez, por exemplo, no
blog oficial ,
aqui e
no próprio Habré . Portanto, não vou me repetir, mas vou direto ao ponto. A solução original é um script do PowerShell que redefine o atributo "temporário" para todos os arquivos em uma determinada pasta. Tomando como base, escrevi minha própria versão, que encontra pastas replicadas no servidor de destino e percorre cada uma delas, redefinindo o atributo problem e enviando um relatório sobre os arquivos encontrados por email. Também foi adicionado suporte para
caminhos longos (requer a 5ª versão do PowerShell).
Para que o script funcione, você precisa das ferramentas de gerenciamento de serviço DFS (por padrão, elas são instaladas juntamente com a adição da função Replicação DFS). Se eles não estiverem disponíveis no servidor de destino, execute este cmdlet:
Install-WindowsFeature RSAT-DFS-Mgmt-Con
E aqui está o próprio script:
TempAttrFixer.ps1 Param( # [parameter(Mandatory=$false)][String]$OutDir ) $SMTPServer = "mail.mydomain.com" $MailFrom = "sender@mydomain.com" $MailTo = "recipient@mydomain.com" Function ConvertTo-LiteralPath { # LiteralPath Param( [parameter(Mandatory=$true)][String]$Path ) # UNC If ($Path.Substring(0,2) -eq "\\") { Return ("\\?\UNC" + $Path.Remove(0,1)) } Else { Return "\\?\$Path" } } $StartTime = Get-Date $Error.Clear() If (!$OutDir) { $OutDir = (Get-WmiObject Win32_OperatingSystem).SystemDrive +"\TempAttrFixer_Report" } # , $FoldersToScan = @(Get-DfsrMembership -ComputerName $env:COMPUTERNAME | Sort-Object GroupName, FolderName).ContentPath $LogFileName = "$env:COMPUTERNAME" + "_TempFiles_" + (Get-Date -Format "yyyy-MM-dd-HH-mm-ss") + ".csv" $LogFilePath = "$OutDir\$LogFileName" $Delimiter = "`t" $FilesCount = 0 If (!(Test-Path $OutDir -PathType Container)) { New-Item -ItemType Directory -Force -Path $OutDir | Out-Null } ForEach ($Folder in $FoldersToScan) { # PowerShell 5.1, LireralPath Write-Output "Scanning `"$Folder`"..." Get-ChildItem -LiteralPath (ConvertTo-LiteralPath $Folder) -Recurse | ForEach-Object -Process { if (($_.Attributes -band 0x100) -eq 0x100) { $FilesCount += 1 $Entry = $_.FullName + $Delimiter + $_.GetAccessControl().Owner + "`r`n" $Entry $Entry | Out-File -FilePath $LogFilePath -Encoding unicode -Append -NoNewline $_.Attributes = ($_.Attributes -band 0xFEFF) } } } $FinishTime = Get-Date $TimeSpan = $FinishTime - $StartTime Write-Output ("Done, errors: " + $Error.Count) $Encoding = [System.Text.Encoding]::Unicode If ($FilesCount -gt 0) { $MessageBody = $null $Subject = " " $MessageBody += " : $env:COMPUTERNAME`r`n" $MessageBody += " : " + $TimeSpan.ToString() + "`r`n" $MessageBody += " `"$LogFilePath`"`r`n" Send-MailMessage -SmtpServer $SMTPServer -From $MailFrom -Subject $Subject -Encoding $Encoding -To $MailTo -Body $MessageBody -Attachments $LogFilePath } Else { $MessageBody = $null $Subject = " " $MessageBody += " : $env:COMPUTERNAME`r`n" $MessageBody += " : " + $TimeSpan.ToString() + "`r`n" Send-MailMessage -SmtpServer $SMTPServer -From $MailFrom -Subject $Subject -Encoding $Encoding -To $MailTo -Body $MessageBody } #, - If ($Error.Count -gt 0) { $MessageBody = $null $Subject = " " $MessageBody += " : $env:COMPUTERNAME`r`n" $MessageBody += " : $env:UserName`r`n" $MessageBody += " :`r`n" $MessageBody += $Error[0] Send-MailMessage -SmtpServer $SMTPServer -From $MailFrom -Subject $Subject -Encoding $Encoding -To $MailTo -Body $MessageBody }
Corrigimos os valores das variáveis responsáveis pelos alertas por email e adicionamos o script ao planejador:
powershell.exe -NoLogo -ExecutionPolicy Bypass -NoProfile -File "< >\TempAttrFixer.ps1"
É mais fácil executar a tarefa a partir do SYSTEM, mas se você tiver
um nível aumentado de paranóia e uma abordagem séria à segurança da informação for praticada, poderá usar uma conta separada, concedendo o privilégio de efetuar logon como um trabalho em lotes e o direito de modificar arquivos em pastas replicadas.
Em vez de relatórios por email (ou em adição a eles), você pode configurar o script para interagir com o zabbix ou outro sistema de monitoramento. Também é importante entender que o procedimento consome bastante recursos, portanto, não o execute com muita frequência. Demora cerca de uma hora para processar 10 TB de dados, e o script é executado uma vez por dia à noite.
Meus colegas e eu estávamos interessados na questão de onde vêm os arquivos com o atributo temporário. Portanto, em cada relatório, juntamente com o nome completo do arquivo, o proprietário do NTFS é exibido. Com base nos dados coletados, foi possível descobrir que, em nossa situação, o atributo às vezes era adicionado aos arquivos ao copiar dados de discos locais encaminhados via RDP (estamos usando ativamente a tecnologia de área de trabalho remota). Mas é possível que os arquivos tenham sido inicialmente "defeituosos". Até agora, não foi possível descobrir com mais detalhes.
Ficaria muito grato se você passar em uma pequena pesquisa e compartilhar sua experiência nos comentários.