简体   繁体   中英

Triggering a NotifyIcon from a ScheduledJob in powershell

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM