1

我之前曾问过一个关于这个脚本的问题,但是我需要帮助的部分得到了修复,所以我决定问一个新问题。

我正在研究一个 PS 脚本,该脚本获取目录中每个文件的哈希值以及位于其他位置的一些特定文件,将它们组合成一个 csv,然后将它们与之前捕获的基线进行比较。然后有一个 for each 循环,其中每个具有不同散列的文件都被输出到一个 XML 文件,其中包含算法、散列、文件路径和最后修改日期的信息。

### This PowerShell 4.0 script compares the MD5 hash of each file in    ###
### a directory in it's current state and compares it with a baseline   ###
### copy taken previously. If no baseline exists, a new one is created. ###
### ***The first time this script is run, a false-positive report       ###

# Variables
$DateTime = Get-Date -format M.d.yyyy.hh.mm.ss
$Hashstore = "d:\Baseline.txt"
$HashCompare = "d:\Difference_$DateTime.txt"
$HashTemp = "d:\hashtemp_$DateTime.txt"
$FileDir = "d:\scripts\"
$CRQLocation = "d:\Change Request.csv"
$ScriptLocation = "d:\FileChecker.ps1"
$OutPut = "d:\Results_$DateTime.xml"

# Check if Baseline.txt Exists
If (Test-Path $Hashstore)
    # // File exists
    {
}
Else {
     # // File does not exist - Should never happen!
     $RefreshHash = dir $FileDir -Recurse | Get-FileHash -Algorithm MD5
     $RefreshScript = Get-FileHash $ScriptLocation -Algorithm MD5
     $RefreshCRQ = Get-FileHash $CRQLocation -Algorithm MD5

}

## Generate new Compare Hash.txt
$HashNew = dir $FileDir -Recurse | Get-FileHash -Algorithm MD5
$HashNew | Export-Csv -Path $HashCompare -NoTypeInformation -Force

#Get hash of this script
$HashScript = Get-FileHash $ScriptLocation -Algorithm MD5
$HashScript | Export-Csv -append -Path $HashCompare -NoTypeInformation -Force

#Get hash of CRQ Log
$HashCRQ = Get-FileHash $CRQLocation -Algorithm MD5
$HashCRQ | Export-Csv -append -Path $HashCompare -NoTypeInformation -Force

# Get Hash of baseline.txt
$HashBaseline = Get-FileHash -Path $Hashstore -Algorithm MD5

# Get Hash of hashcompare.txt
$HashDiff = Get-FileHash -Path $HashCompare -Algorithm MD5

# If changed, output hash to storage, and flag changes
If ($HashBaseline.hash -eq $HashDiff.hash) {
    Add-Content -Path D:\success.$DateTime.txt -Value " Source Files ARE EQUAL </p>"
}
Else {
    Add-Content -Path D:\failure.$DateTime.txt -Value "Source Files NOT EQUAL </p>"
    $HashNew | Export-Csv -Path $HashTemp -NoTypeInformation -Force

    # Storing a collection of differences in $Diffs
    $Diffs = Compare-Object -ReferenceObject (Import-Csv $Hashstore) -DifferenceObject (Import-Csv $HashCompare)

    Foreach ($Diff in $Diffs) {
        $DiffHashInfo = $Diff | Select-Object -ExpandProperty InputObject
        $DiffFileInfo =  Get-ChildItem -Path $DiffHashInfo.Path

        # Creating a list of properties for the information you need
        $DiffObjProperties = [ordered]@{'Algorithm'=$DiffHashInfo.Algorithm
                               'Hash'=$DiffHashInfo.Hash
                               'File Path'=$DiffFileInfo.FullName
                               'Last edit time'=$DiffFileInfo.LastWriteTime
                               }

        # Building a custom object from the list of properties in $DiffObjProperties
        $DiffObj = New-Object -TypeName psobject -Property $DiffObjProperties
        $DiffObj
    }
}
$DiffObj | ConvertTo-Xml -As String -NoTypeInformation | Out-File $OutPut

我从用户 Mathieu Buisson 那里得到了极好的帮助,但我遇到了另一个错误。

我的理解是,循环会获取每个发现不同的文件,转换我需要的字段,然后将它们全部附加到文件中。最后一行将这些转换为 xml 并输出它们。

我的问题是输出。基线和差异文件创建正确,success/fail.txt 文件生成且准确。问题是 xml 要么出现空白,要么只列出以前不存在的文件。在这个程度上,它只在 xml 中列出了一个文件,即使 PS 控制台显示两个或更多。

如何获取 XML 中已更改文件的完整列表?

如果还有我需要提供的信息,请告诉我。

非常感谢您的帮助!!

4

1 回答 1

2
$HashCRQ = Get-FileHash $CRQLocation -Algorithm MD5
$HashCRQ | Export-Csv -append -Path $HashCompare -NoTypeInformation -Force

您正在将文件 d:\Change Request.csv 的哈希添加到 $HashCompare。

$HashScript = Get-FileHash $ScriptLocation -Algorithm MD5
$HashScript | Export-Csv -append -Path $HashCompare -NoTypeInformation -Force

您正在将文件 d:\FileChecker.ps1 的哈希添加到 $Hashcompare

这两个文件不位于 $FileDir,所以我不明白为什么要将它们添加到 $HashCompare,因为当您将 $HashCompare 与 $Hashstore 进行比较时,您正在将 $FileDir 的内容与 $FileDir 的内容进行比较 + 2个其他文件。我假设 $Hashtore 包含 $FileDir 内容的哈希值,但我只能假设因为脚本没有说明 $Hashstore 的内容是如何创建的。

$HashNew | Export-Csv -Path $HashTemp -NoTypeInformation -Force

如果存在差异,则将 $FileDir 内容的哈希(不包括上面提到的 2 个附加文件)发送到 $Hashtemp。但是文件 $HashTemp 没有在脚本的其他任何地方使用。

那么,你想比较什么?$HashStore 与 $fileDir + $HashCRQ + $HashCRQ 的当前内容的哈希值?如果是这样,$Diffs 是正确的。或者 $HashStore 与 $fileDir 的当前内容的哈希值?如果是这样, $Diffs 应该是:

Compare-Object -ReferenceObject (Import-Csv $Hashstore) -DifferenceObject (Import-Csv $HashTemp)

关于 XML 输出,$DiffObj 是在 Foreach 循环内创建的,因此它代表每个单独的不同文件,并且每次我们通过循环时都会更改。所以 $DiffObj 实际上是一个对象,这就是为什么 ConvertTo-Xml 最多只会显示一个对象。

你需要这样做:

创建一个变量作为空数组,它将累积 $DiffObj 的每次迭代:

$DiffObjCollection = @()

注意:您需要在 foreach 循环之外定义此变量,否则每次我们通过循环时它将被重置为空数组。

然后,我们将 $DiffObj 的每个单独迭代存储在这个“集合变量”中:

$DiffObjCollection += $DiffObj

注意:这需要在 Foreach 循环的末尾,但在其中,以确保我们每次通过循环时都将 $DiffObj 添加到 $DiffObjCollection。

最后,在浏览完每个不同的文件之后,我们可以使用我们的“集合变量”并将这个对象集合转换为 XML:

$DiffObjCollection | ConvertTo-Xml -As String -NoTypeInformation | Out-File $OutPut

注意:这需要在 Foreach 循环之外并且在脚本的末尾。

于 2014-08-23T11:07:11.743 回答