Monitoring a folder and starting Powerpoint

Hi everyone,

I’m hitting a bit of a wall here in my internet research, so I need some help.

I’m a total noob at Powershell and even though I used to code when I was younger this ship has sailed long ago.

What I want to achieve is the following:

I’ve got a Sharepoint site with a powerpoint presentation in it. That presentation runs on various laptops on different sites. I need to be able to change the presentation without having to go to each location or have someone there do it for me.

What I’ve come up with so far is a first script that monitors if a file is dumped in a subfolder called New. When it occurs, it stops Powerpoint. Then I’ve got another script that monitors when a file is created in the main folder and then starts the presentation.

So what happens is: I have a file Pres.ppsx in the folder. I dump NewPres.ppsx in \New, deletes Pres.ppsx and then (in \New) rename NewPres in Pres then Copy and Paste it in the main folder. Still following ? :slight_smile:

I thought that would do the trick. However it does not really see the file rename. In addition, the first script seems to halt after it has performed its shutdown action. And cherry on top, when it starts the presentation it sometimes does it 3 times.

So I’m wondering if there’s a better and more clever solution to do this.

Thanks a lot.

Script 1:

SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO

$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "C:\FullPath\New"
$watcher.Filter = "*.ppsx"
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $true  

DEFINE ACTIONS AFTER A EVENT IS DETECTED

$action = {$pp = [Runtime.Interopservices.Marshal]::GetActiveObject('powerpoint.application')
$pp.Presentations | % { 
$_.Save()
$_.Close() 
}

# Kill off all PowerPoint apps
Get-Process | ?{$_.ProcessName -eq "POWERPNT"} | Stop-Process

DECIDE WHICH EVENTS SHOULD BE WATCHED (We want PPT to be killed when a new ppsx is dropped in the folder)

$created = Register-ObjectEvent $watcher "Created" -Action $action
#$changed = Register-ObjectEvent $watcher "Changed" -Action $action
#$deleted = Register-ObjectEvent $watcher "Deleted" -Action $action
#$renamed = Register-ObjectEvent $watcher "Renamed" -Action $action
while ($true) {sleep 5}

Script 2:

SET FOLDER TO WATCH + FILES TO WATCH + SUBFOLDERS YES/NO

$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "C:\FullPath"
$watcher.Filter = "*.ppsx"
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $true  

DEFINE ACTIONS AFTER A EVENT IS DETECTED

$action = { 
            # Add entry in the log - Not necessary but helps me understand what happens
            $path = $Event.SourceEventArgs.FullPath
            $changeType = $Event.SourceEventArgs.ChangeType
            $logline = "$(Get-Date), $changeType, $path"
            Add-content "C:\PS1\log.txt" -value $logline
                  
            # Opens the slideshow defined as pptx                
            $pptx = "C:\FullPath\FrontDesk.ppsx"
            $application = New-Object -ComObject powerpoint.application
            $presentation = $application.Presentations.open($pptx)
            $application.visible = "msoTrue"
            $presentation.SlideShowSettings.Run()
          }    

DECIDE WHICH EVENTS SHOULD BE WATCHED (We want PPT to start with $pptx when $pptx has changed)

$created = Register-ObjectEvent $watcher "Created" -Action $action
#$changed = Register-ObjectEvent $watcher "Changed" -Action $action
#$deleted = Register-ObjectEvent $watcher "Deleted" -Action $action
#$renamed = Register-ObjectEvent $watcher "Renamed" -Action $action
while ($true) {sleep 5}

The FileSystemWatcher is a little hard to work with. It isn’t designed for a high level of precision - as you’ve seen, it can sometimes fire multiple events for new files. It can also “miss” files. That’s not something you can fix. Additionally, PowerShell wasn’t really designed with the idea of an always-running event-driven script. It’s a procedural scripting language.

I think you’d probably be better off reducing the complexity that you have going on, especially if you can stomach a delay of a few minutes in all this happening. Write a single script. Have it run under Task Scheduler, perhaps every 5 or 10 minutes. Each run, have it look to see if a new file exists. If one does, kill PowerPoint, do the file copy/move/whatever, and restart PowerPoint. The script then ends, whether there as a new file or not. Task Scheduler runs it again on the next interval.

Moving to a time-based, procedural, single-script approach is going to be a lot more reliable than an always-running event-driven approach that relies on the FileSystemWatcher. I think “less clever,” rather than “more clever,” will probably get you there :).

Id actually start it from a different direction

Basically you can register for WMI events. One of those events has to do with files being created/deleted and folders created/deleted.

you can use PowerShell to use the WMI cmdlets to do something similar.

I used this technique back in the days with vbscript when I wanted to watch for certain files created and then rename them and copy them somewhere else.