-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNew-ToastNotification.ps1.old
780 lines (710 loc) · 35.7 KB
/
New-ToastNotification.ps1.old
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
<#
.SYNOPSIS
Create nice Windows 10 toast notifications for the logged on user in Windows.
.DESCRIPTION
Everything is customizeable through config-toast.xml.
Config-toast.xml can be locally or set to an UNC path with the -Config parameter.
This way you can quickly modify the configuration without the need to push new files to the computer running the toast.
Can be used for improving the numbers in Windows Servicing as well as kindly reminding users of pending reboots.
All actions are logged to a local log file in programdata\ToastNotification\New-Toastnotificaion.log.
.PARAMETER Config
Specify the path for the config.xml. If none is specificed, the script uses the local config.xml
.NOTES
Filename: New-ToastNotification.ps1
Version: 1.1
Author: Martin Bengtsson
Blog: www.imab.dk
Twitter: @mwbengtsson
Version history:
1.0 - script created
1.1 - Separated checks for pending reboot in registry/WMI from OS uptime.
More checks for conflicting options in config.xml.
The content of the config.xml is now imported with UTF-8 encoding enabling other characters to be used in the text boxes.
.LINKS
https://www.imab.dk/windows-10-toast-notification-script/
#>
[CmdletBinding()]
param(
[Parameter(HelpMessage='Path to XML Configuration File')]
[string]$Config
)
######### FUNCTIONS #########
# Create write log function
function Write-Log {
[CmdletBinding()]
param
(
[Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)]
[ValidateNotNullOrEmpty()]
[Alias("LogContent")]
[string]$Message,
# EDIT with your location for the local log file
[Parameter(Mandatory=$false)]
[Alias('LogPath')]
[string]$Path="$env:ALLUSERSPROFILE\ToastNotificationScript\" + "New-ToastNotification.log",
[Parameter(Mandatory=$false)]
[ValidateSet("Error","Warn","Info")]
[string]$Level="Info"
)
Begin
{
# Set VerbosePreference to Continue so that verbose messages are displayed.
$VerbosePreference = 'Continue'
}
Process
{
$LogSize = (Get-Item -Path $Path).Length/1MB
$MaxLogSize = 5
# Check for file size of the log. If greater than 5MB, it will create a new one and delete the old.
if ((Test-Path $Path) -AND $LogSize -gt $MaxLogSize) {
Write-Error "Log file $Path already exists and file exceeds maximum file size. Deleting the log and starting fresh."
Remove-Item $Path -Force
$NewLogFile = New-Item $Path -Force -ItemType File
}
# If attempting to write to a log file in a folder/path that doesn't exist create the file including the path.
elseif (!(Test-Path $Path)) {
Write-Verbose "Creating $Path."
$NewLogFile = New-Item $Path -Force -ItemType File
}
else {
# Nothing to see here yet.
}
# Format Date for our Log File
$FormattedDate = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
# Write message to error, warning, or verbose pipeline and specify $LevelText
switch ($Level) {
'Error' {
Write-Error $Message
$LevelText = 'ERROR:'
}
'Warn' {
Write-Warning $Message
$LevelText = 'WARNING:'
}
'Info' {
Write-Verbose $Message
$LevelText = 'INFO:'
}
}
# Write log entry to $Path
"$FormattedDate $LevelText $Message" | Out-File -FilePath $Path -Append
}
End
{
}
}
# Create Pending Reboot function for registry
function Test-PendingRebootRegistry {
Write-Log -Message "Running Test-PendingRebootRegistry function"
$CBSRebootKey = Get-ChildItem "HKLM:\Software\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending" -ErrorAction Ignore
$WURebootKey = Get-Item "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired" -ErrorAction Ignore
$FileRebootKey = Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager" -Name PendingFileRenameOperations -ErrorAction Ignore
if (($CBSRebootKey -ne $null) -OR ($WURebootKey -ne $null) -OR ($FileRebootKey -ne $null)) {
Write-Log -Message "Check returned TRUE on ANY of the registry checks: Reboot is pending!"
return $true
}
Write-Log -Message "Check returned FALSE on ANY of the registry checks: Reboot is NOT pending!"
return $false
}
# Create Pending Reboot function for WMI via SCCM client
function Test-PendingRebootWMI {
Write-Log -Message "Running Test-PendingRebootWMI function"
if (Get-Service -Name ccmexec) {
Write-Log -Message "Computer has SCCM client installed - checking for pending reboots in WMI"
$Util = [wmiclass]"\\.\root\ccm\clientsdk:CCM_ClientUtilities"
$Status = $Util.DetermineIfRebootPending()
if(($Status -ne $null) -AND $Status.RebootPending) {
Write-Log -Message "Check returned TRUE on checking WMI for pending reboot: Reboot is pending!"
return $true
}
Write-Log -Message "Check returned FALSE on checking WMI for pending reboot: Reboot is NOT pending!"
return $false
}
else {
Write-Log -Level Warn -Message "Computer has no SCCM client installed - skipping checking WMI for pending reboots"
return $false
}
}
# Create Get Device Uptime function
function Get-DeviceUptime {
$OS = Get-WmiObject Win32_OperatingSystem
$Uptime = (Get-Date) - ($OS.ConvertToDateTime($OS.LastBootUpTime))
$Uptime.Days
}
#Create upcoming or recently deadline check for updates
function get-recentUpdateDeadline{
Write-Log -Message "Running check for software updates that have either deadlined in the last 24hrs or will deadline in 24hrs"
$deadlineCheck = Get-CimInstance -Namespace root\ccm\clientsdk -ClassName ccm_SoftwareUpdate | select deadline
[int]$checkval=0
foreach($deadline in $deadlineCheck){
$timespan = New-TimeSpan -Start $deadline.deadline -End (get-date)
if(($timespan.TotalHours -le '24') -and ($timespan.TotalHours -ge '-24'){
$checkval++
}
}
if($checkval -gt 0){
Write-Log -Message "Check returned TRUE upcoming or recently deadlined updates!"
return $true
}else{
Write-Log -Level Warn -Message "Check returned FALSE upcoming or recently deadlined updates."
return $false
}
}
######### GENERAL VARIABLES #########
# Getting executing directory
$global:ScriptPath = Split-Path -Parent $MyInvocation.MyCommand.Definition
# Setting image variables
$LogoImage = "file:///$global:ScriptPath/jhalogo.png"
$HeroImage = "file:///$global:ScriptPath/ToastHeroImage.jpg"
$RunningOS = Get-WmiObject -Class Win32_OperatingSystem | Select-Object BuildNumber
# If no config file is set as parameter, use the default.
# Default is executing directory. In this case, the config-toast.xml must exist in same directory as the New-ToastNotification.ps1 file
if (!$Config) {
Write-Log -Message "No config file set as parameter. Using local config file"
$Config = Join-Path ($global:ScriptPath) "config-toast.xml"
}
# Load config.xml
if (Test-Path $Config) {
try {
$Xml = [xml](Get-Content -Path $Config -Encoding UTF8)
Write-Log -Message "Successfully loaded $Config"
}
catch {
$ErrorMessage = $_.Exception.Message
Write-Log -Message "Error, could not read $Config"
Write-Log -Message "Error message: $ErrorMessage"
Exit 1
}
}
else {
Write-Log -Message "Error, could not find or access $Config"
Exit 1
}
# Load xml content into variables
try {
Write-Log -Message "Loading xml content from $Config into variables"
# Load Toast Notification features
$ToastEnabled = $Xml.Configuration.Feature | Where-Object {$_.Name -like 'Toast'} | Select-Object -ExpandProperty 'Enabled'
$UpgradeOS = $Xml.Configuration.Feature | Where-Object {$_.Name -like 'UpgradeOS'} | Select-Object -ExpandProperty 'Enabled'
$PendingRebootUptime = $Xml.Configuration.Feature | Where-Object {$_.Name -like 'PendingRebootUptime'} | Select-Object -ExpandProperty 'Enabled'
$PendingRebootCheck = $Xml.Configuration.Feature | Where-Object {$_.Name -like 'PendingRebootCheck'} | Select-Object -ExpandProperty 'Enabled'
# Load Toast Notification options
$PendingRebootUptimeTextEnabled = $Xml.Configuration.Option | Where-Object {$_.Name -like 'PendingRebootUptimeText'} | Select-Object -ExpandProperty 'Enabled'
$PendingRebootUptimeTextValue = $Xml.Configuration.Option | Where-Object {$_.Name -like 'PendingRebootUptimeText'} | Select-Object -ExpandProperty 'Value'
$MaxUptimeDays = $Xml.Configuration.Option | Where-Object {$_.Name -like 'MaxUptimeDays'} | Select-Object -ExpandProperty 'Value'
$PendingRebootCheckTextEnabled = $Xml.Configuration.Option | Where-Object {$_.Name -like 'PendingRebootCheckText'} | Select-Object -ExpandProperty 'Enabled'
$PendingRebootCheckTextValue = $Xml.Configuration.Option | Where-Object {$_.Name -like 'PendingRebootCheckText'} | Select-Object -ExpandProperty 'Value'
$TargetOS = $Xml.Configuration.Option | Where-Object {$_.Name -like 'TargetOS'} | Select-Object -ExpandProperty 'Build'
$DeadlineEnabled = $Xml.Configuration.Option | Where-Object {$_.Name -like 'Deadline'} | Select-Object -ExpandProperty 'Enabled'
$DeadlineContent = $Xml.Configuration.Option | Where-Object {$_.Name -like 'Deadline'} | Select-Object -ExpandProperty 'Value'
$SCAppName = $Xml.Configuration.Option | Where-Object {$_.Name -like 'UseSoftwareCenterApp'} | Select-Object -ExpandProperty 'Name'
$SCAppStatus = $Xml.Configuration.Option | Where-Object {$_.Name -like 'UseSoftwareCenterApp'} | Select-Object -ExpandProperty 'Enabled'
$PSAppName = $Xml.Configuration.Option | Where-Object {$_.Name -like 'UsePowershellApp'} | Select-Object -ExpandProperty 'Name'
$PSAppStatus = $Xml.Configuration.Option | Where-Object {$_.Name -like 'UsePowershellApp'} | Select-Object -ExpandProperty 'Enabled'
$CustomAudio = $Xml.Configuration.Option | Where-Object {$_.Name -like 'CustomAudio'} | Select-Object -ExpandProperty 'Enabled'
$CustomAudioTextToSpeech = $Xml.Configuration.Option | Where-Object {$_.Name -like 'CustomAudio'} | Select-Object -ExpandProperty 'TextToSpeech'
$Scenario = $Xml.Configuration.Option | Where-Object {$_.Name -like 'Scenario'} | Select-Object -ExpandProperty 'Type'
$Action = $Xml.Configuration.Option | Where-Object {$_.Name -like 'Action'} | Select-Object -ExpandProperty 'Value'
# Load Toast Notification buttons
$ActionButtonEnabled = $Xml.Configuration.Option | Where-Object {$_.Name -like 'ActionButton'} | Select-Object -ExpandProperty 'Enabled'
$ActionButtonContent = $Xml.Configuration.Option | Where-Object {$_.Name -like 'ActionButton'} | Select-Object -ExpandProperty 'Value'
$DismissButtonEnabled = $Xml.Configuration.Option | Where-Object {$_.Name -like 'DismissButton'} | Select-Object -ExpandProperty 'Enabled'
$DismissButtonContent = $Xml.Configuration.Option | Where-Object {$_.Name -like 'DismissButton'} | Select-Object -ExpandProperty 'Value'
$SnoozeButtonEnabled = $Xml.Configuration.Option | Where-Object {$_.Name -like 'SnoozeButton'} | Select-Object -ExpandProperty 'Enabled'
$SnoozeButtonContent = $Xml.Configuration.Option | Where-Object {$_.Name -like 'SnoozeButton'} | Select-Object -ExpandProperty 'Value'
# Load Toast Notification text
$AttributionText = $Xml.Configuration.Text| Where-Object {$_.Name -like 'AttributionText'} | Select-Object -ExpandProperty '#text'
$HeaderText = $Xml.Configuration.Text | Where-Object {$_.Name -like 'HeaderText'} | Select-Object -ExpandProperty '#text'
$TitleText = $Xml.Configuration.Text | Where-Object {$_.Name -like 'TitleText'} | Select-Object -ExpandProperty '#text'
$BodyText1 = $Xml.Configuration.Text | Where-Object {$_.Name -like 'BodyText1'} | Select-Object -ExpandProperty '#text'
$BodyText2 = $Xml.Configuration.Text | Where-Object {$_.Name -like 'BodyText2'} | Select-Object -ExpandProperty '#text'
Write-Log -Message "Successfully loaded xml content from $Config"
}
catch {
Write-Log -Message "Xml content from $Config was not loaded properly"
Exit 1
}
# Check if toast is enabled in config.xml
if ($ToastEnabled -ne "True") {
Write-Log -Message "Toast notification is not enabled. Please check $Config file"
Exit 1
}
# Checking for conflicts in config. Some combinations makes no sense, thus trying to prevent those from happening
if (($UpgradeOS -eq "True") -AND ($PendingRebootCheck -eq "True")) {
Write-Log -Level Warn -Message "Error. Conflicting selection in the $Config file"
Write-Log -Level Warn -Message "Error. You can't have both ÜpgradeOS feature set to True AND PendingRebootCheck feature set to True at the same time"
Exit 1
}
if (($UpgradeOS -eq "True") -AND ($PendingRebootUptime -eq "True")) {
Write-Log -Level Warn -Message "Error. Conflicting selection in the $Config file"
Write-Log -Level Warn -Message "Error. You can't have both ÜpgradeOS feature set to True AND PendingRebootUptime feature set to True at the same time"
Exit 1
}
if (($PendingRebootCheck -eq "True") -AND ($PendingRebootUptime -eq "True")) {
Write-Log -Level Warn -Message "Error. Conflicting selection in the $Config file"
Write-Log -Level Warn -Message "Error. You currently can't have both PendingReboot features set to True. Please use them seperately."
Exit 1
}
if (($SCAppStatus -eq "True") -AND ($PSAppStatus -eq "True")) {
Write-Log -Level Warn -Message "Error. Conflicting selection in the $Config file"
Write-Log -Level Warn -Message "Error. You can't have both SoftwareCenter app set to True AND PowershellApp set to True at the same time"
Exit 1
}
if (($SCAppStatus -ne "True") -AND ($PSAppStatus -ne "True")) {
Write-Log -Level Warn -Message "Error. Conflicting selection in the $Config file"
Write-Log -Level Warn -Message "Error. You need to enable at least 1 app in the config doing the notification. ie. Software Center or Powershell"
Exit 1
}
if (($UpgradeOS -eq "True") -AND ($PendingRebootUptimeTextEnabled -eq "True")) {
Write-Log -Level Warn -Message "Error. Conflicting selection in the $Config file"
Write-Log -Level Warn -Message "Error. You can't have UpgradeOS set to True and PendingRebootUptimeText set to True at the same time"
Exit 1
}
if (($UpgradeOS -eq "True") -AND ($PendingRebootCheckTextEnabled -eq "True")) {
Write-Log -Level Warn -Message "Error. Conflicting selection in the $Config file"
Write-Log -Level Warn -Message "Error. You can't have UpgradeOS set to True and PendingRebootCheckText set to True at the same time"
Exit 1
}
if (($PendingRebootUptimeTextEnabled -eq "True") -AND ($PendingRebootCheckTextEnabled -eq "True")) {
Write-Log -Level Warn -Message "Error. Conflicting selection in the $Config file"
Write-Log -Level Warn -Message "Error. You can't have PendingRebootUptimeText set to True and PendingRebootCheckText set to True at the same time"
Write-Log -Level Warn -Message "You should only enable one of the text options."
Exit 1
}
if (($PendingRebootCheck -eq "True") -AND ($PendingRebootUptimeTextEnabled -eq "True")) {
Write-Log -Level Warn -Message "Error. Conflicting selection in the $Config file"
Write-Log -Level Warn -Message "Error. You can't have PendingRebootCheck set to True and PendingRebootUptimeText set to True at the same time."
Write-Log -Level Warn -Message "You should use PendingRebootCheck with the PendingRebootCheckText option instead"
Exit 1
}
if (($PendingRebootUptime -eq "True") -AND ($PendingRebootCheckTextEnabled -eq "True")) {
Write-Log -Level Warn -Message "Error. Conflicting selection in the $Config file"
Write-Log -Level Warn -Message "Error. You can't have PendingRebootUptime set to True and PendingRebootCheckText set to True at the same time."
Write-Log -Level Warn -Message "You should use PendingRebootUptime with the PendingRebootUptimeText option instead"
Exit 1
}
# Running Pending Reboot Checks
if ($PendingRebootCheck -eq "True") {
Write-Log -Message "PendingRebootCheck set to True. Checking for pending reboots"
$TestPendingRebootRegistry = Test-PendingRebootRegistry
$TestPendingRebootWMI = Test-PendingRebootWMI
}
if ($PendingRebootUptime -eq "True") {
Write-Log -Message "PendingRebootUptime set to True. Checking for device uptime"
$Uptime = Get-DeviceUptime
}
# Run check for recent deadline
if($RecentDeadlineCheck -eq "True"){
Write-Log -Message "RecentDeadlineCheck set to True. Checking for recent software update deadline"
$recentdeadline = get-recentUpdateDeadline
}
# Check for required entries in registry for when using Software Center as application for the toast
if ($SCAppStatus -eq "True") {
# Path to the notification app doing the actual toast
$RegPath = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Notifications\Settings"
$App = "Microsoft.SoftwareCenter.DesktopToasts"
# Creating registry entries if they don't exists
if (-NOT(Test-Path -Path "$RegPath\$App")) {
New-Item -Path "$RegPath\$App" -Force
New-ItemProperty -Path "$RegPath\$App" -Name "ShowInActionCenter" -Value 1 -PropertyType "DWORD" -Force
New-ItemProperty -Path "$RegPath\$App" -Name "Enabled" -Value 1 -PropertyType "DWORD" -Force
}
# Make sure the app used with the action center is enabled
if ((Get-ItemProperty -Path "$RegPath\$App" -Name "Enabled").Enabled -ne "1") {
New-ItemProperty -Path "$RegPath\$App" -Name "Enabled" -Value 1 -PropertyType "DWORD" -Force
}
}
# Check for required entries in registry for when using Powershell as application for the toast
if ($PSAppStatus -eq "True") {
# Register the AppID in the registry for use with the Action Center, if required
$RegPath = "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Notifications\Settings"
$App = "{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\WindowsPowerShell\v1.0\powershell.exe"
# Creating registry entries if they don't exists
if (-NOT(Test-Path -Path "$RegPath\$App")) {
New-Item -Path "$RegPath\$App" -Force
New-ItemProperty -Path "$RegPath\$App" -Name "ShowInActionCenter" -Value 1 -PropertyType "DWORD"
}
# Make sure the app used with the action center is enabled
if ((Get-ItemProperty -Path "$RegPath\$App" -Name "ShowInActionCenter").ShowInActionCenter -ne "1") {
New-ItemProperty -Path "$RegPath\$App" -Name "ShowInActionCenter" -Value 1 -PropertyType "DWORD" -Force
}
}
# Create the default toast notification XML with action button and dismiss button
if (($ActionButtonEnabled -eq "True") -AND ($DismissButtonEnabled -eq "True")) {
Write-Log -Message "Creating the xml for displaying both action button and dismiss button"
[xml]$Toast = @"
<toast scenario="$Scenario">
<visual>
<binding template="ToastGeneric">
<image placement="hero" src="$HeroImage"/>
<image id="1" placement="appLogoOverride" hint-crop="circle" src="$LogoImage"/>
<text placement="attribution">$AttributionText</text>
<text>$HeaderText</text>
<group>
<subgroup>
<text hint-style="title" hint-wrap="true" >$TitleText</text>
</subgroup>
</group>
<group>
<subgroup>
<text hint-style="body" hint-wrap="true" >$BodyText1</text>
</subgroup>
</group>
<group>
<subgroup>
<text hint-style="body" hint-wrap="true" >$BodyText2</text>
</subgroup>
</group>
</binding>
</visual>
<actions>
<action activationType="protocol" arguments="$Action" content="$ActionButtonContent" />
<action activationType="system" arguments="dismiss" content="$DismissButtonContent"/>
</actions>
</toast>
"@
}
# NO action button and NO dismiss button
if (($ActionButtonEnabled -ne "True") -AND ($DismissButtonEnabled -ne "True")) {
Write-Log -Message "Creating the xml for no action button and no dismiss button"
[xml]$Toast = @"
<toast scenario="$Scenario">
<visual>
<binding template="ToastGeneric">
<image placement="hero" src="$HeroImage"/>
<image id="1" placement="appLogoOverride" hint-crop="circle" src="$LogoImage"/>
<text placement="attribution">$AttributionText</text>
<text>$HeaderText</text>
<group>
<subgroup>
<text hint-style="title" hint-wrap="true" >$TitleText</text>
</subgroup>
</group>
<group>
<subgroup>
<text hint-style="body" hint-wrap="true" >$BodyText1</text>
</subgroup>
</group>
<group>
<subgroup>
<text hint-style="body" hint-wrap="true" >$BodyText2</text>
</subgroup>
</group>
</binding>
</visual>
<actions>
</actions>
</toast>
"@
}
# Action button and NO dismiss button
if (($ActionButtonEnabled -eq "True") -AND ($DismissButtonEnabled -ne "True")) {
Write-Log -Message "Creating the xml for no dismiss button"
[xml]$Toast = @"
<toast scenario="$Scenario">
<visual>
<binding template="ToastGeneric">
<image placement="hero" src="$HeroImage"/>
<image id="1" placement="appLogoOverride" hint-crop="circle" src="$LogoImage"/>
<text placement="attribution">$AttributionText</text>
<text>$HeaderText</text>
<group>
<subgroup>
<text hint-style="title" hint-wrap="true" >$TitleText</text>
</subgroup>
</group>
<group>
<subgroup>
<text hint-style="body" hint-wrap="true" >$BodyText1</text>
</subgroup>
</group>
<group>
<subgroup>
<text hint-style="body" hint-wrap="true" >$BodyText2</text>
</subgroup>
</group>
</binding>
</visual>
<actions>
<action activationType="protocol" arguments="$Action" content="$ActionButtonContent" />
</actions>
</toast>
"@
}
# Dismiss button and NO action button
if (($ActionButtonEnabled -ne "True") -AND ($DismissButtonEnabled -eq "True")) {
Write-Log -Message "Creating the xml for no action button"
[xml]$Toast = @"
<toast scenario="$Scenario">
<visual>
<binding template="ToastGeneric">
<image placement="hero" src="$HeroImage"/>
<image id="1" placement="appLogoOverride" hint-crop="circle" src="$LogoImage"/>
<text placement="attribution">$AttributionText</text>
<text>$HeaderText</text>
<group>
<subgroup>
<text hint-style="title" hint-wrap="true" >$TitleText</text>
</subgroup>
</group>
<group>
<subgroup>
<text hint-style="body" hint-wrap="true" >$BodyText1</text>
</subgroup>
</group>
<group>
<subgroup>
<text hint-style="body" hint-wrap="true" >$BodyText2</text>
</subgroup>
</group>
</binding>
</visual>
<actions>
<action activationType="system" arguments="dismiss" content="$DismissButtonContent"/>
</actions>
</toast>
"@
}
# Snooze button - this option will always enable both action button and dismiss button regardless of config settings
if ($SnoozeButtonEnabled -eq "True") {
Write-Log -Message "Creating the xml for snooze button"
[xml]$Toast = @"
<toast scenario="$Scenario">
<visual>
<binding template="ToastGeneric">
<image placement="hero" src="$HeroImage"/>
<image id="1" placement="appLogoOverride" hint-crop="circle" src="$LogoImage"/>
<text placement="attribution">$AttributionText</text>
<text>$HeaderText</text>
<group>
<subgroup>
<text hint-style="title" hint-wrap="true" >$TitleText</text>
</subgroup>
</group>
<group>
<subgroup>
<text hint-style="body" hint-wrap="true" >$BodyText1</text>
</subgroup>
</group>
<group>
<subgroup>
<text hint-style="body" hint-wrap="true" >$BodyText2</text>
</subgroup>
</group>
</binding>
</visual>
<actions>
<input id="snoozeTime" type="selection" title="Click Snooze to be reminded in:" defaultInput="15">
<selection id="15" content="15 minutes"/>
<selection id="60" content="1 hour"/>
<selection id="240" content="4 hours"/>
<selection id="480" content="8 hours"/>
</input>
<action activationType="protocol" arguments="$Action" content="$ActionButtonContent" />
<action activationType="system" arguments="snooze" hint-inputId="snoozeTime" content="$SnoozeButtonContent"/>
<action activationType="system" arguments="dismiss" content="$DismissButtonContent"/>
</actions>
</toast>
"@
}
# Add an additional group and text to the toast xml used for notifying about possible deadline. Used with UpgradeOS option
if ($DeadlineEnabled -eq "True") {
$DeadlineGroup = @"
<group>
<subgroup>
<text hint-style="base" hint-align="left">Your deadline:</text>
<text hint-style="caption" hint-align="left">$(Get-Date -Date $DeadlineContent -Format "dd MMMM yyy HH:mm")</text>
</subgroup>
</group>
"@
$Toast.toast.visual.binding.InnerXml = $Toast.toast.visual.binding.InnerXml + $DeadlineGroup
}
# Add an additional group and text to the toast xml
if ($PendingRebootCheckTextEnabled -eq "True") {
$PendingRebootGroup = @"
<group>
<subgroup>
<text hint-style="body" hint-wrap="true" >$PendingRebootCheckTextValue</text>
</subgroup>
</group>
"@
$Toast.toast.visual.binding.InnerXml = $Toast.toast.visual.binding.InnerXml + $PendingRebootGroup
}
# Add an additional group and text to the toast xml used for notifying about computer uptime. Only add this if the computer uptime exceeds MaxUptimeDays.
if (($PendingRebootUptimeTextEnabled -eq "True") -AND ($Uptime -gt "$MaxUptimeDays")) {
$UptimeGroup = @"
<group>
<subgroup>
<text hint-style="body" hint-wrap="true" >$PendingRebootUptimeTextValue</text>
</subgroup>
</group>
<group>
<subgroup>
<text hint-style="base" hint-align="left">Computer uptime: $Uptime days</text>
</subgroup>
</group>
"@
$Toast.toast.visual.binding.InnerXml = $Toast.toast.visual.binding.InnerXml + $UptimeGroup
}
# Toast used for upgrading OS. Checking running OS buildnumber. No need to display toast, if the OS is already running on TargetOS
if (($UpgradeOS -eq "True") -AND ($RunningOS.BuildNumber -lt "$TargetOS")) {
Write-Log -Message "Toast notification is used in regards to OS upgrade. Taking running OS build into account"
# Load required objects
$Load = [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime]
$Load = [Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime]
# Load the notification into the required format
$ToastXml = New-Object -TypeName Windows.Data.Xml.Dom.XmlDocument
$ToastXml.LoadXml($Toast.OuterXml)
# Display the toast notification
try {
Write-Log -Message "All good. Displaying the toast notification"
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($App).Show($ToastXml)
}
catch {
Write-Log -Message "Something went wrong when displaying the toast notification"
}
if ($CustomAudio -eq "True") {
Invoke-Command -ScriptBlock {Add-Type -AssemblyName System.Speech
$speak = New-Object System.Speech.Synthesis.SpeechSynthesizer
$speak.Speak("$CustomAudioTextToSpeech")
$speak.Dispose()
}
}
# Stopping script. No need to accidently run further toasts
break
}
# Toast used for PendingReboot check and considering OS uptime
if (($PendingRebootUptime -eq "True") -AND ($Uptime -gt "$MaxUptimeDays")) {
Write-Log -Message "Toast notification is used in regards to pending reboot. Uptime count is greater than $MaxUptimeDays"
# Load required objects
$Load = [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime]
$Load = [Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime]
# Load the notification into the required format
$ToastXml = New-Object -TypeName Windows.Data.Xml.Dom.XmlDocument
$ToastXml.LoadXml($Toast.OuterXml)
# Display the toast notification
try {
Write-Log -Message "All good. Displaying the toast notification"
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($App).Show($ToastXml)
}
catch {
Write-Log -Message "Something went wrong when displaying the toast notification"
}
if ($CustomAudio -eq "True") {
Invoke-Command -ScriptBlock {Add-Type -AssemblyName System.Speech
$speak = New-Object System.Speech.Synthesis.SpeechSynthesizer
$speak.Speak("$CustomAudioTextToSpeech")
$speak.Dispose()
}
}
# Stopping script. No need to accidently run further toasts
break
}
# Toast used for pendingReboot check and considering checks in registry
if (($PendingRebootCheck -eq "True") -AND ($TestPendingRebootRegistry -eq $True)) {
Write-Log -Message "Toast notification is used in regards to pending reboot registry. TestPendingRebootRegistry returned $TestPendingRebootRegistry"
# Load required objects
$Load = [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime]
$Load = [Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime]
# Load the notification into the required format
$ToastXml = New-Object -TypeName Windows.Data.Xml.Dom.XmlDocument
$ToastXml.LoadXml($Toast.OuterXml)
# Display the toast notification
try {
Write-Log -Message "All good. Displaying the toast notification"
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($App).Show($ToastXml)
}
catch {
Write-Log -Message "Something went wrong when displaying the toast notification"
}
if ($CustomAudio -eq "True") {
Invoke-Command -ScriptBlock {Add-Type -AssemblyName System.Speech
$speak = New-Object System.Speech.Synthesis.SpeechSynthesizer
$speak.Speak("$CustomAudioTextToSpeech")
$speak.Dispose()
}
}
# Stopping script. No need to accidently run further toasts
break
}
# Toast used for pendingReboot check and considering checks in WMI
if (($PendingRebootCheck -eq "True") -AND ($TestPendingRebootWMI -eq $True)) {
Write-Log -Message "Toast notification is used in regards to pending reboot WMI. TestPendingRebootWMI returned $TestPendingRebootWMI"
# Load required objects
$Load = [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime]
$Load = [Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime]
# Load the notification into the required format
$ToastXml = New-Object -TypeName Windows.Data.Xml.Dom.XmlDocument
$ToastXml.LoadXml($Toast.OuterXml)
# Display the toast notification
try {
Write-Log -Message "All good. Displaying the toast notification"
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($App).Show($ToastXml)
}
catch {
Write-Log -Message "Something went wrong when displaying the toast notification"
}
if ($CustomAudio -eq "True") {
Invoke-Command -ScriptBlock {Add-Type -AssemblyName System.Speech
$speak = New-Object System.Speech.Synthesis.SpeechSynthesizer
$speak.Speak("$CustomAudioTextToSpeech")
$speak.Dispose()
}
}
# Stopping script. No need to accidently run further toasts
break
}
# Toast not used for either OS upgrade or Pending reboot. Run this if all features are set to false in config.xml
if (($UpgradeOS -ne "True") -AND ($PendingRebootCheck -ne "True") -AND ($PendingRebootUptime -ne "True")) {
Write-Log -Message "Toast notification is not used in regards to OS upgrade OR Pending Reboots. Displaying default toast"
# Load required objects
$Load = [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime]
$Load = [Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime]
# Load the notification into the required format
$ToastXml = New-Object -TypeName Windows.Data.Xml.Dom.XmlDocument
$ToastXml.LoadXml($Toast.OuterXml)
# Display the toast notification
try {
Write-Log -Message "All good. Displaying the toast notification"
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($App).Show($ToastXml)
}
catch {
Write-Log -Message "Something went wrong when displaying the toast notification"
}
if ($CustomAudio -eq "True") {
Invoke-Command -ScriptBlock {Add-Type -AssemblyName System.Speech
$speak = New-Object System.Speech.Synthesis.SpeechSynthesizer
$speak.Speak("$CustomAudioTextToSpeech")
$speak.Dispose()
}
}
# Stopping script. No need to accidently run further toasts
break
}
#Toast for update deadline
if (($RecentDeadlineCheck -eq "True") -and ($recentdeadline -eq "True")) {
Write-Log -Message "Toast notification is used in regards to recent updates deadline."
# Load required objects
$Load = [Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime]
$Load = [Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime]
# Load the notification into the required format
$ToastXml = New-Object -TypeName Windows.Data.Xml.Dom.XmlDocument
$ToastXml.LoadXml($Toast.OuterXml)
# Display the toast notification
try {
Write-Log -Message "All good. Displaying the toast notification"
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($App).Show($ToastXml)
}
catch {
Write-Log -Message "Something went wrong when displaying the toast notification"
}
if ($CustomAudio -eq "True") {
Invoke-Command -ScriptBlock {Add-Type -AssemblyName System.Speech
$speak = New-Object System.Speech.Synthesis.SpeechSynthesizer
$speak.Speak("$CustomAudioTextToSpeech")
$speak.Dispose()
}
}
# Stopping script. No need to accidently run further toasts
break
}