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