将桌面和文档与其备份进行比较,并生成一个 output.txt 文件,突出显示它们之间的不同文件夹和文件

Comparing Desktop and documents with their backup and produce an output.txt file that highlights the different folders and files between them

有人可以帮助我吗?对 powershell 还是个新手,我正在比较我的文档和桌面镜像,以使用几种不同的代码检查我的备份解决方案。下面的那个是为了检查 documents/desktop 及其镜像文件夹,并准确地告诉我源和目标之间有哪些文件 'different' 并将其输出到同一个 output.txt 文件(不确定是否它会覆盖它)。当我单独为我的文档执行此操作时,当我想为我的桌面尝试代码时它会起作用,它根本不会输出任何内容。有什么建议吗?

function Get-Directories ($path)
{
    $PathLength = $path.length
    Get-ChildItem $path -exclude *.pst,*.ost,*.iso,*.lnk | % {
        Add-Member -InputObject $_ -MemberType NoteProperty -Name RelativePath -Value $_.FullName.substring($PathLength+1)
        $_
    }
}

Compare-Object (Get-Directories $Folder3) (Get-Directories $Folder4) -Property RelativePath | Sort RelativePath, Name -desc | Out-File  C:\Users\desktop\output.txt

因为你在列出文件时没有使用 -Recurse,你可以只使用文件名而不是添加相对路径 属性:

$folder1 = gci 'C:\Users\username\desktop' -exclude *.pst,*.ost,*.iso,*.lnk
$folder2 = gci 'D:\desktop' -exclude *.pst,*.ost,*.iso,*.lnk
Compare-Object $folder1 $folder2 -Property Name,Length

Name     Length SideIndicator
----     ------ -------------
test.txt    174 =>           
test.csv    174 <=           

# Alternatively, use -PassThru to keep the whole object:
Compare-Object $folder1 $folder2 -Property Name,Length -PassThru | select SideIndicator,FullName,Length,LastWriteTime

SideIndicator FullName                  Length LastWriteTime       
------------- --------                  ------ -------------       
=>            D:\desktop                   174 7/14/2021 2:47:09 PM
<=            C:\Users\username\desktop    174 7/14/2021 2:47:09 PM

使用 Out-File -Append 将输出附加到文件。


至于对当前脚本进行故障排除,请尝试手动检查 RelativePath 属性 是否已为您正确设置:

(Get-Directories $Folder3).RelativePath
(Get-Directories $Folder4).RelativePath

最后,我建议使用 robocopy 而不是 powershell 来备份这样的东西,因为它可以使用备份权限(对于锁定的文件)并且可以一次复制多个文件,但这是个人偏好:

robocopy source destination /b /mir /mt /r:0 /w:0

/b - Runs robocopy in backup mode. Will copy everything as long as you are an Administrator
/mir - Mirrors everything from the source to the destination
/mt - Copies up to 8 files at a time
/r:0 - Sets it to not retry a file, default is like a million retries
/w:0 - Sets the time to 0 seconds between retries - default is like 30 seconds

source: https://community.spiceworks.com/topic/286190-transfer-user-profiles-using-robocopy

根据您问题的早期修订判断,您的问题不是您的代码没有输出 任何东西,而是输出 为空Name 属性 值.

因此,您的代码中唯一缺少的是 Compare-Object-PassThru 开关 :

Compare-Object -PassThru (Get-Directories $Folder3) (Get-Directories $Folder4) -Property RelativePath | 
  Sort RelativePath, Name -desc | 
    Out-File C:\Users\desktop\output.txt

没有 -PassThru, Compare-Object 输出 [pscustomobject] 个具有 .SideIndicator 属性 的实例(表示差异对象独占哪一侧)并且仅传递给 -Property.

的比较属性
  • 也就是说,在您最初的尝试中,Compare-Object 输出对象只有 .SideIndicator.RelativePath 属性,而 none 来自 Get-ChildItem 的原始 [System.IO.FileInfo] 个实例的其他属性,例如 .Name.LastWriteTime、...

-PassThru原始对象被传递,装饰有ETS(扩展类型系统).SideIndicator 属性(以与添加 .RelativePath 属性 相同的方式装饰),稍后访问 .Name 属性 将按预期工作。

注:

  • 因为 Out-File 然后收到完整的(和修饰的)[System.IO.FileInfo] 实例,您可能想要限制通过 Select-Object 调用预先写入的属性。
    此外,您可以选择 结构化 输出格式,通过 Export-Csv for instance, given that the formatting that Out-File apply 仅适用于人类观察者,不适用于程序化处理。

  • $_.FullName.substring($PathLength+1) 在你的 Get-Directories 应该是 $_.FullName.substring($PathLength),否则你会切断第一个字符。