I have a PowerShell script to send a notification to an user when a new fax is added to a folder. Here's the script:
$searchPath = "\\server_name\Public\folder_x\folder_y\FAX"
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = $searchPath
$watcher.IncludeSubdirectories = $false
$watcher.EnableRaisingEvents = $true
$created = Register-ObjectEvent $watcher "Created" -Action {
[System.Windows.MessageBox]::Show('New fax in folder \\server_name\Public\folder_x\folder_y\FAX')
}
This script is running when I open it in PowerShell ISE and press Play but it's not working any other way.
I tried making it run from command line after changing my execution policy to Unrestricted, but it's not working. I typed powershell "C:\Users\my_username\Documents\FAX_Warning.ps1" I get no error, it's just not doing anything.
I also tried it in the task manager which is what I ultimately want to use. I made a task to run PowerShell with the path as an argument at every login of the user, but it is not working. Again, it's just not doing anything.
Any idea why it's working in the PowerShell ISE but not in anything else?
Your problem is because System.Windows.Forms.MessageBox.Show() runs in the session of the caller.
the fact of it working on ISE is because you are running in the session that contains the window handle.
The easiest way of doing this is using P/Invoke, and the WTSSendMessage Win32 Terminal Services API.
This API allows you to send messages to all or selected sessions on a local or remote computer.
There are a LOT of ways to accomplish this, and you can find examples here.
On our method, we list all sessions on the current computer using WTSEnumerateSessions, filter the active, or selected ones and send the message.
First we add the signature for these functions:
This method uses the least amount of C# possible, so we're not actually defining the WTS_SESSION_INFO struct. We're taking advantage that the layout of these structs are sequential and that each member it's 8 bytes long.
We tidy it up, put into a function inside the script block for your event action:
Also, it's a good idea putting a check inside the action to make sure it's being triggered, like:
Hope it helps.
Happy scripting!