diff --git a/New-ToastNotification.ps1 b/New-ToastNotification.ps1
index de05ea6..c1196b9 100644
--- a/New-ToastNotification.ps1
+++ b/New-ToastNotification.ps1
@@ -1,20 +1,20 @@
<#
.SYNOPSIS
- Create nice Windows 10 toast notifications for the logged on user in Windows 10.
+ Create nice toast notifications for the logged on user in Windows 10.
.DESCRIPTION
Everything is customizeable through config-toast.xml.
- Config-toast.xml can be locally or set to an UNC path with the -Config parameter.
+ Config-toast.xml can be locally, hosted online in blob storage 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 appdata\roaming\ToastNotification\New-Toastnotificaion.log.
+ Can be used for improving the numbers in Windows Servicing as well as kindly reminding users of pending reboots (and a bunch of other use cases as well).
+ All actions are logged to a local log file in AppData\Roaming\ToastNotificationScript\New-ToastNotification.log.
.PARAMETER Config
Specify the path for the config.xml. If none is specified, the script uses the local config.xml
.NOTES
Filename: New-ToastNotification.ps1
- Version: 2.0.0
+ Version: 2.0.1
Author: Martin Bengtsson
Blog: www.imab.dk
Twitter: @mwbengtsson
@@ -77,26 +77,38 @@
- Added support for having images used in the script hosted online
-
-
** Most of the work done in version 2.0.0 is done by Chad Brower // @Brower_Cha on Twitter **
** I have added the additional protocols/scripts and rewritten some minor things **
** As well as added support for dynamic deadline retrieval for software updates **
** Stuff has been rewritten to suit my understanding and thoughts of the script **
2.0.0 - Huge changes to how this script handles custom protocols
- - Added Support for Custom Actions/Protocols within the script under user context removing the need for that to be run under SYSTEM/ADMIN
-
-
-
-
- - Added Support to dynamically create Custom Action Scripts to support Custom Protocols
- - Added Support for Software (Feature) Updates : Searches for an update and will store in variable
- - Added new XML Types for Software Updates:
- -
- -
- - Added support for getting deadline date/time dynamically for software updates
- - Configure DynamicDeadline with the UpdateID
+ Added Support for Custom Actions/Protocols within the script under user context removing the need for that to be run under SYSTEM/ADMIN
+ -
+ -
+ -
+ -
+ Added Support to dynamically create Custom Action Scripts to support Custom Protocols
+ Added Support for Software (Feature) Updates : Searches for an update and will store in variable
+ Added new XML Types for Software Updates:
+ -
+ -
+ Added support for getting deadline date/time dynamically for software updates
+ - Configure DynamicDeadline with the UpdateID
+
+ 2.0.1 - Updated custom action scripts!
+ - Moved all custom action scripts into the user's profile in $env:APPDATA\ToastNotificationScript
+ - $env:ALLUSERSPROFILE was used previously. This is a bad location if device is used by multiple users due to permission issues
+ - Updated all custom action scripts to invoke their respective action via WMI
+ - Rewritten all custom action scripts
+ - Added logic allowing new custom action scripts to be created if necessary
+ - Now checks script version in registry
+ - If newer version is available from the script, new custom action scripts will be created
+ - This allows me to make sure the relevant scripts are in place in case I change something along the way
+ - Modified script output of custom script for RunPackageID to pick up Program ID dynamically
+ Added support for getting deadline date/time dynamically for applications
+ - Configure DynamicDeadline with the Application ID
+
.LINK
https://www.imab.dk/windows-10-toast-notification-script/
@@ -119,7 +131,6 @@ function Write-Log() {
[Alias("LogContent")]
[string]$Message,
- # EDIT with your location for the local log file
[Parameter(Mandatory=$false)]
[Alias('LogPath')]
[string]$Path="$env:APPDATA\ToastNotificationScript\New-ToastNotification.log",
@@ -204,7 +215,7 @@ function Test-PendingRebootWMI() {
return $false
}
else {
- Write-Log -Message "Computer has no ConfigMgr client installed - skipping checking WMI for pending reboots" -Level Warn
+ Write-Log -Message "Computer has no ConfigMgr client installed - skipping checking WMI for pending reboots" -Level Error
return $false
}
}
@@ -227,7 +238,7 @@ function Get-GivenName() {
$PrincipalContext.Dispose()
}
catch [System.Exception] {
- Write-Log -Message "$_." -Level Warn
+ Write-Log -Message "$_." -Level Error
}
if ($GivenName) {
Write-Log -Message "Given name retrieved from Active Directory: $GivenName"
@@ -277,11 +288,11 @@ function Get-WindowsVersion() {
$true
}
elseif ($OS.Version -notlike "10.0.*") {
- Write-Log -Level Warn -Message "Not running supported version of Windows"
+ Write-Log -Level Error -Message "Not running supported version of Windows"
$false
}
else {
- Write-Log -Level Warn -Message "Not running supported version of Windows"
+ Write-Log -Level Error -Message "Not running supported version of Windows"
$false
}
}
@@ -295,7 +306,7 @@ function Test-WindowsPushNotificationsEnabled() {
$true
}
elseif ($ToastEnabledKey -eq "0") {
- Write-Log -Level Warn -Message "Toast notifications are not enabled in Windows. The script will run, but toasts might not be displayed"
+ Write-Log -Level Error -Message "Toast notifications are not enabled in Windows. The script will run, but toasts might not be displayed"
$false
}
else {
@@ -317,7 +328,7 @@ function Get-ADPasswordExpiration([string]$fADPasswordExpirationDays) {
$PrincipalContext.Dispose()
}
catch [System.Exception] {
- Write-Log -Message "$_." -Level Warn
+ Write-Log -Message "$_." -Level Error
}
if (($SamAccountName) -AND ($DomainName)) {
Write-Log -Message "SamAccountName found: $SamAccountName and DomainName found: $DomainName. Continuing looking for AD password expiration date"
@@ -329,7 +340,7 @@ function Get-ADPasswordExpiration([string]$fADPasswordExpirationDays) {
$ExpiryDate = [DateTime]::FromFileTime([Int64]::Parse((($Result.Properties["msDS-UserPasswordExpiryTimeComputed"])[0]).ToString()))
}
catch {
- Write-Log -Message "Failed to retrieve password expiration date from Active Directory. Script is continuing, but without password expiration date" -Level Warn
+ Write-Log -Message "Failed to retrieve password expiration date from Active Directory. Script is continuing, but without password expiration date" -Level Error
}
if ($ExpiryDate) {
@@ -354,40 +365,54 @@ function Get-ADPasswordExpiration([string]$fADPasswordExpirationDays) {
}
}
elseif (-NOT($ExpiryDate)) {
- Write-Log -Message "No password expiration date found. Returning False" -Level Warn
+ Write-Log -Message "No password expiration date found. Returning False" -Level Error
$false
}
}
elseif (-NOT($SamAccountName) -OR ($DomainName)) {
- Write-Log -Message "Failed to retrieve SamAccountName or DomainName from local Active Directory. Script is continuing, but password expiration date cannot be retrieved" -Level Warn
+ Write-Log -Message "Failed to retrieve SamAccountName or DomainName from local Active Directory. Script is continuing, but password expiration date cannot be retrieved" -Level Error
$false
}
}
-# Create function for retrieving deadline directly from WMI based on the PackageID.
-# This works for Task Sequences, regular packages and software updates
+# Create function for retrieving deadline directly from WMI based on the PackageID, UpdateID or ApplicationID.
+# This works for Task Sequences, regular packages, software updates and applications
# Thank you @kevmjohnston :-)
function Get-DynamicDeadline() {
Write-Log -Message "Running Get-DynamicDeadline function. Trying to get deadline details from WMI and ConfigMgr"
if (Get-Service -Name ccmexec -ErrorAction SilentlyContinue) {
+ # Getting package or task sequence information from WMI
if ($RunPackageIDEnabled -eq "True") {
Write-Log -Message "RunPackageIDEnabled is True. Trying to get deadline information based on package id"
try {
- # Get task sequence program information from WMI. This is the same location used by Software Center
$PackageID = Get-CimInstance -Namespace root\ccm\clientsdk -Query "SELECT * FROM CCM_Program where PackageID = '$DynDeadlineValue'"
}
catch {
- Write-Log -Message "Failed to get PackageID from WMI" -Level Warn
+ Write-Log -Message "Failed to get Package ID from WMI" -Level Error
}
}
+ # Getting software update information from WMI
elseif ($RunUpdateIDEnabled -eq "True") {
Write-Log -Message "RunUpdateIDEnabled is True. Trying to get deadline information based on update id"
$UpdateID = Get-CMUpdate
}
+ # Getting application information from WMI
+ elseif ($RunApplicationIDEnabled -eq "True") {
+ Write-Log -Message "RunApplicationIDEnabled is True. Trying to get deadline information based on application id"
+ try {
+ $ApplicationID = Get-CimInstance -Namespace root\ccm\clientsdk -Query "SELECT * FROM CCM_Application where ID = '$DynDeadlineValue'"
+ }
+ catch {
+ Write-Log -Message "Failed to get Application ID from WMI" -Level Error
+ }
+ }
+ # If not used with any of the options which supports getting the deadline dynamically
else {
- Write-Log -Level Warn "Currently no option enabled within the toast configuration which supports getting the deadline retrieved dynamically"
+ Write-Log -Level Error "Currently no option enabled within the toast configuration which supports getting the deadline retrieved dynamically"
+ Write-Log -Level Error "This currently only works for packages/task sequences and software updates"
}
+ # If a package ID was retrieved, get deadline information
if (-NOT[string]::IsNullOrEmpty($PackageID)) {
# Get the deadline based on the package id
# The Where-Object clause filters out any old/dummy deadline values
@@ -401,34 +426,48 @@ function Get-DynamicDeadline() {
$Deadline.ToUniversalTime()
}
else {
- Write-Log -Message "Failed to get deadline date and time from WMI" -Level Warn
- Write-Log -Message "Please check if there really is a deadline configured" -Level Warn
- Write-Log -Message "The script is continuing, but the toast is displayed without deadline date and time" -Level Warn
+ Write-Log -Message "Failed to get deadline date and time from WMI" -Level Error
+ Write-Log -Message "Please check if there really is a deadline configured" -Level Error
+ Write-Log -Message "The script is continuing, but the toast is displayed without deadline date and time" -Level Error
}
}
+ # If a software update ID was retrieved, get deadline information
elseif (-NOT[string]::IsNullOrEmpty($UpdateID)) {
- Write-Log -Message "UpdateID retrieved. UpdateID is: $DynDeadlineValue. Now getting deadline date and time"
+ Write-Log -Message "Update ID retrieved. Update ID is: $DynDeadlineValue. Now getting deadline date and time"
if (-NOT[string]::IsNullOrEmpty($UpdateID.Deadline)) {
Write-Log -Message "Deadline date and time successfully retrieved from WMI. Deadline is: $($UpdateID.Deadline)"
$UpdateID.Deadline.ToUniversalTime()
}
else {
- Write-Log -Message "Failed to get deadline date and time from WMI" -Level Warn
- Write-Log -Message "Please check if there really is a deadline configured" -Level Warn
- Write-Log -Message "The script is continuing, but the toast is displayed without deadline date and time" -Level Warn
+ Write-Log -Message "Failed to get deadline date and time from WMI" -Level Error
+ Write-Log -Message "Please check if there really is a deadline configured" -Level Error
+ Write-Log -Message "The script is continuing, but the toast is displayed without deadline date and time" -Level Error
}
}
+ # If a application ID was retrieved, get deadline information
+ elseif (-NOT[string]::IsNullOrEmpty($ApplicationID)) {
+ Write-Log -Message "Application ID retrieved. Application ID is: $DynDeadlineValue. Now getting deadline date and time"
+ if (-NOT[string]::IsNullOrEmpty($ApplicationID.Deadline)) {
+ Write-Log -Message "Deadline date and time successfully retrieved from WMI. Deadline is: $($ApplicationID.Deadline)"
+ $ApplicationID.Deadline.ToUniversalTime()
+ }
+ else {
+ Write-Log -Message "Failed to get deadline date and time from WMI" -Level Error
+ Write-Log -Message "Please check if there really is a deadline configured" -Level Error
+ Write-Log -Message "The script is continuing, but the toast is displayed without deadline date and time" -Level Error
+ }
+ }
else {
- Write-Log -Message "Appears that the specified package ID or update ID: $DynDeadlineValue is not deployed to the device."
+ Write-Log -Message "Appears that the specified Package ID or Update ID or Application ID: $DynDeadlineValue is not deployed to the device."
}
}
else {
- Write-Log -Message "ConfigMgr service not found. This function requires the ConfigMgr client to be installed" -Level Warn
+ Write-Log -Message "ConfigMgr service not found. This function requires the ConfigMgr client to be installed" -Level Error
}
}
-# Get-CMUpdate function
+# Create Get-CMUpdate function
# This gets information about a deployed software update from WMI on the device
# HUGE shout-out to Chad Brower // @Brower_Cha on Twitter
# Added in version 2.0.0
@@ -461,24 +500,27 @@ function Get-CMUpdate() {
Write-Log -Level Info -Message "Found update that matches UpdateID: $($GetCMUpdate.ArticleID) and name: $($GetCMUpdate.Name)."
$GetCMUpdate
}
+ # If the evaluation state is in error, retry the installation of the software update, but write this to log separately
elseif ($EvaluationState -eq "Error") {
Write-Log -Message "UpdateID: $($GetCMUpdate.ArticleID) is in evaluation state: $EvaluationState. Retrying installation"
$GetCMUpdate
}
+ # If the evalutation is not in a desired state, do not display toast notification and exit script
else {
- Write-Log -Level Warn -Message "EvalutationState of UpdateID: $($GetCMUpdate.ArticleID) is not set to available. EvaluationState is: $EvaluationState."
- Write-Log -Level Warn -Message "Script will exit here. Not displaying toast notification when when eval state is: $EvaluationState"
+ Write-Log -Level Error -Message "EvalutationState of UpdateID: $($GetCMUpdate.ArticleID) is not set to available. EvaluationState is: $EvaluationState."
+ Write-Log -Level Error -Message "Script will exit here. Not displaying toast notification when when eval state is: $EvaluationState"
Exit 1
}
}
+ # If the software update defined in the config.xml file is not found on the system, do not display toast notification and exit script
else {
- Write-Log -Level Warn -Message "Specified update was not found on system. UpdateID: $RunUpdateIDValue and name: $RunUpdateTitleValue. Please check deployment in ConfigMgr"
- Write-Log -Level Warn -Message "Script will exit here. Not displaying toast notification when specified update is not deployed"
+ Write-Log -Level Error -Message "Specified update was not found on system. UpdateID: $RunUpdateIDValue and name: $RunUpdateTitleValue. Please check deployment in ConfigMgr"
+ Write-Log -Level Error -Message "Script will exit here. Not displaying toast notification when specified update is not deployed"
Exit 1
}
}
else {
- Write-Log -Level Warn -Message "ConfigMgr service not found. This function requires the ConfigMgr client to be installed"
+ Write-Log -Level Error -Message "ConfigMgr service not found. This function requires the ConfigMgr client to be installed"
}
}
@@ -493,7 +535,7 @@ function Write-PackageIDRegistry() {
New-Item -Path $RegistryPath -Force
}
catch {
- Write-Log -Message "Error. Could not create ToastNotificationScript registry path" -Level Warn
+ Write-Log -Message "Error. Could not create ToastNotificationScript registry path" -Level Error
}
}
# If the PackageID specified in the config.xml is picked up
@@ -505,7 +547,7 @@ function Write-PackageIDRegistry() {
$TestPackageID = Get-CimInstance -Namespace root\ccm\clientsdk -Query "SELECT * FROM CCM_Program WHERE PackageID = '$RunPackageIDValue'"
}
catch {
- Write-Log -Level Warn -Message "Failed to retrieve $RunPackageIDValue from WMI"
+ Write-Log -Level Error -Message "Failed to retrieve $RunPackageIDValue from WMI"
}
# If the PackageID is found in WMI with the ConfigMgr client, tattoo that PackageID into registry
if ($TestPackageID) {
@@ -516,18 +558,18 @@ function Write-PackageIDRegistry() {
New-ItemProperty -Path $RegistryPath -Name $RegistryName -Value $RunPackageIDValue -PropertyType "String" -Force
}
catch {
- Write-Log -Level Warn -Message "Failed to write PackageID: $RunPackageIDValue to registry"
+ Write-Log -Level Error -Message "Failed to write PackageID: $RunPackageIDValue to registry"
}
}
}
else {
- Write-Log -Level Warn -Message "PackageID: $RunPackageIDValue was not found in WMI as deployed to the client. Please check the config.xml or deployment in ConfigMgr"
- Write-Log -Level Warn -Message "Script will exit here. Not displaying toast notification when specified package is not deployed"
+ Write-Log -Level Error -Message "PackageID: $RunPackageIDValue was not found in WMI as deployed to the client. Please check the config.xml or deployment in ConfigMgr"
+ Write-Log -Level Error -Message "Script will exit here. Not displaying toast notification when specified package is not deployed"
Exit 1
}
}
else {
- Write-Log -Level Warn -Message "No ConfigMgr service found. This function requires the ConfigMgr client to be installed"
+ Write-Log -Level Error -Message "No ConfigMgr service found. This function requires the ConfigMgr client to be installed"
}
}
}
@@ -543,7 +585,7 @@ function Write-ApplicationIDRegistry() {
New-Item -Path $RegistryPath -Force
}
catch {
- Write-Log -Level Warn -Message "Error. Could not create ToastNotificationScript registry path"
+ Write-Log -Level Error -Message "Error. Could not create ToastNotificationScript registry path"
}
}
# If the ApplicationID specified in the config.xml is picked up
@@ -552,10 +594,10 @@ function Write-ApplicationIDRegistry() {
if (Get-Service -Name ccmexec -ErrorAction SilentlyContinue) {
# Testing if the ApplicationID specified in the config.xml actually is deployed to the device
try {
- $TestApplicationID = Get-CimInstance -ClassName CCM_Application -Namespace "root\ccm\clientSDK" | Where-Object {$_.Id -eq $RunApplicationIDValue}
+ $TestApplicationID = Get-CimInstance -ClassName CCM_Application -Namespace root\ccm\clientsdk | Where-Object {$_.Id -eq $RunApplicationIDValue}
}
catch {
- Write-Log -Level Warn -Message "Failed to retrieve $RunApplicationIDValue from WMI"
+ Write-Log -Level Error -Message "Failed to retrieve $RunApplicationIDValue from WMI"
}
# If the ApplicationID is found in WMI with the ConfigMgr client, tattoo that ApplicationID into registry
@@ -567,18 +609,18 @@ function Write-ApplicationIDRegistry() {
New-ItemProperty -Path $RegistryPath -Name $RegistryName -Value $RunApplicationIDValue -PropertyType "String" -Force
}
catch {
- Write-Log -Level Warn -Message "Failed to write ApplicationID: $RunApplicationIDValue to registry"
+ Write-Log -Level Error -Message "Failed to write ApplicationID: $RunApplicationIDValue to registry"
}
}
}
else {
- Write-Log -Level Warn -Message "ApplicationID: $RunApplicationIDValue was not found in WMI as deployed to the client. Please check the config.xml or deployment in ConfigMgr"
- Write-Log -Level Warn -Message "Script will exit here. Not displaying toast notification when specified application is not deployed"
+ Write-Log -Level Error -Message "ApplicationID: $RunApplicationIDValue was not found in WMI as deployed to the client. Please check the config.xml or deployment in ConfigMgr"
+ Write-Log -Level Error -Message "Script will exit here. Not displaying toast notification when specified application is not deployed"
Exit 1
}
}
else {
- Write-Log -Level Warn -Message "No ConfigMgr service found. This function requires the ConfigMgr client to be installed"
+ Write-Log -Level Error -Message "No ConfigMgr service found. This function requires the ConfigMgr client to be installed"
}
}
}
@@ -597,7 +639,7 @@ function Write-UpdateIDRegistry() {
New-Item -Path $RegistryPath -Force
}
catch {
- Write-Log -Level Warn -Message "Error. Could not create ToastNotificationScript registry path"
+ Write-Log -Level Error -Message "Error. Could not create ToastNotificationScript registry path"
}
}
# If the UpdateID specified in the config.xml is picked up
@@ -609,7 +651,7 @@ function Write-UpdateIDRegistry() {
$GetUpdateID = Get-CMUpdate
}
catch {
- Write-Log -Level Warn -Message "Failed to successfully run the Get-CMUpdate function"
+ Write-Log -Level Error -Message "Failed to successfully run the Get-CMUpdate function"
}
# If the UpdateID is found in WMI with the ConfigMgr client, tattoo that UpdateID into registry
@@ -621,16 +663,16 @@ function Write-UpdateIDRegistry() {
New-ItemProperty -Path $RegistryPath -Name $RegistryName -Value $GetUpdateID.UpdateID -PropertyType "String" -Force
}
catch {
- Write-Log -Level Warn -Message "Failed to write UpdateID: $($GetUpdateID.UpdateID) to registry"
+ Write-Log -Level Error -Message "Failed to write UpdateID: $($GetUpdateID.UpdateID) to registry"
}
}
}
else {
- Write-Log -Level Warn -Message "UpdateID: $RunUpdateIDValue was not found in WMI as deployed to the client. Please check the config.xml or deployment in ConfigMgr"
+ Write-Log -Level Error -Message "UpdateID: $RunUpdateIDValue was not found in WMI as deployed to the client. Please check the config.xml or deployment in ConfigMgr"
}
}
else {
- Write-Log -Level Warn -Message "No ConfigMgr service found. This function requires the ConfigMgr client to be installed"
+ Write-Log -Level Error -Message "No ConfigMgr service found. This function requires the ConfigMgr client to be installed"
}
}
}
@@ -651,11 +693,11 @@ function Display-ToastNotification() {
Exit 0
}
catch {
- Write-Log -Message "Something went wrong when displaying the toast notification" -Level Warn
- Write-Log -Message "Make sure the script is running as the logged on user" -Level Warn
+ Write-Log -Message "Something went wrong when displaying the toast notification" -Level Error
+ Write-Log -Message "Make sure the script is running as the logged on user" -Level Error
# Using Write-Output for sending status to IME log when used with Endpoint Analytics in Intune
Write-Output "Something went wrong when displaying the toast notification. Make sure the script is running as the logged on user"
- Exit 1
+ Exit 1
}
if ($CustomAudio -eq "True") {
Invoke-Command -ScriptBlock {
@@ -672,7 +714,7 @@ function Display-ToastNotification() {
function Test-NTSystem() {
$currentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
if ($currentUser.IsSystem -eq $true) {
- Write-Log -Message "The script is being run as SYSTEM. This is not supported. The script needs the current user's context" -Level Warn
+ Write-Log -Message "The script is being run as SYSTEM. This is not supported. The script needs the current user's context" -Level Error
$true
}
elseif ($currentUser.IsSystem -eq $false) {
@@ -680,7 +722,7 @@ function Test-NTSystem() {
}
}
-# Write-CustomActionRegistry function
+# Create Write-CustomActionRegistry function
# This function creates custom protocols for the logged on user in HKCU.
# This will remove the need to create the protocols outside of the toast notification script
# HUGE shout-out to Chad Brower // @Brower_Cha on Twitter
@@ -694,12 +736,12 @@ function Write-CustomActionRegistry() {
$ActionType,
[Parameter(Position="1")]
[string]
- $RegCommandPath = $CustomScriptPath
+ $RegCommandPath = $global:CustomScriptPath
)
+ Write-Log -Message "Running Write-CustomActionRegistry function: $ActionType"
switch ($ActionType) {
-
ToastReboot {
- # Build out registry for custom action
+ # Build out registry for custom action for rebooting the device via the action button
if((Test-Path -LiteralPath "HKCU:\Software\Classes\$($ActionType)\shell\open\command") -ne $true) {
try {
New-Item "HKCU:\Software\Classes\$($ActionType)\shell\open\command" -Force -ErrorAction SilentlyContinue | Out-Null
@@ -711,12 +753,12 @@ function Write-CustomActionRegistry() {
catch {
Write-Log -Level Error "Failed to create the $ActionType custom protocol in HKCU\Software\Classes. Action button might not work"
$ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
}
}
}
ToastRunUpdateID {
- # Build out registry for custom action
+ # Build out registry for custom action for running software update via the action button
if((Test-Path -LiteralPath "HKCU:\Software\Classes\$($ActionType)\shell\open\command") -ne $true) {
try {
New-Item "HKCU:\Software\Classes\$($ActionType)\shell\open\command" -Force -ErrorAction SilentlyContinue | Out-Null
@@ -728,12 +770,12 @@ function Write-CustomActionRegistry() {
catch {
Write-Log -Level Error "Failed to create the $ActionType custom protocol in HKCU\Software\Classes. Action button might not work"
$ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
}
}
}
ToastRunPackageID {
- # Build out registry for custom action
+ # Build out registry for custom action for running packages and task sequences via the action button
if((Test-Path -LiteralPath "HKCU:\Software\Classes\$($ActionType)\shell\open\command") -ne $true) {
try {
New-Item "HKCU:\Software\Classes\$($ActionType)\shell\open\command" -Force -ErrorAction SilentlyContinue | Out-Null
@@ -745,12 +787,12 @@ function Write-CustomActionRegistry() {
catch {
Write-Log -Level Error "Failed to create the $ActionType custom protocol in HKCU\Software\Classes. Action button might not work"
$ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
}
}
}
ToastRunApplicationID {
- # Build out registry for custom action
+ # Build out registry for custom action for running applications via the action button
if((Test-Path -LiteralPath "HKCU:\Software\Classes\$($ActionType)\shell\open\command") -ne $true) {
try {
New-Item "HKCU:\Software\Classes\$($ActionType)\shell\open\command" -Force -ErrorAction SilentlyContinue | Out-Null
@@ -762,14 +804,14 @@ function Write-CustomActionRegistry() {
catch {
Write-Log -Level Error "Failed to create the $ActionType custom protocol in HKCU\Software\Classes. Action button might not work"
$ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
}
}
}
}
}
-# Write-CustomActionScript function
+# Create Write-CustomActionScript function
# This function creates the custom scripts in ProgramData\ToastNotificationScript which is used to carry out custom protocol actions
# HUGE shout-out to Chad Brower // @Brower_Cha on Twitter
# Added in version 2.0.0
@@ -778,327 +820,261 @@ function Write-CustomActionScript() {
param (
[Parameter(Position="0")]
[ValidateSet("ToastRunApplicationID","ToastRunPackageID","ToastRunUpdateID","ToastReboot")]
- [string]
- $Type,
+ [string] $Type,
[Parameter(Position="1")]
- [String]
- $Path = $CustomScriptPath # Global var can be changed
+ [String] $Path = $global:CustomScriptsPath
)
- # Create Path for custom scipts to live
- if (-NOT(Test-Path -Path $Path)) {
- Write-Log -Message "CustomScriptPath not found. Creating it: $Path"
- try {
- New-item -Path $Path -ItemType Directory -Force | Out-Null
- }
- catch {
- Write-Log -Level Error -Message "Failed to create the CustomScriptPath folder: $Path"
- }
- }
+ Write-Log -Message "Running Write-CustomActionScript function: $Type"
switch ($Type) {
+ # Create custom scripts for running software updates via the action button
ToastRunUpdateID {
try {
$CMDFileName = $Type + '.cmd'
- $CMDFilePath = $CustomScriptPath + '\' + $CMDFileName
- if (-NOT(Test-Path -Path $CMDFilePath)) {
- Write-Log -Message "$CMDFileName does not exist - creating it"
- try {
- New-item -Path $CustomScriptPath -Name $CMDFileName -Force -OutVariable PathInfo | Out-Null
- }
- catch {
- $ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
- }
- try {
- $GetCustomScriptPath = $PathInfo.FullName
- [String]$Script = 'powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -File "C:\ProgramData\ToastNotificationScript\ToastRunUpdateID.ps1"'
- if (-NOT[string]::IsNullOrEmpty($Script)) {
- Out-File -FilePath $GetCustomScriptPath -InputObject $Script -Encoding ASCII -Force
- }
- }
- catch {
- Write-Log -Level Error "Failed to create the custom .cmd script for $Type. Action button might not work"
- $ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
+ $CMDFilePath = $Path + '\' + $CMDFileName
+ try {
+ New-item -Path $Path -Name $CMDFileName -Force -OutVariable PathInfo | Out-Null
+ }
+ catch {
+ $ErrorMessage = $_.Exception.Message
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
+ }
+ try {
+ $GetCustomScriptPath = $PathInfo.FullName
+ [String]$Script = "powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -File `"$global:CustomScriptsPath\ToastRunUpdateID.ps1`""
+ if (-NOT[string]::IsNullOrEmpty($Script)) {
+ Out-File -FilePath $GetCustomScriptPath -InputObject $Script -Encoding ASCII -Force
}
}
- else {
- Write-Log -Message "$CMDFileName already exist. Doing nothing"
+ catch {
+ Write-Log -Level Error "Failed to create the custom .cmd script for $Type. Action button might not work"
+ $ErrorMessage = $_.Exception.Message
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
}
}
catch {
Write-Log -Level Error "Failed to create the custom .cmd script for $Type. Action button might not work"
$ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
}
try {
$PS1FileName = $Type + '.ps1'
- $PS1FilePath = $CustomScriptPath + '\' + $PS1FileName
- if (-NOT(Test-Path -Path $PS1FilePath)) {
- Write-Log -Message "$PS1FileName does not exist - creating it"
- try {
- New-item -Path $CustomScriptPath -Name $PS1FileName -Force -OutVariable PathInfo | Out-Null
- }
- catch {
- $ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
- }
- try {
- $GetCustomScriptPath = $PathInfo.FullName
- [String]$Script = @'
+ $PS1FilePath = $Path + '\' + $PS1FileName
+ try {
+ New-item -Path $Path -Name $PS1FileName -Force -OutVariable PathInfo | Out-Null
+ }
+ catch {
+ $ErrorMessage = $_.Exception.Message
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
+ }
+ try {
+ $GetCustomScriptPath = $PathInfo.FullName
+ [String]$Script = @'
$RegistryPath = "HKCU:\SOFTWARE\ToastNotificationScript"
$UpdateID = (Get-ItemProperty -Path $RegistryPath -Name "RunUpdateID").RunUpdateID
-$Arguments = Get-WmiObject -Namespace root\ccm\clientSDK -Query "SELECT * FROM CCM_SoftwareUpdate WHERE UpdateID = '$UpdateID'"
-Invoke-WmiMethod -Namespace root\ccm\clientsdk -Class CCM_SoftwareUpdatesManager -Name InstallUpdates -ArgumentList (,$Arguments)
-if (Test-Path -Path "C:\Windows\CCM\ClientUX\SCClient.exe") { Start-Process -FilePath "C:\Windows\CCM\ClientUX\SCClient.exe" -ArgumentList "SoftwareCenter:Page=Updates" -WindowStyle Maximized }
+$TestUpdateID = Get-WmiObject -Namespace ROOT\ccm\ClientSDK -Query "SELECT * FROM CCM_SoftwareUpdate WHERE UpdateID = '$UpdateID'"
+if (-NOT[string]::IsNullOrEmpty($TestUpdateID)) {
+ Invoke-WmiMethod -Namespace ROOT\ccm\ClientSDK -Class CCM_SoftwareUpdatesManager -Name InstallUpdates -ArgumentList (,$TestUpdateID)
+ if (Test-Path -Path "$env:windir\CCM\ClientUX\SCClient.exe") { Start-Process -FilePath "$env:windir\CCM\ClientUX\SCClient.exe" -ArgumentList "SoftwareCenter:Page=Updates" -WindowStyle Maximized }
+}
exit 0
'@
- if (-NOT[string]::IsNullOrEmpty($Script)) {
- Out-File -FilePath $GetCustomScriptPath -InputObject $Script -Encoding ASCII -Force
- }
- }
- catch {
- Write-Log -Level Error "Failed to create the custom .ps1 script for $Type. Action button might not work"
- $ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
+ if (-NOT[string]::IsNullOrEmpty($Script)) {
+ Out-File -FilePath $GetCustomScriptPath -InputObject $Script -Encoding ASCII -Force
}
}
- else {
- Write-Log -Message "$PS1FileName already exist. Doing nothing"
+ catch {
+ Write-Log -Level Error "Failed to create the custom .ps1 script for $Type. Action button might not work"
+ $ErrorMessage = $_.Exception.Message
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
}
}
catch {
Write-Log -Level Error "Failed to create the custom .ps1 script for $Type. Action button might not work"
$ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
}
# Do not run another type; break
Break
}
+ # Create custom script for rebooting the device directly from the action button
ToastReboot {
try {
$CMDFileName = $Type + '.cmd'
- $CMDFilePath = $CustomScriptPath + '\' + $CMDFileName
- # Testing to see if the CMD file already exist.
- # If it already exist and it was created by another user, permission issues would occur when trying to overwrite it
- if (-NOT(Test-Path -Path $CMDFilePath)) {
- Write-Log -Message "$CMDFileName does not exist - creating it"
- try {
- New-item -Path $CustomScriptPath -Name $CMDFileName -Force -OutVariable PathInfo | Out-Null
- }
- catch {
- $ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
- }
- try {
- $GetCustomScriptPath = $PathInfo.FullName
- [String]$Script = 'shutdown /r /t 0 /d p:0:0 /c "Toast Notification Reboot"'
- if (-NOT[string]::IsNullOrEmpty($Script)) {
- Out-File -FilePath $GetCustomScriptPath -InputObject $Script -Encoding ASCII -Force
- }
- }
- catch {
- Write-Log -Level Error "Failed to create the custom .cmd script for $Type. Action button might not work"
- $ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
+ $CMDFilePath = $Path + '\' + $CMDFileName
+ try {
+ New-item -Path $Path -Name $CMDFileName -Force -OutVariable PathInfo | Out-Null
+ }
+ catch {
+ $ErrorMessage = $_.Exception.Message
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
+ }
+ try {
+ $GetCustomScriptPath = $PathInfo.FullName
+ [String]$Script = 'shutdown /r /t 0 /d p:0:0 /c "Toast Notification Reboot"'
+ if (-NOT[string]::IsNullOrEmpty($Script)) {
+ Out-File -FilePath $GetCustomScriptPath -InputObject $Script -Encoding ASCII -Force
}
}
- else {
- Write-Log -Message "$CMDFileName already exist. Doing nothing"
+ catch {
+ Write-Log -Level Error "Failed to create the custom .cmd script for $Type. Action button might not work"
+ $ErrorMessage = $_.Exception.Message
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
}
}
catch {
Write-Log -Level Error "Failed to create the custom .cmd script for $Type. Action button might not work"
$ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
}
# Do not run another type; break
Break
}
-
+ # Script output updated in 2.0.1 to dynamically pick up the Program ID.
+ # Previously this was hard coded to '*', making it work for task sequences only. Now also works for regular packages (only one program).
+ # Create custom scripts to run packages and task sequences directly from the action button
ToastRunPackageID {
try {
$CMDFileName = $Type + '.cmd'
- $CMDFilePath = $CustomScriptPath + '\' + $CMDFileName
- if (-NOT(Test-Path -Path $CMDFilePath)) {
- Write-Log -Message "$CMDFileName does not exist - creating it"
- try {
- New-item -Path $CustomScriptPath -Name $CMDFileName -Force -OutVariable PathInfo | Out-Null
- }
- catch {
- $ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
- }
- try {
- $GetCustomScriptPath = $PathInfo.FullName
- [String]$Script = 'powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -File "C:\ProgramData\ToastNotificationScript\ToastRunPackageID.ps1"'
- if (-NOT[string]::IsNullOrEmpty($Script)) {
- Out-File -FilePath $GetCustomScriptPath -InputObject $Script -Encoding ASCII -Force
- }
- }
- catch {
- Write-Log -Level Error "Failed to create the custom .cmd script for $Type. Action button might not work"
- $ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
+ $CMDFilePath = $Path + '\' + $CMDFileName
+ try {
+ New-item -Path $Path -Name $CMDFileName -Force -OutVariable PathInfo | Out-Null
+ }
+ catch {
+ $ErrorMessage = $_.Exception.Message
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
+ }
+ try {
+ $GetCustomScriptPath = $PathInfo.FullName
+ [String]$Script = "powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -File `"$global:CustomScriptsPath\ToastRunPackageID.ps1`""
+ if (-NOT[string]::IsNullOrEmpty($Script)) {
+ Out-File -FilePath $GetCustomScriptPath -InputObject $Script -Encoding ASCII -Force
}
}
- else {
- Write-Log -Message "$CMDFileName already exist. Doing nothing"
+ catch {
+ Write-Log -Level Error "Failed to create the custom .cmd script for $Type. Action button might not work"
+ $ErrorMessage = $_.Exception.Message
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
}
}
catch {
Write-Log -Level Error "Failed to create the custom .cmd script for $Type. Action button might not work"
$ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
}
try {
$PS1FileName = $Type + '.ps1'
- $PS1FilePath = $CustomScriptPath + '\' + $PS1FileName
- if (-NOT(Test-Path -Path $PS1FilePath)) {
- Write-Log -Message "$PS1FileName does not exist - creating it"
- try {
- New-item -Path $CustomScriptPath -Name $PS1FileName -Force -OutVariable PathInfo | Out-Null
- }
- catch {
- $ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
- }
- try {
- $GetCustomScriptPath = $PathInfo.FullName
- [String]$Script = @'
+ $PS1FilePath = $Path + '\' + $PS1FileName
+ try {
+ New-item -Path $Path -Name $PS1FileName -Force -OutVariable PathInfo | Out-Null
+ }
+ catch {
+ $ErrorMessage = $_.Exception.Message
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
+ }
+ try {
+ $GetCustomScriptPath = $PathInfo.FullName
+ [String]$Script = @'
$RegistryPath = "HKCU:\SOFTWARE\ToastNotificationScript"
$PackageID = (Get-ItemProperty -Path $RegistryPath -Name "RunPackageID").RunPackageID
-$SoftwareCenter = New-Object -ComObject "UIResource.UIResourceMgr"
-$ProgramID = "*"
-$SoftwareCenter.ExecuteProgram($ProgramID,$PackageID,$true)
-if (Test-Path -Path "C:\Windows\CCM\ClientUX\SCClient.exe") { Start-Process -FilePath "C:\Windows\CCM\ClientUX\SCClient.exe" -ArgumentList "SoftwareCenter:Page=OSD" -WindowStyle Maximized }
+$TestPackageID = Get-WmiObject -Namespace ROOT\ccm\ClientSDK -Query "SELECT * FROM CCM_Program where PackageID = '$PackageID'"
+if (-NOT[string]::IsNullOrEmpty($TestPackageID)) {
+ $ProgramID = $TestPackageID.ProgramID
+ ([wmiclass]'ROOT\ccm\ClientSDK:CCM_ProgramsManager').ExecuteProgram($ProgramID,$PackageID)
+ if (Test-Path -Path "$env:windir\CCM\ClientUX\SCClient.exe") { Start-Process -FilePath "$env:windir\CCM\ClientUX\SCClient.exe" -ArgumentList "SoftwareCenter:Page=OSD" -WindowStyle Maximized }
+}
exit 0
'@
- if (-NOT[string]::IsNullOrEmpty($Script)) {
- Out-File -FilePath $GetCustomScriptPath -InputObject $Script -Encoding ASCII -Force
- }
- }
- catch {
- Write-Log -Level Error "Failed to create the custom .ps1 script for $Type. Action button might not work"
- $ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
+ if (-NOT[string]::IsNullOrEmpty($Script)) {
+ Out-File -FilePath $GetCustomScriptPath -InputObject $Script -Encoding ASCII -Force
}
}
- else {
- Write-Log -Message "$PS1FileName already exist. Doing nothing"
+ catch {
+ Write-Log -Level Error "Failed to create the custom .ps1 script for $Type. Action button might not work"
+ $ErrorMessage = $_.Exception.Message
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
}
}
catch {
Write-Log -Level Error "Failed to create the custom .ps1 script for $Type. Action button might not work"
$ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
}
# Do not run another type; break
Break
}
+ # Create custom scripts to run applications directly from the action button
ToastRunApplicationID {
try {
$CMDFileName = $Type + '.cmd'
- $CMDFilePath = $CustomScriptPath + '\' + $CMDFileName
- if (-NOT(Test-Path -Path $CMDFilePath)) {
- Write-Log -Message "$CMDFileName does not exist - creating it"
- try {
- New-item -Path $CustomScriptPath -Name $CMDFileName -Force -OutVariable PathInfo | Out-Null
- }
- catch {
- $ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
- }
- try {
- $GetCustomScriptPath = $PathInfo.FullName
- [String]$Script = 'powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -File "C:\ProgramData\ToastNotificationScript\ToastRunApplicationID.ps1"'
- if (-NOT[string]::IsNullOrEmpty($Script)) {
- Out-File -FilePath $GetCustomScriptPath -InputObject $Script -Encoding ASCII -Force
- }
- }
- catch {
- Write-Log -Level Error "Failed to create the custom .cmd script for $Type. Action button might not work"
- $ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
+ $CMDFilePath = $Path + '\' + $CMDFileName
+ try {
+ New-item -Path $Path -Name $CMDFileName -Force -OutVariable PathInfo | Out-Null
+ }
+ catch {
+ $ErrorMessage = $_.Exception.Message
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
+ }
+ try {
+ $GetCustomScriptPath = $PathInfo.FullName
+ [String]$Script = "powershell.exe -ExecutionPolicy Bypass -NoLogo -NonInteractive -NoProfile -WindowStyle Hidden -File `"$global:CustomScriptsPath\ToastRunApplicationID.ps1`""
+ if (-NOT[string]::IsNullOrEmpty($Script)) {
+ Out-File -FilePath $GetCustomScriptPath -InputObject $Script -Encoding ASCII -Force
}
}
- else {
- Write-Log -Message "$CMDFileName already exist. Doing nothing"
+ catch {
+ Write-Log -Level Error "Failed to create the custom .cmd script for $Type. Action button might not work"
+ $ErrorMessage = $_.Exception.Message
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
}
+
}
catch {
Write-Log -Level Error "Failed to create the custom .cmd script for $Type. Action button might not work"
$ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
}
try {
$PS1FileName = $Type + '.ps1'
- $PS1FilePath = $CustomScriptPath + '\' + $PS1FileName
- if (-NOT(Test-Path -Path $PS1FilePath)) {
- Write-Log -Message "$PS1FileName does not exist - creating it"
- try {
- New-item -Path $CustomScriptPath -Name $PS1FileName -Force -OutVariable PathInfo | Out-Null
- }
- catch {
- $ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
- }
- try {
- $GetCustomScriptPath = $PathInfo.FullName
- [String]$Script = @'
-function Trigger-AppInstallation() {
- param(
- [Parameter(Mandatory=$true)]
- [String]$appID
- )
- Begin {
- $application = (Get-CimInstance -ClassName CCM_Application -Namespace "root\ccm\clientSDK" | Where-Object {$_.Id -eq $appID})
- $args = @{EnforcePreference = [UINT32] 0
- Id = "$($application.Id)"
- IsMachineTarget = $application.IsMachineTarget
- IsRebootIfNeeded = $false
- Priority = 'High'
- Revision = "$($application.Revision)"}
- }
- Process {
- if ($application.InstallState -eq "NotInstalled") {
- try {
- Invoke-CimMethod -Namespace "root\ccm\clientSDK" -ClassName CCM_Application -MethodName Install -Arguments $args
- }
- catch { }
- }
- elseif ($application.InstallState -eq "Installed") {
- try {
- Invoke-CimMethod -Namespace "root\ccm\clientSDK" -ClassName CCM_Application -MethodName Repair -Arguments $args
- }
- catch { }
- }
- }
- End { }
+ $PS1FilePath = $Path + '\' + $PS1FileName
+ try {
+ New-item -Path $Path -Name $PS1FileName -Force -OutVariable PathInfo | Out-Null
+ }
+ catch {
+ $ErrorMessage = $_.Exception.Message
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
+ }
+ try {
+ $GetCustomScriptPath = $PathInfo.FullName
+ [String]$Script = @'
+$RegistryPath = "HKCU:\SOFTWARE\ToastNotificationScript"
+$ApplicationID = (Get-ItemProperty -Path $RegistryPath -Name "RunApplicationID").RunApplicationID
+$TestApplicationID = Get-CimInstance -ClassName CCM_Application -Namespace ROOT\ccm\ClientSDK | Where-Object {$_.Id -eq $ApplicationID}
+$AppArguments = @{
+ Id = $TestApplicationID.Id
+ IsMachineTarget = $TestApplicationID.IsMachineTarget
+ Revision = $TestApplicationID.Revision
+}
+if (-NOT[string]::IsNullOrEmpty($TestApplicationID)) {
+ if ($TestApplicationID.InstallState -eq "NotInstalled") { Invoke-CimMethod -Namespace "ROOT\ccm\clientSDK" -ClassName CCM_Application -MethodName Install -Arguments $AppArguments }
+ elseif ($TestApplicationID.InstallState -eq "Installed") { Invoke-CimMethod -Namespace "ROOT\ccm\clientSDK" -ClassName CCM_Application -MethodName Repair -Arguments $AppArguments }
+ if (Test-Path -Path "$env:windir\CCM\ClientUX\SCClient.exe") { Start-Process -FilePath "$env:windir\CCM\ClientUX\SCClient.exe" -ArgumentList "SoftwareCenter:Page=InstallationStatus" -WindowStyle Maximized }
}
-$registryPath = "HKCU:\SOFTWARE\ToastNotificationScript"
-$applicationID = (Get-ItemProperty -Path $RegistryPath -Name "RunApplicationID").RunApplicationID
-Trigger-AppInstallation -appID $applicationID
-if (Test-Path -Path "C:\Windows\CCM\ClientUX\SCClient.exe") { Start-Process -FilePath "C:\Windows\CCM\ClientUX\SCClient.exe" -ArgumentList "SoftwareCenter:Page=InstallationStatus" -WindowStyle Maximized };
exit 0
'@
- if (-NOT[string]::IsNullOrEmpty($Script)) {
- Out-File -FilePath $GetCustomScriptPath -InputObject $Script -Encoding ASCII -Force
- }
- }
- catch {
- Write-Log -Level Error "Failed to create the custom .ps1 script for $Type. Action button might not work"
- $ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
+ if (-NOT[string]::IsNullOrEmpty($Script)) {
+ Out-File -FilePath $GetCustomScriptPath -InputObject $Script -Encoding ASCII -Force
}
}
- else {
- Write-Log -Message "$PS1FileName already exist. Doing nothing"
+ catch {
+ Write-Log -Level Error "Failed to create the custom .ps1 script for $Type. Action button might not work"
+ $ErrorMessage = $_.Exception.Message
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
}
}
catch {
Write-Log -Level Error "Failed to create the custom .ps1 script for $Type. Action button might not work"
$ErrorMessage = $_.Exception.Message
- Write-Log -Level Error -Message "$($ErrorMessage)"
+ Write-Log -Level Error -Message "Error message: $ErrorMessage"
}
# Do not run another type; break
Break
@@ -1107,8 +1083,15 @@ exit 0
}
######### GENERAL VARIABLES #########
-# Getting executing directory
+# Global variables
+# Setting global script version
+$global:ScriptVersion = "2.0.1"
+# Setting executing directory
$global:ScriptPath = Split-Path -Parent $MyInvocation.MyCommand.Definition
+# Setting global custom action script location
+$global:CustomScriptsPath = "$env:APPDATA\ToastNotificationScript\Scripts"
+# Setting global registry path
+$global:RegistryPath = "HKCU:\SOFTWARE\ToastNotificationScript"
# Get running OS build
$RunningOS = Get-CimInstance -Class Win32_OperatingSystem | Select-Object BuildNumber
# Get user culture for multilanguage support
@@ -1120,21 +1103,45 @@ $LogoImageTemp = "$env:TEMP\ToastLogoImage.jpg"
$HeroImageTemp = "$env:TEMP\ToastHeroImage.jpg"
# Setting path to local images
$ImagesPath = "file:///$global:ScriptPath/Images"
-# Getting custom action script location
-$global:CustomScriptPath = "$env:ALLUSERSPROFILE\ToastNotificationScript"
+
+# Create the global registry path for the toast notification script
+if (-NOT(Test-Path -Path $global:RegistryPath)) {
+ Write-Log -Message "ToastNotificationScript registry path not found. Creating it: $global:RegistryPath"
+ try {
+ New-Item -Path $global:RegistryPath -Force | Out-Null
+ }
+ catch {
+ Write-Log -Message "Failed to create the ToastNotificationScript registry path: $global:RegistryPath" -Level Error
+ Write-Log -Message "This is required. Script will now exit" -Level Error
+ Exit 1
+ }
+}
+
+# Create the global path for the custom action scipts used by the custom action protocols
+if (-NOT(Test-Path -Path $global:CustomScriptsPath)) {
+ Write-Log -Message "CustomScriptPath not found. Creating it: $global:CustomScriptsPath"
+ try {
+ New-item -Path $global:CustomScriptsPath -ItemType Directory -Force | Out-Null
+ }
+ catch {
+ Write-Log -Level Error -Message "Failed to create the CustomScriptPath folder: $global:CustomScriptsPath"
+ Write-Log -Message "This is required. Script will now exit" -Level Error
+ Exit 1
+ }
+}
# Testing for prerequisites
# Testing if script is being run as SYSTEM. This is not supported as the toast notification needs the current user's context
$isSystem = Test-NTSystem
if ($isSystem -eq $True) {
- Write-Log -Message "Aborting script" -Level Warn
+ Write-Log -Message "Aborting script" -Level Error
Exit 1
}
# Test if the script is being run on a supported version of Windows. Windows 10 AND workstation OS is required
$SupportedWindowsVersion = Get-WindowsVersion
if ($SupportedWindowsVersion -eq $False) {
- Write-Log -Message "Aborting script" -Level Warn
+ Write-Log -Message "Aborting script" -Level Error
Exit 1
}
@@ -1162,15 +1169,15 @@ if (($Config.StartsWith("https://")) -OR ($Config.StartsWith("http://"))) {
}
catch {
$ErrorMessage = $_.Exception.Message
- Write-Log -Message "Error, could not read $Config" -Level Warn
- Write-Log -Message "Error message: $ErrorMessage" -Level Warn
+ Write-Log -Message "Error, could not read $Config" -Level Error
+ Write-Log -Message "Error message: $ErrorMessage" -Level Error
# Using Write-Output for sending status to IME log when used with Endpoint Analytics in Intune
Write-Output "Error, could not read $Config. Error message: $ErrorMessage"
Exit 1
}
}
else {
- Write-Log -Level Warn -Message "The provided URL to the config does not reply or does not come back OK"
+ Write-Log -Level Error -Message "The provided URL to the config does not reply or does not come back OK"
# Using Write-Output for sending status to IME log when used with Endpoint Analytics in Intune
Write-Output "The provided URL to the config does not reply or does not come back OK"
Exit 1
@@ -1187,18 +1194,18 @@ elseif (-NOT($Config.StartsWith("https://")) -OR (-NOT($Config.StartsWith("http:
}
catch {
$ErrorMessage = $_.Exception.Message
- Write-Log -Message "Error, could not read $Config" -Level Warn
- Write-Log -Message "Error message: $ErrorMessage" -Level Warn
+ Write-Log -Message "Error, could not read $Config" -Level Error
+ Write-Log -Message "Error message: $ErrorMessage" -Level Error
Exit 1
}
}
else {
- Write-Log -Level Warn -Message "No config file found on the specified location [locally or fileshare]"
+ Write-Log -Level Error -Message "No config file found on the specified location [locally or fileshare]"
Exit 1
}
}
else {
- Write-Log -Level Warn -Message "Something about the config file is completely off"
+ Write-Log -Level Error -Message "Something about the config file is completely off"
# Using Write-Output for sending status to IME log when used with Endpoint Analytics in Intune
Write-Output "Something about the config file is completely off"
Exit 1
@@ -1319,169 +1326,169 @@ if ($ToastEnabled -ne "True") {
}
# 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"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -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"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -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"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -Message "Error. You currently can't have both PendingReboot features set to True. Please use them seperately"
Exit 1
}
if (($ADPasswordExpiration -eq "True") -AND ($UpgradeOS -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 ADPasswordExpiration AND UpgradeOS set to True at the same time"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -Message "Error. You can't have both ADPasswordExpiration AND UpgradeOS set to True at the same time"
Exit 1
}
if (($ADPasswordExpiration -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 ADPasswordExpiration AND PendingRebootCheck set to True at the same time"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -Message "Error. You can't have both ADPasswordExpiration AND PendingRebootCheck set to True at the same time"
Exit 1
}
if (($ADPasswordExpiration -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 ADPasswordExpiration AND PendingRebootUptime set to True at the same time"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -Message "Error. You can't have both ADPasswordExpiration AND PendingRebootUptime set to True at the same time"
Exit 1
}
if (($SCAppStatus -eq "True") -AND (-NOT(Get-Service -Name ccmexec))) {
- Write-Log -Level Warn -Message "Error. Using Software Center app for the notification requires the ConfigMgr client installed"
- Write-Log -Level Warn -Message "Error. Please install the ConfigMgr cient or use Powershell as app doing the notification"
+ Write-Log -Level Error -Message "Error. Using Software Center app for the notification requires the ConfigMgr client installed"
+ Write-Log -Level Error -Message "Error. Please install the ConfigMgr cient or use Powershell as app doing the notification"
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"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -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"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -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"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -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"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -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"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -Message "Error. You can't have PendingRebootUptimeText set to True and PendingRebootCheckText set to True at the same time"
+ Write-Log -Level Error -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"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -Message "Error. You can't have PendingRebootCheck set to True and PendingRebootUptimeText set to True at the same time"
+ Write-Log -Level Error -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"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -Message "Error. You can't have PendingRebootUptime set to True and PendingRebootCheckText set to True at the same time"
+ Write-Log -Level Error -Message "You should use PendingRebootUptime with the PendingRebootUptimeText option instead"
Exit 1
}
if (($ADPasswordExpirationTextEnabled -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 ADPasswordExpirationTextEnabled 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"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -Message "Error. You can't have ADPasswordExpirationTextEnabled set to True and PendingRebootCheckText set to True at the same time"
+ Write-Log -Level Error -Message "You should only enable one of the text options"
Exit 1
}
if (($ADPasswordExpirationTextEnabled -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 ADPasswordExpirationTextEnabled set to True and PendingRebootUptimeTextEnabled set to True at the same time"
- Write-Log -Level Warn -Message "You should only enable one of the text options"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -Message "Error. You can't have ADPasswordExpirationTextEnabled set to True and PendingRebootUptimeTextEnabled set to True at the same time"
+ Write-Log -Level Error -Message "You should only enable one of the text options"
Exit 1
}
if (($DeadlineEnabled -eq "True") -AND ($DynDeadlineEnabled -eq "True")) {
- Write-Log -Level Warn -Message "Error. Conflicting selection in the $Config file"
- Write-Log -Level Warn -Message "Error. You can't have DeadlineEnabled set to True and DynamicDeadlineEnabled set to True at the same time"
- Write-Log -Level Warn -Message "You should only enable one of the deadline options"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -Message "Error. You can't have DeadlineEnabled set to True and DynamicDeadlineEnabled set to True at the same time"
+ Write-Log -Level Error -Message "You should only enable one of the deadline options"
Exit 1
}
if (($RunApplicationIDEnabled -eq "True") -AND ($RunPackageIDEnabled -eq "True")) {
- Write-Log -Level Warn -Message "Error. Conflicting selection in the $Config file"
- Write-Log -Level Warn -Message "Error. You can't have RunApplicationIDEnabled set to True and RunPackageIDEnabled set to True at the same time"
- Write-Log -Level Warn -Message "You should only enable one of the options"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -Message "Error. You can't have RunApplicationIDEnabled set to True and RunPackageIDEnabled set to True at the same time"
+ Write-Log -Level Error -Message "You should only enable one of the options"
Exit 1
}
if (($RunApplicationIDEnabled -eq "True") -AND ($RunUpdateIDEnabled -eq "True")) {
- Write-Log -Level Warn -Message "Error. Conflicting selection in the $Config file"
- Write-Log -Level Warn -Message "Error. You can't have RunApplicationIDEnabled set to True and RunUpdateIDEnabled set to True at the same time"
- Write-Log -Level Warn -Message "You should only enable one of the options"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -Message "Error. You can't have RunApplicationIDEnabled set to True and RunUpdateIDEnabled set to True at the same time"
+ Write-Log -Level Error -Message "You should only enable one of the options"
Exit 1
}
if (($RunUpdateIDEnabled -eq "True") -AND ($RunPackageIDEnabled -eq "True")) {
- Write-Log -Level Warn -Message "Error. Conflicting selection in the $Config file"
- Write-Log -Level Warn -Message "Error. You can't have RunUpdateIDEnabled set to True and RunPackageIDEnabled set to True at the same time"
- Write-Log -Level Warn -Message "You should only enable one of the options"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -Message "Error. You can't have RunUpdateIDEnabled set to True and RunPackageIDEnabled set to True at the same time"
+ Write-Log -Level Error -Message "You should only enable one of the options"
Exit 1
}
# New checks for conflicting selections. Trying to prevent that one option is enabled with the wrong action
# Example: Having RunUpdatesID enabled and expecting the toast action button to trigger installation of an update, but instead reboots the computer
# Added in version 2.0.0
if (($Action -eq "ToastRunApplicationID:") -AND ($RunUpdateIDEnabled -eq "True")) {
- Write-Log -Level Warn -Message "Error. Conflicting selection in the $Config file"
- Write-Log -Level Warn -Message "You are using the toast notification with RunUpdateIDEnabled set to $RunUpdateIDEnabled, but the action button is set to $Action"
- Write-Log -Level Warn -Message "This seems like an unintended configuration"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -Message "You are using the toast notification with RunUpdateIDEnabled set to $RunUpdateIDEnabled, but the action button is set to $Action"
+ Write-Log -Level Error -Message "This seems like an unintended configuration"
Exit 1
}
if (($Action -eq "ToastRunPackageID:") -AND ($RunUpdateIDEnabled -eq "True")) {
- Write-Log -Level Warn -Message "Error. Conflicting selection in the $Config file"
- Write-Log -Level Warn -Message "You are using the toast notification with RunUpdateIDEnabled set to $RunUpdateIDEnabled, but the action button is set to $Action"
- Write-Log -Level Warn -Message "This seems like an unintended configuration"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -Message "You are using the toast notification with RunUpdateIDEnabled set to $RunUpdateIDEnabled, but the action button is set to $Action"
+ Write-Log -Level Error -Message "This seems like an unintended configuration"
Exit 1
}
if (($Action -eq "ToastReboot:") -AND ($RunUpdateIDEnabled -eq "True")) {
- Write-Log -Level Warn -Message "Error. Conflicting selection in the $Config file"
- Write-Log -Level Warn -Message "You are using the toast notification with RunUpdateIDEnabled set to $RunUpdateIDEnabled, but the action button is set to $Action"
- Write-Log -Level Warn -Message "This seems like an unintended configuration"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -Message "You are using the toast notification with RunUpdateIDEnabled set to $RunUpdateIDEnabled, but the action button is set to $Action"
+ Write-Log -Level Error -Message "This seems like an unintended configuration"
Exit 1
}
if (($Action -eq "ToastRunApplicationID:") -AND ($RunPackageIDEnabled -eq "True")) {
- Write-Log -Level Warn -Message "Error. Conflicting selection in the $Config file"
- Write-Log -Level Warn -Message "You are using the toast notification with RunPackageIDEnabled set to $RunPackageIDEnabled, but the action button is set to $Action"
- Write-Log -Level Warn -Message "This seems like an unintended configuration"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -Message "You are using the toast notification with RunPackageIDEnabled set to $RunPackageIDEnabled, but the action button is set to $Action"
+ Write-Log -Level Error -Message "This seems like an unintended configuration"
Exit 1
}
if (($Action -eq "ToastRunUpdateID:") -AND ($RunPackageIDEnabled -eq "True")) {
- Write-Log -Level Warn -Message "Error. Conflicting selection in the $Config file"
- Write-Log -Level Warn -Message "You are using the toast notification with RunPackageIDEnabled set to $RunPackageIDEnabled, but the action button is set to $Action"
- Write-Log -Level Warn -Message "This seems like an unintended configuration"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -Message "You are using the toast notification with RunPackageIDEnabled set to $RunPackageIDEnabled, but the action button is set to $Action"
+ Write-Log -Level Error -Message "This seems like an unintended configuration"
Exit 1
}
if (($Action -eq "ToastReboot:") -AND ($RunPackageIDEnabled -eq "True")) {
- Write-Log -Level Warn -Message "Error. Conflicting selection in the $Config file"
- Write-Log -Level Warn -Message "You are using the toast notification with RunPackageIDEnabled set to $RunPackageIDEnabled, but the action button is set to $Action"
- Write-Log -Level Warn -Message "This seems like an unintended configuration"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -Message "You are using the toast notification with RunPackageIDEnabled set to $RunPackageIDEnabled, but the action button is set to $Action"
+ Write-Log -Level Error -Message "This seems like an unintended configuration"
Exit 1
}
if (($Action -eq "ToastRunPackageID:") -AND ($RunApplicationIDEnabled -eq "True")) {
- Write-Log -Level Warn -Message "Error. Conflicting selection in the $Config file"
- Write-Log -Level Warn -Message "You are using the toast notification with RunApplicationIDEnabled set to $RunApplicationIDEnabled, but the action button is set to $Action"
- Write-Log -Level Warn -Message "This seems like an unintended configuration"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -Message "You are using the toast notification with RunApplicationIDEnabled set to $RunApplicationIDEnabled, but the action button is set to $Action"
+ Write-Log -Level Error -Message "This seems like an unintended configuration"
Exit 1
}
if (($Action -eq "ToastRunUpdateID:") -AND ($RunApplicationIDEnabled -eq "True")) {
- Write-Log -Level Warn -Message "Error. Conflicting selection in the $Config file"
- Write-Log -Level Warn -Message "You are using the toast notification with RunApplicationIDEnabled set to $RunApplicationIDEnabled, but the action button is set to $Action"
- Write-Log -Level Warn -Message "This seems like an unintended configuration"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -Message "You are using the toast notification with RunApplicationIDEnabled set to $RunApplicationIDEnabled, but the action button is set to $Action"
+ Write-Log -Level Error -Message "This seems like an unintended configuration"
Exit 1
}
if (($Action -eq "ToastReboot:") -AND ($RunApplicationIDEnabled -eq "True")) {
- Write-Log -Level Warn -Message "Error. Conflicting selection in the $Config file"
- Write-Log -Level Warn -Message "You are using the toast notification with RunApplicationIDEnabled set to $RunApplicationIDEnabled, but the action button is set to $Action"
- Write-Log -Level Warn -Message "This seems like an unintended configuration"
+ Write-Log -Level Error -Message "Error. Conflicting selection in the $Config file"
+ Write-Log -Level Error -Message "You are using the toast notification with RunApplicationIDEnabled set to $RunApplicationIDEnabled, but the action button is set to $Action"
+ Write-Log -Level Error -Message "This seems like an unintended configuration"
Exit 1
}
@@ -1498,11 +1505,11 @@ if (($LogoImageFileName.StartsWith("https://")) -OR ($LogoImageFileName.StartsWi
Write-Log -Message "Successfully downloaded $LogoImageTemp from $LogoImageFileName"
}
catch {
- Write-Log -Level Warn -Message "Failed to download the $LogoImageTemp from $LogoImageFileName"
+ Write-Log -Level Error -Message "Failed to download the $LogoImageTemp from $LogoImageFileName"
}
}
else {
- Write-Log -Level Warn -Message "The image supposedly located on $LogoImageFileName is not available"
+ Write-Log -Level Error -Message "The image supposedly located on $LogoImageFileName is not available"
}
}
if (($HeroImageFileName.StartsWith("https://")) -OR ($HeroImageFileName.StartsWith("http://"))) {
@@ -1517,25 +1524,50 @@ if (($HeroImageFileName.StartsWith("https://")) -OR ($HeroImageFileName.StartsWi
Write-Log -Message "Successfully downloaded $HeroImageTemp from $HeroImageFileName"
}
catch {
- Write-Log -Level Warn -Message "Failed to download the $HeroImageTemp from $HeroImageFileName"
+ Write-Log -Level Error -Message "Failed to download the $HeroImageTemp from $HeroImageFileName"
}
}
else {
- Write-Log -Level Warn -Message "The image supposedly located on $HeroImageFileName is not available"
+ Write-Log -Level Error -Message "The image supposedly located on $HeroImageFileName is not available"
}
}
# Creating custom scripts and protocols if enabled in the config
if ($CreateScriptsProtocolsEnabled -eq "True") {
- Write-Log -Message "CreateScriptsAndProtocols set to True. Will create custom scripts and protocols automatically for the logged on user"
- Write-CustomActionRegistry -ActionType ToastReboot
- Write-CustomActionRegistry -ActionType ToastRunApplicationID
- Write-CustomActionRegistry -ActionType ToastRunPackageID
- Write-CustomActionRegistry -ActionType ToastRunUpdateID
- Write-CustomActionScript -Type ToastReboot
- Write-CustomActionScript -Type ToastRunApplicationID
- Write-CustomActionScript -Type ToastRunPackageID
- Write-CustomActionScript -Type ToastRunUpdateID
+ $RegistryName = "ScriptsAndProtocolsVersion"
+ Write-Log -Message "CreateScriptsAndProtocols set to True. Will allow creation of scripts and protocols"
+ # Testing to see if the global registry path exist. It should, because it was created earlier
+ if (Test-Path -Path $global:RegistryPath) {
+ # Creating the registry key used to determine if scripts and protocols should be created
+ # If it does not exist already, create the key with a value of '0'
+ if (((Get-Item -Path $global:RegistryPath -ErrorAction SilentlyContinue).Property -contains $RegistryName) -ne $true) {
+ New-ItemProperty -Path $global:RegistryPath -Name $RegistryName -Value "0" -PropertyType "String" -Force | Out-Null
+ }
+ if (((Get-Item -Path $global:RegistryPath -ErrorAction SilentlyContinue).Property -contains $RegistryName) -eq $true) {
+ # If the registry key exist, but has a value less than the script version, go ahead and create scripts and protocols
+ if ((Get-ItemProperty -Path $global:RegistryPath -Name $RegistryName -ErrorAction SilentlyContinue).$RegistryName -lt $global:ScriptVersion) {
+ Write-Log -Message "Registry value of $RegistryName does not match Script version: $global:ScriptVersion"
+ try {
+ Write-Log -Message "Creating scripts and protocols for the logged on user"
+ Write-CustomActionRegistry -ActionType ToastReboot
+ Write-CustomActionRegistry -ActionType ToastRunApplicationID
+ Write-CustomActionRegistry -ActionType ToastRunPackageID
+ Write-CustomActionRegistry -ActionType ToastRunUpdateID
+ Write-CustomActionScript -Type ToastReboot
+ Write-CustomActionScript -Type ToastRunApplicationID
+ Write-CustomActionScript -Type ToastRunPackageID
+ Write-CustomActionScript -Type ToastRunUpdateID
+ New-ItemProperty -Path $global:RegistryPath -Name $RegistryName -Value $global:ScriptVersion -PropertyType "String" -Force | Out-Null
+ }
+ catch {
+ Write-Log -Message "Someting failed during creation of custom scripts and protocols" -Level Error
+ }
+ }
+ elseif ((Get-ItemProperty -Path $global:RegistryPath -Name $RegistryName -ErrorAction SilentlyContinue).$RegistryName -ge $global:ScriptVersion) {
+ Write-Log -Message "Script version: $global:ScriptVersion matches value of $RegistryName in registry. Not creating custom scripts and protocols"
+ }
+ }
+ }
}
# Running RunUpdateID function
@@ -1600,7 +1632,7 @@ if ($SCAppStatus -eq "True") {
}
}
else {
- Write-Log -Message "No ConfigMgr client thus cannot use Software Center as notifying app" -Level Warn
+ Write-Log -Message "No ConfigMgr client thus cannot use Software Center as notifying app" -Level Error
}
}
diff --git a/ToastNotificationScript2.0.1.zip b/ToastNotificationScript2.0.1.zip
new file mode 100644
index 0000000..d44e460
Binary files /dev/null and b/ToastNotificationScript2.0.1.zip differ
diff --git a/config-toast-officeupgrade.xml b/config-toast-officeupgrade.xml
index af88356..b7f6f38 100644
--- a/config-toast-officeupgrade.xml
+++ b/config-toast-officeupgrade.xml
@@ -16,7 +16,7 @@
-
+
@@ -25,7 +25,7 @@
-
+
diff --git a/config-toast-osupgrade.xml b/config-toast-osupgrade.xml
index 93ace19..fd34b76 100644
--- a/config-toast-osupgrade.xml
+++ b/config-toast-osupgrade.xml
@@ -22,7 +22,7 @@
-
+
diff --git a/config-toast-waasfu.xml b/config-toast-waasfu.xml
index fddf973..5310eaf 100644
--- a/config-toast-waasfu.xml
+++ b/config-toast-waasfu.xml
@@ -13,10 +13,10 @@
-
+
-
+
@@ -25,7 +25,7 @@
-
+
@@ -40,8 +40,8 @@
Snoozewww.imab.dkHelpdesk kindly reminds you...
- Windows 10 upgrade available!
- There's a new Windows upgrade available. Do yourself a favor and install it yourself.... or we will do it for you ;-)
+ Windows 10 Feature Update!
+ There's a new Windows feature update available. Do yourself a favor and install it yourself.... or we will do it for you ;-)Don't worry! You will receive an adequate amount of reminders before any actions are taken automatically.Click snooze to be reminded again in:Your deadline is:
diff --git a/config-toast-whfb.xml b/config-toast-whfb.xml
new file mode 100644
index 0000000..3596656
--- /dev/null
+++ b/config-toast-whfb.xml
@@ -0,0 +1,102 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Your computer is required to restart due to having exceeded the maximum allowed uptime.
+ Reason: Pending reboots was found in registry or WMI.
+ Your password will expire on:
+ Hey you - wake up. Your computer needs to restart. Do it now.
+ Enroll Now
+ Dismiss
+ Snooze
+ www.imab.dk
+ Helpdesk kindly reminds you...
+ Windows Hello for Business
+ For security reasons, we kindly ask you to enroll your device into Windows Hello for Business. The enrollment is mandatory!
+ If the enrollment isn't completed prior to the deadline, access to your e-mails will be blocked. Please locate further instructions from hitting the Enroll Now button.
+ Click snooze to be reminded again in:
+ Your deadline is:
+ Good morning
+ Good afternoon
+ Good evening
+ Minutes
+ Hour
+ Hours
+ Computer uptime:
+ days
+
+
+ Din computer er påkrævet at genstarte, da den har overskredet den maksimale oppetid.
+ Årsag: Udestående genstart fundet i registry eller WMI.
+ Dit password vil udløbe:
+ Hej dig - vågn op. Din computer skal genstarte. Gør det nu.
+ Påbegynd
+ Afvis
+ Udskyd
+ www.imab.dk
+ En venlig påmindelse fra Helpdesk
+ Windows Hello for Business
+ Af hensyn til vores IT-sikkerhed, beder vi dig om at påbegynde brugen af Windows Hello for Business så hurtigt som muligt. Brugen heraf er påkrævet!
+ Hvis Windows Hello for Business ikke er taget i brug inden tidsfristens udløb, vil adgang til firma ressourcer såsom e-mails blive blokeret. Find flere informationer ved tryk på Påbegynd.
+ Klik udskyd for at blive påmindet igen om:
+ Din tidsfrist er:
+ Godmorgen
+ God eftermiddag
+ Godaften
+ Minutter
+ Time
+ Timer
+ Computer oppetid:
+ dage
+
+
+ Din dator behöver startas om då den överskridit den maximala tillåtna upptiden.
+ Orsak: Väntande omstart hittades i registret eller WMI.
+ Ditt lösenord går ut:
+ Hej du - vakna upp. Datorn måste starta om. Gör det nu.
+ Starta Om
+ Stäng
+ Påminn
+ www.imab.dk
+ En vänlig påminnelse från IT...
+ Din dator behövs starta om
+ För att kunna garantera datorns säkerhet och stabilitet ber vi dig att starta om datorn så snart som möjligt.
+ Att starta om sin dator regelbundet bidrar till en stabilare och säkrare It-miljö. Tack på förhand!
+ Klicka på Påminn för att bli påmind igen:
+ Slutdatum är:
+ God morgon
+ God eftermiddag
+ God kväll
+ Minuter
+ Timma
+ Timmar
+ Datorns upptid:
+ dagar
+
+
\ No newline at end of file