# encoding: ascii
# api: powershell
# title: Compare-Folders.ps1
# description: This PowerShell Script will compare all of the files in the same directory on two or more different computers. It will compute the MD5 hash of a file and use that to compare
# version: 1.0.0
# type: script
# author: Brian
# license: CC0
# function: Reduce-Set
# x-poshcode-id: 4781
# x-archived: 2016-10-25T20:25:47
# x-published: 2016-01-08T14:45:00
#
#
#require -version 2.0
<#
.SYNOPSIS
This PowerShell Script will compare all of the files in the same directory on two or more different computers. It will compute the MD5 hash of a file and use that to compare
.DESCRIPTION
Version - 1.0.0
This PowerShell Script will compare all of the files in the same directory on two or more different computers
.EXAMPLE
.\Compare-Folders.ps1 -computers @("srv-1","srv-2") -path "D:\Inetpub"
.PARAMETER Computers
Specifies the computers to compare. Mandatory parameter
.PARAMETER Path
Specifies the folder to check on the computers
.PARAMETER csv
Full Path to CSV file. If not passed, then results will display to the screen
.NOTES
#>
[CmdletBinding(SupportsShouldProcess=$true)]
param (
[Parameter(Mandatory=$true)] [string[]] $computers,
[Parameter(Mandatory=$true)] [string] $path,
[string] $csv
)
function Reduce-Set
{
param(
[Parameter(ValueFromPipeline=$true)]
[HashTable] $ht
)
begin {
Set-Varible -Name differences -Values @()
}
process {
Write-Verbose "Comparing Keys . . ."
foreach ( $key in $ht.Keys ) {
if( $ht[$key].Count -eq 1 ) {
$differences += (New-Object PSObject -Property @{
File = $ht[$key] | Select -ExpandProperty Name
System = $ht[$key] | Select -ExpandProperty System
Hash = $ht[$key] | Select -ExpandProperty FileHash
})
}
elseif( ($ht[$key] | Select -Unique -ExpandProperty FileHash).Count -ne 1 ) {
foreach( $diff in $ht[$key] ) {
$differences += (New-Object PSObject -Property @{
File = $diff.Name
System = $diff.System
Hash = $diff.FileHash
})
}
}
}
}
end {
return $differences
}
}
$map = {
param ( [string] $directory )
function Get-Hash {
param([string] $file)
$fileStream = [system.io.file]::openread($file)
$hasher = [System.Security.Cryptography.HashAlgorithm]::create("md5")
$hash = $hasher.ComputeHash($fileStream)
$fileStream.Close()
$md5 = ([system.bitconverter]::tostring($hash)).Replace("-","")
return ( $md5 )
}
Set-Variable -Name files -Value @()
Write-Verbose ("Working on - {0}" -f $ENV:COMPUTERNAME)
foreach( $file in (Get-ChildItem $directory -Recurse | Where { $_.PSIsContainer -eq $false } ) ) {
$files += New-Object PSObject -Property @{
Name = $file.FullName
System = $ENV:COMPUTERNAME
FileHash = (Get-Hash $file.FullName)
}
}
return $files
}
function main
{
$results = Invoke-Command -ComputerName $computers -ScriptBlock $map -ArgumentList $path |
Select Name, FileHash, System |
Group-Object -Property Name -AsHashTable |
Reduce-Set
if( ![string]::IsNullOrEmpty($csv) ) {
$results | Export-Csv -Encoding Ascii -NoTypeInformation $csv
Invoke-Item $csv
}
else {
return $results
}
}
main