更换Powershell中比较对象中的侧指示灯

更换Powershell中比较对象中的侧指示灯,powershell,csv,Powershell,Csv,我对Powershell很陌生,我的主要信息来源是阅读书籍、观看Youtube视频和在这里提问,希望能找到帮助。所以请原谅我缺乏正确的知识 我有一个脚本,它请求一个路径,获取文件的MD5散列,并将它们导出到所需的路径中。我对这个特定的CSV文件做了一些更改,它没有显示算法、哈希和路径,就像导出到CSV时GetFileHash通常显示的那样,它显示的内容有点不同。代码如下: $p = Read-Host -Prompt 'Please type the full destination path

我对Powershell很陌生,我的主要信息来源是阅读书籍、观看Youtube视频和在这里提问,希望能找到帮助。所以请原谅我缺乏正确的知识

我有一个脚本,它请求一个路径,获取文件的MD5散列,并将它们导出到所需的路径中。我对这个特定的CSV文件做了一些更改,它没有显示算法、哈希和路径,就像导出到CSV时GetFileHash通常显示的那样,它显示的内容有点不同。代码如下:

$p = Read-Host -Prompt 'Please type the full destination path of the Installer with a \ at the end'
$number = [regex]::matches($p,"\\").count
$csv = Read-Host -Prompt 'Please enter the path where you want the CSV to be exported with the name and .csv at the end'
Get-ChildItem $p -Recurse | ForEach-Object{ Get-FileHash $_.FullName -Algorithm MD5 -ErrorAction SilentlyContinue} | Select-Object Hash,
    @{
        Name = "FileName";
        Expression = { [string]::Join("\", ($_.Path -split "\\" | Select-Object -Skip ($number))) }
    } | Export-Csv -Path $csv
这有助于我更改CSV文件中的列,并使它们看起来像这样:

| Hash | FileName |
| ---- | -------- |
| 12345abcde | SampleFile.txt|
| abcde12345 | TestFolder1\File1.txt |
|    FileName    |       Result       |
| ---------------| ------------------ |
| SampleFile.txt | Not found in source|
例如,如果上述代码的路径是C:\Users\Admin\Desktop\ExampleFiles,其中包含1SampleFile.txt和2一个包含File1.txt的TestFolder1,则导出的CSV文件中的列将以上述方式显示

我正在编写一个新的脚本,我需要它来比较我在上面的脚本中导出的哈希值。我当然会有两个CSV文件。我想在这里做的是将SideIndicator()更改为简单地键入一条更易于阅读的消息。例如,如果一个文件存在于源文件中而不存在于目标文件中,则只需键入“在目标文件中找不到”,而不必键入SideIndicators。此外,我希望它以与上面显示的相同的方式显示文件名。我希望它以与上表相同的方式显示路径,而不是完整路径

下面是我到目前为止一直在编写的代码,但它不适合我

$RHashPath = Read-Host -Prompt "Please enter the path of the source hash's CSV file"
$DHashPath = Read-Host -Prompt "Please enter the path of the destination hash's CSV file"
$number = [regex]::matches($RHashPath,"\\").count
$ReferenceHash = Import-Csv -Path $RHashPath
$DestinationHash = Import-Csv -Path $DHashPath
(Compare-Object -ReferenceObject $RHashPath -DifferenceObject $DHashPath -PassThru |
 ForEach-Object {
        if ($_.SideIndicator -eq "=>" ) {
        $_.SideIndicator = 'Not found in destination files'
    }
        if ($_.SideIndicator -eq "<=") {
            $_.SideIndicator = 'Not found in reference files'
        }
    } | Select-Object hash,
     @{
        Name = "FileName";
        Expression = { [string]::Join("\", ($_.Path -split "\\" | Select-Object -Skip ($number))) }
     }
) > C:\Users\Admin\Desktop\Difference.csv

您的脚本中存在一些问题

  • 您正在将
    $rhaspath
    转发到
    比较对象
    ,而不是
    $ReferenceHash
    ,与
    $DestinationHash
    相同

  • 您必须通过
    -Property
    参数定义
    比较对象
    应比较的属性,如中所述

  • Foreach对象
    表达式不会将任何对象返回到管道。因此,
    Select Object
    不会接收任何要处理的对象

  • 我希望我能理解你的全部问题。这是我想出的一些代码

    File1.csv:

    Hash, FileName
    abc, C:\file1.txt
    def, C:\file2.txt
    
    File2.csv:

    Hash, FileName
    abc, C:\file1.txt
    ghi, C:\file3.txt
    
    守则:

    
    $RHashPath = Resolve-Path File1.csv
    $DHashPath = Resolve-Path File2.csv
    $ReferenceHash = Import-Csv -Path $RHashPath
    $DestinationHash = Import-Csv -Path $DHashPath
    $Result = Compare-Object -ReferenceObject $ReferenceHash -DifferenceObject $DestinationHash -Property Hash, FileName  | ForEach-Object {
    
        # $_ is from type [pscustomobject] we can add a member via 'Add-Member'
        if ($_.SideIndicator -eq "=>" ) {
            $_ | Add-Member -NotePropertyName 'Result' -NotePropertyValue 'Not found in reference file'
        }
    
        # A property value appeared only in the reference object (<=) 
        if ($_.SideIndicator -eq "<=") {
            $_ | Add-Member -NotePropertyName 'Result' -NotePropertyValue 'Not found in destination file'
        }
    
        # Return the custom object to the pipeline
        $_
    } | Select-Object @{N="FileName"; E={ Split-Path $_.FileName -Leaf}}, Result
    
    
    如果要将
    $Result
    转换为CSV:

    $Result | ConvertTo-Csv | Out-File C:\Result.csv
    

    希望这就是您要查找的内容。

    看起来您只显示了与
    文件名
    列相关的差异,但是输入csv文件中也有文件哈希,当然它们也可能有所不同

    我建议您也将这些散列值添加到比较中,以便获得morfe完整输出:

    $referenceFile   = 'D:\Test\File1.csv'
    $destinationFile = 'D:\Test\File2.csv'
    $ReferenceHash   = Import-Csv -Path $referenceFile
    $DestinationHash = Import-Csv -Path $destinationFile
    
    $result = Compare-Object -ReferenceObject $ReferenceHash -DifferenceObject $DestinationHash -Property Hash,FileName |
        ForEach-Object {
            # capture the values before going into the switch
            $file = $_.FileName
            $hash = $_.Hash
            switch ($_.SideIndicator) {
                '=>' { [PsCustomObject] @{FileName = $file; Hash = $hash; Result = "Not found in reference file '$referenceFile'"  }; break }
                '<=' { [PsCustomObject] @{FileName = $file; Hash = $hash; Result = "Not found in destination file '$destinationFile'"} }
            }
        }
    
    # output on screen
    $result
    
    # output to new CSV file
    $result | Export-Csv -Path 'C:\Users\Admin\Desktop\Difference.csv' -NoTypeInformation
    

    是的,你答对了我的问题。但这并没有为我返回任何内容,我也想将结果导出到CSV中。你能给我一些建议吗?@Aithorusa我已经用CSV导出的其他信息更新了我的答案。对不起,还有两件事。结果显示在同一列中,并用
    分隔。文件名模式返回到它,只显示文件名。例如,如果其中有一个文件夹和一个文件,则FileName列应如下显示:
    Folder1\Text123.txt
    。我能够用我在一开始编写的前一段代码做到这一点,但我不知道如何在这里实现它。
    $referenceFile   = 'D:\Test\File1.csv'
    $destinationFile = 'D:\Test\File2.csv'
    $ReferenceHash   = Import-Csv -Path $referenceFile
    $DestinationHash = Import-Csv -Path $destinationFile
    
    $result = Compare-Object -ReferenceObject $ReferenceHash -DifferenceObject $DestinationHash -Property Hash,FileName |
        ForEach-Object {
            # capture the values before going into the switch
            $file = $_.FileName
            $hash = $_.Hash
            switch ($_.SideIndicator) {
                '=>' { [PsCustomObject] @{FileName = $file; Hash = $hash; Result = "Not found in reference file '$referenceFile'"  }; break }
                '<=' { [PsCustomObject] @{FileName = $file; Hash = $hash; Result = "Not found in destination file '$destinationFile'"} }
            }
        }
    
    # output on screen
    $result
    
    # output to new CSV file
    $result | Export-Csv -Path 'C:\Users\Admin\Desktop\Difference.csv' -NoTypeInformation
    
    FileName                         Hash   Result                                           
    --------                         ----   ------                                           
    D:\SampleFile2.txt               123456 Not found in reference file 'D:\Test\File1.csv'  
    D:\SomePath\SubFolder\A_File.txt acb987 Not found in reference file 'D:\Test\File1.csv'  
    D:\SampleFile.txt                123456 Not found in destination file 'D:\Test\File2.csv'
    D:\SomePath\SubFolder\A_File.txt acbdef Not found in destination file 'D:\Test\File2.csv'