Avatar of wbrandle
wbrandleFlag for United States of America

asked on 

How do I monitor a folder and email changes once a day?

I have three different folders I need to monitor on a server. One for new folders and files added, one for files removed or deleted, and the other directory for files that have changed or been modified. I need a separate email sent to specified email addresses for each directory once a day, at a specified time, and its content will list the folders and files that have been added, modified, or deleted.  I have tried folder spy but it sends emails for every single change and that’s just too many emails.  Would prefer a PowerShell script that I could run as a scheduled task but at this point anything that will work I am interested in. Can anyone help?
Windows Server 2012PowershellShell ScriptingIT AdministrationNetwork Management

Avatar of undefined
Last Comment
Qlemo
Avatar of Dustin Saunders
Dustin Saunders
Flag of United States of America image

You have 2 ways to do this, depending on how you want to go about it.

Option 1 is to record all the files in the folder into a CSV or equivalent and then the scheduled task will compare what changed and send out an email.  This doesn't require a running service, etc.

The other option is to create a file system watcher in a dummy service and have that record the changes.

Do you need to see every time the files change or just a list of new, deleted, changed files?
Avatar of wbrandle
wbrandle
Flag of United States of America image

ASKER

Just a new list. Basically, what has changed since the last email was sent out. I need the task done automatically so it does not become another added daily task.  The first directory is basically and "Inbox" for a specific group of employees to copy their completed work too. Then another specific group would get notified that there are files waiting for them so they could move the file out to another location.
The other two locations are just for monitoring sensitive restrictive directories.
Avatar of Qlemo
Qlemo
Flag of Germany image

I would go the "compare to snapshot" way. The only issue is that you need to create the first snapshot manually.

Alternatively, you can trust to the archive bit (but need to reset it after processing to make it work) for added or changed files.
For deleted files you'll always need a reference, if not using a trigger (file system watcher).
SOLUTION
Avatar of Dustin Saunders
Dustin Saunders
Flag of United States of America image

Blurred text
THIS SOLUTION IS ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
To do it with a "snapshot" file, I'd recommend loading those CSVs into datatables, then doing a compare there to generate the differences.  This EE answer from another question shows how I'd do the datatable compares:
foreach ($row in $dt1.Rows)
{
    $sqlRow = $dt2.Select("ID="+$row.ID)
    if ($sqlRow.Length -ne 0)
    {
        Write-Host "Update action."
    }
    else
    {
        Write-Host "Insert action."
    }
}

foreach ($row in $dt2.Rows)
{
    $compareRow = $dt1.Select("ID="+$row.ID)
    if ($compareRow.Length -eq 0)
    {
        Write-Host "Remove Action."
    }
}

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of Qlemo
Qlemo
Flag of Germany image

Blurred text
THIS SOLUTION IS ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
Avatar of Shabbir Rao
Shabbir Rao

Avatar of wbrandle
wbrandle
Flag of United States of America image

ASKER

That's a lot of information, I will experiment with provided input thus far and get back to you a little later. Thanks All.
Avatar of wbrandle
wbrandle
Flag of United States of America image

ASKER

So to be up front, I am not a PowerShell guy so please bare with me.
So I tried Qlemo's first. I copied everything into PowerShell ISE. I created a folder on my C: drive called Monitoring with two subfolders Folder1 & Folder2.  I changed the Smtp server information to an actual server and account. Rand the script and I get;

Compare-Object : Cannot bind argument to parameter 'ReferenceObject' because it is null.
At C:\Users\Employee\Documents\FolderMonitor.ps1:16 char:27
+     $cmp = compare-object $snapshot_old $snapshot_new
+                           ~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Compare-Object], ParameterBindingValidationExcept
   ion
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell
   .Commands.CompareObjectCommand
 
Compare-Object : Cannot bind argument to parameter 'ReferenceObject' because it is null.
At C:\Users\Employee\Documents\FolderMonitor.ps1:16 char:27
+     $cmp = compare-object $snapshot_old $snapshot_new
+                           ~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Compare-Object], ParameterBindingValidationExcept
   ion
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell
   .Commands.CompareObjectCommand

Was there something else I should have changed?

I will try Dustin's now. Thanks all.
Avatar of Qlemo
Qlemo
Flag of Germany image

The error message means that the snapshot file has been found, but was empty. And indeed, I forgot to create the initial file content :/.
$smtpParam = @{
  SmtpServer = 'mail.domain.com'
  from       = 'me@domain.com'
  to         = 'you@domain.com'
}


foreach ($folder in 'C:\Monitoring\Folder1', 'C:\Monitoring\Folder2')
{
  $del = $new = $chg = $null
  $snapshot_file = 'C:\Monitoring\'+(split-path $folder -leaf)+'-files.txt'
  $snapshot_new = Get-ChildItem -recurse $folder -Name

  if (test-path $snapshot_file)
  {
    $snapshot_old = Get-Content $snapshot_file
    $cmp = compare-object $snapshot_old $snapshot_new
    $new = ($cmp | ? { $_.SideIndicator -eq '=>' }).InputObject
    $del = ($cmp | ? { $_.SideIndicator -eq '<=' }).InputObject

    $snapshot_date = (Get-ChildItem $snapshot_file).LastWriteTime
    $chg = Get-ChildItem -recurse $folder | ? { $_.LastWriteTime -gt $snapshot_date } | Select -Expand Name
  }

  if ($new) { Send-MailMessage @smtpParam -Subject "$folder - new files"     -Body ($new -join "`r`n") }
  if ($del) { Send-MailMessage @smtpParam -Subject "$folder - deleted files" -Body ($del -join "`r`n") }
  if ($chg) { Send-MailMessage @smtpParam -Subject "$folder - changed files" -Body ($chg -join "`r`n") }

  $snapshot_new | Out-File $snapshot_file
}

Open in new window

Avatar of wbrandle
wbrandle
Flag of United States of America image

ASKER

Qlemo, could you provide how I would change the first part to include port and authentication?

$smtpParam = @{
  SmtpServer = 'mail.domain.com'
  from       = 'me@domain.com'
  to         = 'you@domain.com'
Avatar of Qlemo
Qlemo
Flag of Germany image

Authentication is usually not required if inside of your domain. It needs some more effort:
$smtpParam = @{
  SmtpServer = 'mail.domain.com'
  credential = New-Object System.Management.Automation.PsCredential('MyUser', (ConvertTo-SecureString 'MyPwd' -AsPlainText –force))
  Port       = 65432
  from       = 'me@domain.com'
  to         = 'you@domain.com'
}

Open in new window

You'll have to replace 'MyUser' and 'MyPwd', and of course the port number, by the real-life data.
Powershell
Powershell

Windows PowerShell is a task automation and configuration management framework from Microsoft, consisting of a command-line shell and associated scripting language built on the .NET Framework. PowerShell provides full access to the Component Object Model (COM) and Windows Management Instrumentation (WMI), enabling administrators to perform administrative tasks on both local and remote Windows systems as well as WS-Management and Common Information Model (CIM) enabling management of remote Linux systems and network devices.

27K
Questions
--
Followers
--
Top Experts
Get a personalized solution from industry experts
Ask the experts
Read over 600 more reviews

TRUSTED BY

IBM logoIntel logoMicrosoft logoUbisoft logoSAP logo
Qualcomm logoCitrix Systems logoWorkday logoErnst & Young logo
High performer badgeUsers love us badge
LinkedIn logoFacebook logoX logoInstagram logoTikTok logoYouTube logo