如何比较2个文件夹下的文件与PowerShell;

时间:2015-09-18 12:19:55

标签: powershell

我是PowerShell的新手,并尝试从少数论坛和msdn学习东西。现在我得到了我的学习小组的一些要求。

我试图在PowerShell中将2个文件夹的文件相互比较,以便进行有效的文件比较,我正在使用MD5哈希。 直到现在我已经创建了这样的代码,

char[] toWirte = {913,914,915,916};
OutputStream out = new BufferedOutputStream(new FileOutputStream("test.txt"));
out.write(new String(toWirte).getBytes("UTF-16"));

$ SourceFolderList = @()& $ DestinationFolderList = @()是名称和数组的数组。 FullName属性。

现在我正在尝试使用$ SourceFolderList&中匹配的值创建一个新数组。 $ DestinationFolderList(我希望我的方式正确吗?!)

但问题是,我不知道如何循环遍历数组中的每个项目,并从2个文件夹中获取每个文件的全名作为参数传递给MD5hash函数。

我正在尝试这种方式

[Cmdletbinding()]
Param
(
[Parameter(Position=0, Mandatory)][ValidateScript({ Test-Path -Path $_ })][string]$SourceFolder,
[Parameter(Position=1, Mandatory)][ValidateScript({ Test-Path -Path $_ })][string]$DestinationFolder
) 
$SourceFolderList =@()
$DestinationFolderList =@()

$Sourcefiles = @(Get-ChildItem -Path $SourceFolder -Filter *.log)
foreach($srcFile in $Sourcefiles )
{
    $SourceFolderHash = [ordered]@{}
    $SourceFolderHash.Name = $srcFile.Name
    $SourceFolderHash.FullName = $srcFile.FullName
    $obj = New-Object PSObject -Property $SourceFolderHash
    $SourceFolderList+= $obj
}

$Destfiles = @(Get-ChildItem -Path $DestinationFolder -Filter *.log)
foreach($Destfile in $Destfiles )
{
    $DestinationFolderHash = [ordered]@{}
    $DestinationFolderHash.Name = $Destfile.Name
    $DestinationFolderHash.FullName = $Destfile.FullName
    $obj = New-Object PSObject -Property $DestinationFolderHash
    $DestinationFolderList+= $obj
}

在第一种方式中我没有得到正确的文件路径<<目标文件夹的文件路径>>

的索引不匹配

在第二种方式中,我根本没有获得文件的完整路径。

如果我以错误的方式达到我的要求,请纠正我。 请帮我解决这个问题。

1 个答案:

答案 0 :(得分:1)

我认为通过将文件信息收集到数组中,您的任务将变得更加困难。为什么不直接遍历源文件夹中的文件,并将其哈希值与动态目标文件夹中的文件哈希进行比较:

function Compare-Folders
{
    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [string]$Source,

        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [string]$Destinaton,

        [Parameter(ValueFromPipelineByPropertyName = $true)]
        [string]$Filter
    )

    Process
    {
        # Iterate over files in source folder, skip folders
        Get-ChildItem -Path $Source -Filter $Filter | Where-Object {!$_.PsIsContainer} | ForEach-Object {
            # Generate file name in destination folder
            $DstFileName = Resolve-Path -Path (Join-Path -Path $Destinaton -ChildPath (Split-Path -Path $_.FullName -Leaf))

            # Create hashtable with filenames and hashes
            $Result = @{
                SourceFile = $_.FullName
                SourceFileHash = (Get-FileHash -Path $_.FullName -Algorithm MD5).Hash
                DestinationFile = $DstFileName
                DestinationFileHash = (Get-FileHash -Path $DstFileName -Algorithm MD5).Hash
            }

            # Check if file hashes are equal and add result to hashtable
            $Result.Add('IsEqual', ($Result.SourceFileHash -eq $Result.DestinationFileHash))

            # Output PsObject from hashtable
            New-Object -TypeName psobject -Property $Result |
                Select-Object -Property SourceFile, SourceFileHash , DestinationFile, DestinationFileHash, IsEqual
        }
    }
}