Compare two locations, report on differences

Compare two folder locations, report on differences and copy over files from source if changes are under max size.

I need the script to ensure large amount of changes are not occurring without my knowledge

Script compares the files in the source and destination and makes note of the changed files in the source location

  • file is a new file (compared to destination)
  • file has been modified (compared to destination)
  • if a file is deleted from source, (don’t care, doesn’t add to max size)
    Grab the total size of those new/changed files:
    if size is less than max size:
    -do a robocopy /mir to the destination
    -log all files changed to a specific location
    if size is greater than max size
    -send an email to me@email.com to let them know the source location, destination location and total size
    -script logs information to specific location.
$maxsizeinchanges = 100MB
$date = Get-Date -UFormat "%Y-%m-%d"

$source = Get-ChildItem -Path C:\TEMP\location1 -Recurse | Measure-Object -Property length -Sum
$sourcesize = "{0:N2}" -f ($source.sum / 1MB) + " MB"

$destination = Get-ChildItem -Path C:\TEMP\location2 -Recurse | Measure-Object -Property length -Sum
$destinationsize = "{0:N2}" -f ($destination.sum / 1MB) + " MB"

$totalsize = "{0:N2}" -f (($source.Sum + $destination.Sum) / 1MB) + "MB"
$sizediff = [System.Math]::Abs($destination.Sum - $source.Sum)


if($sizediff -lt $maxsizeinchanges)
{
    #Do a robocopy /mir to the destination
    #Log all files changed to specific location
    robocopy C:\TEMP\location1 C:\TEMP\location2 /MIR /IS /L /R:3 /W:3 >> C:\TEMP\logs\$date.txt
}
else
{
    Send-MailMessage -To "You <you@email.com>" -from "Me <you@email.com>" -Subject $date -Body "test" -SmtpServer smtprelay.server
}

I’ve written the code above but i’m only able to check the size difference between the source and the destination. If the $sizediff is less than the $maxsizeinchanges then proceed with the robocopy mirror, if not then send an email to me@email.com

I need to somehow keep track of which files are getting modified and which files are new. Then get the size of these files and compare it to $maxsizeinchanges. Any ideas on how i can do that?

Alright, so i’ve decided to take this on with a different approach.

“robocopy C:\TEMP\location1 C:\TEMP\location2 /MIR /IS /L /R:3 /W:3 >> C:\TEMP\logs$date.txt” will give me the output below into a text file.


ROBOCOPY :: Robust File Copy for Windows

Started : Friday, May 9, 2014 8:00:44 AM
Source : C:\TEMP\location1
Dest : C:\TEMP\location2\

Files : *.*

Options : . /L /S /E /DCOPY:DA /COPY:DAT /PURGE /MIR /IS /R:3 /W:3


                  14	C:\TEMP\isantillan1\
    Same      		     190	20amp.txt
    Same      		   49597	AppC_Field_Methods.docx
    Same      		   65770	Appendix_d_qaqc.docx
    Newer     		   46031	Capture.PNG
    Newer     		   23517	Capture1.PNG
    Same      		   50041	Capture2.PNG
    Newer     		   43427	Capture3.PNG
    New File  		    7304	franklin_and_prokopik_inv_199451_amount_$216.10 _for_claim_PL-00-00-0564-test.pdf
    New File  		    7415	franklin_and_prokopik_inv_199451_amount_$216.10 _for_claim_PL-00-00-0564.pdf
    New File  		  535040	PhotomergeUI.8BF
    New File  		  15.0 m	public_drive_log.txt
    New File  		   15657	test.docx
    New File  		    4053	tvik_log.txt
    New File  		    1062	tvik_log2.txt

Is there a way for me to output this into an object? Once i have this object, i would like to grab the ones that are “Newer” and “New file” and put it into another object. With this new object, i will get the size of this object and compare it to $maxsizeinchange. If the size difference is less than the $maxsizeinchanges then proceed with the robocopy mirror, if not, then send an email to me@email.com

The output from Robocopy is pure text - to turn that into an object, you’d have to parse the text for whatever information you wanted.

http://technet.microsoft.com/en-us/magazine/2008.09.windowspowershell.aspx#id0080030

Found this old article by you Don. I’ll give it a shot and let you know how it goes.

I was able to get what i need by doing the following code, (see attached file)

Select-String -Path C:\TEMP\logs\2014-05-09.txt -Pattern “Newer”, “New File”

I will then get this output from the code above.

C:\TEMP\logs\2014-05-09.txt:20: Newer 46031 Capture.PNG
C:\TEMP\logs\2014-05-09.txt:21: Newer 23517 Capture1.PNG
C:\TEMP\logs\2014-05-09.txt:23: Newer 43427 Capture3.PNG
C:\TEMP\logs\2014-05-09.txt:24: New File 7304 franklin_and_prokopik_inv_199451_amount_$216.10 for_claim_PL-00-00-0564-test.pdf
C:\TEMP\logs\2014-05-09.txt:25: New File 7415 franklin_and_prokopik_inv_199451_amount
$216.10 _for_claim_PL-00-00-0564.pdf
C:\TEMP\logs\2014-05-09.txt:26: New File 535040 PhotomergeUI.8BF
C:\TEMP\logs\2014-05-09.txt:27: New File 15.0 m public_drive_log.txt
C:\TEMP\logs\2014-05-09.txt:28: New File 15657 test.docx
C:\TEMP\logs\2014-05-09.txt:29: New File 4053 tvik_log.txt
C:\TEMP\logs\2014-05-09.txt:30: New File 1062 tvik_log2.txt

with this tho, I would like to just get the filenames above and get their file size by doing :
Get-ChildItem -Path C:\TEMP\isantillan1 -Recurse | Measure-Object -Property length -Sum

How do i go on about doing this?

I’m sure there’s a much more elegant way to do this, but this code will work for you:

$path = "C:\temp\TF.iQmetrix.CheckinPolicies.txt"
$patterns = @("test", "is")

# Get all of the lines contains one or more patterns and loop through them.
$linesContainingPattern = (Select-String -Pattern $patterns -Path $path)
$fileNames = [string[]]@()	# Initialize empty string array to hold file names.
foreach ($line in $lines)
{
	# If we can find the FileName in this line.
	$match = [regex]::Match($line, "^(?<FileName>.*?):(?!\\)") # Regex grabs all text from the start of the line until the first colon not followed by a backslash.
	if ($match.Success)
	{
		# Get the FileName out of the line and add it to our array of file names.
		$fileName = $match.Groups['FileName'].Value
		$fileNames += $fileName
	}
}

$fileNames

Hey Daniel, would you be able to attach "TF.iQmetrix.CheckinPolicies.txt” or post the contents of it?

Is there a way to grab the last part of the line up to the 1st space? What i actually need are the files names within that line of text where the pattern matches.

“Capture.PNG”, “Capture1.PNG”, “Capture3.PNG”, “franklin_and_prokopik_inv_199451_amount_$216.10”, etc