我想運行一個 powershell 腳本,該腳本可以由用戶提供目錄名稱,然后它將檢查目錄、子目錄和這些目錄的所有檔案內容,以比較它們是否彼此相同。有 8 臺服務器應該都有相同的檔案和內容。下面的代碼似乎沒有按照我的意圖做。我已經看到了 Compare-Object、Get-ChildItem 和 Get-FileHash 的使用,但還沒有找到我確信確實可以完成任務的正確組合。任何和所有的幫助表示贊賞!
$35 = "\\server1\"
$36 = "\\server2\"
$37 = "\\server3\"
$38 = "\\server4\"
$45 = "\\server5\"
$46 = "\\server6\"
$47 = "\\server7\"
$48 = "\\server8\"
do{
Write-Host "|1 : New |"
Write-Host "|2 : Repeat|"
Write-Host "|3 : Exit |"
$choice = Read-Host -Prompt "Please make a selection"
switch ($choice){
1{
$App = Read-Host -Prompt "Input Directory Application"
}
2{
#rerun
}
3{
exit; }
}
$c35 = $35 "$App" "\*"
$c36 = $36 "$App" "\*"
$c37 = $37 "$App" "\*"
$c38 = $38 "$App" "\*"
$c45 = $45 "$App" "\*"
$c46 = $46 "$App" "\*"
$c47 = $47 "$App" "\*"
$c48 = $48 "$App" "\*"
Write-Host "Comparing Server1 -> Server2"
if((Get-ChildItem $c35 -Recurse | Get-FileHash | Select-Object Hash,Path).hash -eq (Get-ChildItem $c36 -Recurse | Get-FileHash | Select-Object Hash,Path).hash){"Identical"}else{"NOT Identical"}
Write-Host "Comparing Server1 -> Server3"
if((Get-ChildItem $c35 -Recurse | Get-FileHash | Select-Object Hash,Path).hash -eq (Get-ChildItem $c37 -Recurse | Get-FileHash | Select-Object Hash,Path).hash){"Identical"}else{"NOT Identical"}
Write-Host "Comparing Server1 -> Server4"
if((Get-ChildItem $c35 -Recurse | Get-FileHash | Select-Object Hash,Path).hash -eq (Get-ChildItem $c38 -Recurse | Get-FileHash | Select-Object Hash,Path).hash){"Identical"}else{"NOT Identical"}
Write-Host "Comparing Server1 -> Server5"
if((Get-ChildItem $c35 -Recurse | Get-FileHash | Select-Object Hash,Path).hash -eq (Get-ChildItem $c45 -Recurse | Get-FileHash | Select-Object Hash,Path).hash){"Identical"}else{"NOT Identical"}
Write-Host "Comparing Server1 -> Server6"
if((Get-ChildItem $c35 -Recurse | Get-FileHash | Select-Object Hash,Path).hash -eq (Get-ChildItem $c46 -Recurse | Get-FileHash | Select-Object Hash,Path).hash){"Identical"}else{"NOT Identical"}
Write-Host "Comparing Server1 -> Server7"
if((Get-ChildItem $c35 -Recurse | Get-FileHash | Select-Object Hash,Path).hash -eq (Get-ChildItem $c47 -Recurse | Get-FileHash | Select-Object Hash,Path).hash){"Identical"}else{"NOT Identical"}
Write-Host "Comparing Server1 -> Server8"
if((Get-ChildItem $c35 -Recurse | Get-FileHash | Select-Object Hash,Path).hash -eq (Get-ChildItem $c48 -Recurse | Get-FileHash | Select-Object Hash,Path).hash){"Identical"}else{"NOT Identical"}
} until ($choice -eq 3)
uj5u.com熱心網友回復:
這是一個示例函式,它試圖有效地將一個參考目錄與多個差異目錄進行比較。它通過首先比較最容易獲得的資訊并在第一個差異處停止來做到這一點。
- 一次獲取有關參考目錄中檔案的所有相關資訊,包括哈希(盡管這可以通過僅在必要時獲取哈希來更優化)。
- 對于每個差異目錄,按以下順序進行比較:
- 檔案數- 如果不同,那么顯然目錄不同
- 相對檔案路徑- 如果不能在參考目錄中找到來自不同目錄的所有路徑,則目錄不同
- 檔案大小- 應該很明顯
- 檔案哈希- 僅當檔案大小相等時才需要計算哈希
Function Compare-MultipleDirectories {
param(
[Parameter(Mandatory)] [string] $ReferencePath,
[Parameter(Mandatory)] [string[]] $DifferencePath
)
# Get basic file information recursively by calling Get-ChildItem with the addition of the relative file path
Function Get-ChildItemRelative {
param( [Parameter(Mandatory)] [string] $Path )
Push-Location $Path # Base path for Get-ChildItem and Resolve-Path
try {
Get-ChildItem -File -Recurse | Select-Object FullName, Length, @{ n = 'RelativePath'; e = { Resolve-Path $_.FullName -Relative } }
} finally {
Pop-Location
}
}
Write-Verbose "Reading reference directory '$ReferencePath'"
# Create hashtable with all infos of reference directory
$refFiles = Get-ChildItemRelative $ReferencePath |
Select-Object *, @{ n = 'Hash'; e = { (Get-FileHash $_.FullName -Algorithm MD5).Hash } } |
Group-Object RelativePath -AsHashTable
# Compare content of each directory of $DifferencePath with $ReferencePath
foreach( $diffPath in $DifferencePath ) {
Write-Verbose "Comparing directory '$diffPath' with '$ReferencePath'"
$areDirectoriesEqual = $false
$differenceType = ''
$diffFiles = Get-ChildItemRelative $diffPath
# Directories must have same number of files
if( $diffFiles.Count -eq $refFiles.Count ) {
# Find first different path (if any)
$firstDifferentPath = $diffFiles | Where-Object { -not $refFiles.ContainsKey( $_.RelativePath ) } |
Select-Object -First 1
if( -not $firstDifferentPath ) {
# Find first different content (if any) by file size comparison
$firstDifferentFileSize = $diffFiles |
Where-Object { $refFiles[ $_.RelativePath ].Length -ne $_.Length } |
Select-Object -First 1
if( -not $firstDifferentFileSize ) {
# Find first different content (if any) by hash comparison
$firstDifferentContent = $diffFiles |
Where-Object { $refFiles[ $_.RelativePath ].Hash -ne (Get-FileHash $_.FullName -Algorithm MD5).Hash } |
Select-Object -First 1
if( -not $firstDifferentContent ) {
$areDirectoriesEqual = $true
}
else {
$differenceType = 'Content'
}
}
else {
$differenceType = 'FileSize'
}
}
else {
$differenceType = 'Path'
}
}
else {
$differenceType = 'FileCount'
}
# Output comparison result
[PSCustomObject]@{
ReferencePath = $ReferencePath
DifferencePath = $diffPath
Equal = $areDirectoriesEqual
DiffCause = $differenceType
}
}
}
使用示例:
# compare each of directories B, C, D, E, F against A
Compare-MultipleDirectories -ReferencePath 'A' -DifferencePath 'B', 'C', 'D', 'E', 'F' -Verbose
輸出示例:
ReferencePath DifferencePath Equal DiffCause
------------- -------------- ----- ---------
A B True
A C False FileCount
A D False Path
A E False FileSize
A F False Content
DiffCause列為您提供函式認為目錄不同的原因的資訊。
筆記:
Select-Object -First 1在我們得到第一個結果后停止搜索是一個巧妙的技巧。它是高效的,因為它不會首先處理所有輸入并洗掉除第一項之外的所有內容,而是在找到第一項后實際上取消管道。Group-Object RelativePath -AsHashTable創建檔案資訊的哈希表,以便屬性可以快速查找RelativePath。- 空子目錄被忽略,因為該函式只查看檔案。例如。如果參考路徑包含一些空目錄但差異路徑不包含,并且所有其他目錄中的檔案相等,則該函式將目錄視為相等。
- 我選擇了 MD5 演算法,因為它比 使用的默認 SHA-256 演算法更快
Get-FileHash,但它不安全。有人可以輕松地操縱不同的檔案,使其具有與原始檔案相同的 MD5 哈希值。不過,在受信任的環境中,這無關緊要。-Algorithm MD5如果您需要更安全的比較,請洗掉。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/531498.html
標籤:电源外壳服务器目录
上一篇:為什么我的腳本在從命令列運行時可以作業,但在Java代碼中卻不行?
下一篇:函式單獨作業,但不在腳本內
