PoshCode Logo PowerShell Code Repository

Compare-Folders.ps1 by Brian 3 years ago
embed code: <script type="text/javascript" src="http://PoshCode.org/embed/4781"></script>download | new post

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

  1. #require -version 2.0
  2. <#
  3. .SYNOPSIS
  4. 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
  5.  
  6. .DESCRIPTION
  7. Version - 1.0.0
  8. This PowerShell Script will compare all of the files in the same directory on two or more different computers
  9.  
  10. .EXAMPLE
  11. .\Compare-Folders.ps1 -computers @("srv-1","srv-2") -path "D:\Inetpub"
  12.  
  13. .PARAMETER Computers
  14. Specifies the computers to compare. Mandatory parameter
  15.  
  16. .PARAMETER Path
  17. Specifies the folder to check on the computers
  18.  
  19. .PARAMETER csv
  20. Full Path to CSV file. If not passed, then results will display to the screen
  21.  
  22. .NOTES
  23.  
  24. #>
  25.  
  26. [CmdletBinding(SupportsShouldProcess=$true)]
  27. param (
  28.         [Parameter(Mandatory=$true)] [string[]] $computers,
  29.         [Parameter(Mandatory=$true)] [string] $path,
  30.     [string] $csv
  31. )
  32.  
  33. function Reduce-Set
  34. {
  35.         param(
  36.                 [Parameter(ValueFromPipeline=$true)]
  37.                 [HashTable] $ht
  38.         )
  39.        
  40.         begin {
  41.                 Set-Varible -Name differences -Values @()
  42.         }
  43.         process {              
  44.                 Write-Verbose "Comparing Keys . . ."                           
  45.                 foreach ( $key in $ht.Keys ) {
  46.                         if( $ht[$key].Count -eq 1 ) {          
  47.                                 $differences += (New-Object PSObject -Property @{
  48.                                         File = $ht[$key] | Select -ExpandProperty Name
  49.                                         System = $ht[$key] | Select -ExpandProperty System
  50.                                         Hash = $ht[$key] | Select -ExpandProperty FileHash
  51.                                 })
  52.                         }
  53.                         elseif( ($ht[$key] | Select -Unique -ExpandProperty FileHash).Count -ne 1 )     {
  54.                                 foreach( $diff in $ht[$key] ) {
  55.                                         $differences += (New-Object PSObject -Property @{
  56.                                                 File =  $diff.Name
  57.                                                 System = $diff.System
  58.                                                 Hash = $diff.FileHash
  59.                                         })
  60.                                 }
  61.                         }
  62.                 }
  63.                
  64.         }
  65.         end {
  66.                 return $differences
  67.         }
  68. }
  69.  
  70. $map = {
  71.         param ( [string] $directory )
  72.        
  73.         function Get-Hash {
  74.         param([string] $file)
  75.                 $fileStream = [system.io.file]::openread($file)
  76.             $hasher = [System.Security.Cryptography.HashAlgorithm]::create("md5")
  77.             $hash = $hasher.ComputeHash($fileStream)
  78.             $fileStream.Close()
  79.             $md5 = ([system.bitconverter]::tostring($hash)).Replace("-","")
  80.             return ( $md5 )
  81.     }
  82.  
  83.     Set-Variable -Name files -Value @()
  84.        
  85.         Write-Verbose ("Working on - {0}" -f $ENV:COMPUTERNAME)
  86.  
  87.         foreach( $file in (Get-ChildItem $directory -Recurse | Where { $_.PSIsContainer -eq $false } ) ) {
  88.                 $files += New-Object PSObject -Property @{
  89.             Name = $file.FullName
  90.                         System = $ENV:COMPUTERNAME
  91.             FileHash = (Get-Hash $file.FullName)
  92.                 }
  93.         }
  94.         return $files
  95. }
  96.  
  97. function main
  98. {
  99.         $results = Invoke-Command -ComputerName $computers -ScriptBlock $map -ArgumentList $path |
  100.         Select Name, FileHash, System |
  101.         Group-Object -Property Name -AsHashTable |
  102.         Reduce-Set
  103.        
  104.         if( ![string]::IsNullOrEmpty($csv) ) {
  105.                 $results | Export-Csv -Encoding Ascii -NoTypeInformation $csv
  106.                 Invoke-Item $csv
  107.         }
  108.         else {
  109.                 return $results
  110.         }
  111. }
  112. main

Submit a correction or amendment below (
click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:


Remember me