Consider the following function:
function Notify-Windows(
[Parameter(Mandatory=$true)]
[string]$text,
[string]$icon="Info",
[string]$title )
{
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$objNotifyIcon = New-Object System.Windows.Forms.NotifyIcon
$objNotifyIcon.Icon = [System.Drawing.SystemIcons]::Information
$objNotifyIcon.BalloonTipIcon = $icon
$objNotifyIcon.BalloonTipText = $text
$objNotifyIcon.BalloonTipTitle = $title
$objNotifyIcon.Visible = $True
$objNotifyIcon.ShowBalloonTip(10000)
}
On its own, this function works as expected, but as soon as I throw it into a scheduled job, it will not notify me:
$repeatEvery = New-TimeSpan -Seconds 60
$trigger = New-JobTrigger -Once -At (Get-Date).Date -RepeatIndefinitely -RepetitionInterval $repeatEvery
$options = New-ScheduledJobOption -RunElevated
$msg = "Enter the username and password that will run the task";
$credential = $Host.UI.PromptForCredential("Task username and password",$msg,"$env:userdomain\$env:username",$env:userdomain)
Register-ScheduledJob -Name notifyWindows -ScriptBlock {
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$objNotifyIcon = New-Object System.Windows.Forms.NotifyIcon
$objNotifyIcon.Icon = [System.Drawing.SystemIcons]::Information
$objNotifyIcon.BalloonTipIcon = "Info"
$objNotifyIcon.BalloonTipText = "It worked!"
$objNotifyIcon.BalloonTipTitle = "My Title"
$objNotifyIcon.Visible = $True
$objNotifyIcon.ShowBalloonTip(10000)
Write-Output "The notify-windows function was called and exited properly"
} `
-Trigger $trigger -ScheduledJobOption $options -Credential $credential
From that code we get the following output:
Id Name JobTriggers Command Enabled
-- ---- ----------- ------- -------
120 notifyWindows 1 ... True
Now we grab the job that we care about and run it:
$sch = Get-ScheduledJob -Id 120
$sch.Run()
Works:
But let's now wait for the schedule to kick in. Then we will grab the job and analyze it:
> Get-Job | where { $_.Name -eq "notifyWindows" }
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
161 notifyWindows PSScheduledJob Completed True localhost ...
> $job = Get-Job -Id 161
> $job.Output
The notify-windows function was called and exited properly
> $job.Error.Count
0
But still... no notification...
I realize that the scheduled job is running on a separate windows session, but isn't there any way to force it to notify me? Or maybe all users?
Ok so after much googling unfortunately I have not found a way to make this work with System.Windows.Forms.NotifyIcon
. With that said, I DID find a nice little package called BurntToast which worked beautifully.
To install:
> Install-Module -Name BurntToast
and then the updated implementation is as follows:
$repeatEvery = New-TimeSpan -Seconds 60
$trigger = New-JobTrigger -Once -At (Get-Date).Date -RepeatIndefinitely -RepetitionInterval $repeatEvery
$options = New-ScheduledJobOption -RunElevated
$msg = "Enter the username and password that will run the task";
$credential = $Host.UI.PromptForCredential("Task username and password",$msg,"$env:userdomain\$env:username",$env:userdomain)
Register-ScheduledJob -Name notifyWindows -ScriptBlock {
New-BurntToastNotification -Text "It worked!"
Write-Output "The notify-windows function was called and exited properly"
} `
-Trigger $trigger -ScheduledJobOption $options -Credential $credential
That's it. Runs on a schedule of 1 minute, super simple, OSS ftw. Now I can write jobs that monitor things and alert me when other things happen! Though it'd still be nice to find out why my other approach didn't work or at least how to make it work.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.