PoshCode Logo PowerShell Code Repository

Send-Growl 3.0 by Joel Bennett 6 years ago (modification of post by Joel Bennett view diff)
View followups from Joel Bennett, doepain, DaisukeMutaguchi and 04210 | diff | embed code: <script type="text/javascript" src="http://PoshCode.org/embed/1276"></script>download | new post

This is the PowerShell 2.0 -only continuation of my Growl module — redesigned as a proper “module” that can be used by (many) other scripts.

It includes support for adding new apps, new message types, registering scriptblocks to handle Growl’s callbacks, passing URL callbacks, etc.

Original post here and future posts here will explain more about callbacks and sending notices to remote computers.

  1. ## This is the first version of a Growl module (just dot-source to use in PowerShell 1.0)
  2. ## v 1.0 supports a very simple notice, and no callbacks
  3. ## v 2.0 supports registering multiple message types
  4. ##       supports callbacks
  5. ## v 2.1 redesigned to be a module used from apps, rather than it's own "PowerGrowler" app
  6. ##
  7. ## TODO:
  8. ## * Test sending notices to other PCs directly
  9.  
  10. Set-StrictMode -Version 2
  11. ## this is just a default now, you'll have opportunities to override it...
  12. $script:appName = "PowerGrowler"
  13.  
  14. [Reflection.Assembly]::LoadFrom("$(Split-Path (gp HKCU:\Software\Growl).'(default)')\Growl.Connector.dll") | Out-Null
  15. if(!(Test-Path Variable:Global:PowerGrowlerNotices)) {
  16.    $global:PowerGrowlerNotices = @{}
  17. }
  18.  
  19. ## We can safely recreate this, it doesn't store much
  20. $script:PowerGrowler = New-Object "Growl.Connector.GrowlConnector"
  21.  
  22. function Register-GrowlType {
  23. #.Synopsis
  24. #  Register a new Type name for growl notices from PowerGrowl
  25. #.Description
  26. #  Creates a new type name that can be used for sending growl notices
  27. #.Parameter AppName
  28. #  The name of the application you want to register as
  29. #.Parameter Name
  30. #  The type name to be used sending growls
  31. #.Parameter DisplayName
  32. #  The test to use for display (defaults to use the same value as the type name)
  33. #.Parameter Icon
  34. #  Overrides the default icon of the message (accepts .ico, .png, .bmp, .jpg, .gif etc)
  35. #.Parameter MachineName
  36. #  The name of a remote machine to register remotely instead of locally.
  37. #.Parameter Priority
  38. #  Overrides the default priority of the message (use sparingly)
  39. #.Example
  40. #  Register-GrowlType "PoshTwitter" "Command Completed"
  41. #  
  42. #  Registers the type "Command Completed," using the default icon, for sending notifications to the local PC
  43. #
  44. PARAM(
  45.    [Parameter(Mandatory=$true,Position=0)]
  46.    [String]$AppName
  47. ,
  48.    [Parameter(Mandatory=$true,Position=1)]
  49.    [ValidateScript( {!$global:PowerGrowlerNotices.Contains($AppName) -OR !$global:PowerGrowlerNotices.$AppName.Notices.ContainsKey($_)} )]
  50.    [String]$Name
  51. ,
  52.    [Parameter(Mandatory=$false,Position=5)]
  53.    [String]$Icon = "$PSScriptRoot\default.ico"
  54. ,
  55.    [Parameter(Mandatory=$false,Position=6)]
  56.    [String]$DisplayName = $Name
  57. ,
  58.    [Parameter(Mandatory=$false,Position=7)]
  59.    [String]$MachineName
  60. ,
  61.    [Parameter(Mandatory=$false)]
  62.    [String]$AppIcon
  63. )
  64.  
  65.    [Growl.Connector.NotificationType]$Notice = $Name
  66.    $Notice.DisplayName = $DisplayName
  67.    $Notice.Icon = Convert-Path (Resolve-Path $Icon)
  68.  
  69.    if($MachineName) {
  70.       $Notice.MachineName = $MachineName
  71.    }
  72.    if(!$global:PowerGrowlerNotices.Contains($AppName)) {
  73.       $global:PowerGrowlerNotices.Add( $AppName, ([Growl.Connector.Application]$AppName) )
  74.  
  75.       $global:PowerGrowlerNotices.$AppName = Add-Member -input $global:PowerGrowlerNotices.$AppName -Name Notices -Type NoteProperty -Value (New-Object hashtable) -Passthru
  76.       $global:PowerGrowlerNotices.$AppName.Icon = Convert-Path (Resolve-Path $AppIcon)
  77.    }
  78.    
  79.    $global:PowerGrowlerNotices.$AppName.Notices.Add( $Name, $Notice )
  80.  
  81.    $script:PowerGrowler.Register( $global:PowerGrowlerNotices.$AppName , [Growl.Connector.NotificationType[]]@($global:PowerGrowlerNotices.$AppName.Notices.Values) )
  82. }
  83.  
  84.  
  85. function Set-GrowlPassword {
  86. #.Synopsis
  87. #  Set the Growl password
  88. #.Description
  89. #  Set the password and optionally, the encryption algorithm, for communicating with Growl
  90. #.Parameter Password
  91. #  The password for Growl
  92. #.Parameter Encryption
  93. #  The algorithm to be used for encryption (defaults to AES)
  94. #.Parameter KeyHash
  95. #  The algorithm to be used for key hashing (defaults to SHA1)
  96. PARAM(
  97.    [Parameter(Mandatory=$true,Position=0)]
  98.    [String]$Password
  99. ,
  100.    [Parameter(Mandatory=$false,Position=1)]
  101.    [ValidateSet( "AES", "DES", "RC2", "TripleDES", "PlainText" )]
  102.    [String]$Encryption = "AES"
  103. ,  
  104.    [Parameter(Mandatory=$false,Position=2)]
  105.    [ValidateSet( "MD5", "SHA1", "SHA256", "SHA384", "SHA512" )]
  106.    [String]$KeyHash = "SHA1"
  107. )  
  108.    $script:PowerGrowler.EncryptionAlgorithm = [Growl.Connector.Cryptography+SymmetricAlgorithmType]::"$Encryption"
  109.    $script:PowerGrowler.KeyHashAlgorithm = [Growl.Connector.Cryptography+SymmetricAlgorithmType]::"$KeyHash"
  110.    $script:PowerGrowler.Password = $Password
  111. }
  112.  
  113. ## Register the "PowerGrowler" "Default" notice so everything works out of the box
  114. Register-GrowlType $script:AppName "Default" -appIcon "$PsScriptRoot\default.ico"
  115.  
  116. function Register-GrowlCallback {
  117. #.Synopsis
  118. #  Register a script to be called when each notice is finished.
  119. #.Description
  120. #  Registers a scriptblock as a handler for the NotificationCallback event. You should accept two parameters, a Growl.Connector.Response and a Growl.Connector.CallbackData object.
  121. #  
  122. #  The NotificationCallback only happens when a callback is requested, which in this Growl library only happens if you pass both CallbackData and CallbackType to the Send-Growl function.
  123. #.Example
  124. #  Register-GrowlCallback { PARAM( $response, $context )
  125. #    Write-Host "Response $($response|out-string)" -fore Cyan
  126. #    Write-Host "Context $($context|fl|out-string)" -fore Green
  127. #    Write-Host $("Response Type: {0}`nNotification ID: {1}`nCallback Data: {2}`nCallback Data Type: {3}`n" -f $context.Result, $context.NotificationID, $context.Data, $context.Type) -fore Yellow
  128. #  }
  129. #
  130. #  Registers an informational debugging-style handler.
  131. #
  132. PARAM(
  133. [Parameter(Mandatory=$true)]
  134. [Scriptblock]$Handler
  135. )
  136.    Register-ObjectEvent $script:PowerGrowler NotificationCallback -Action $Handler
  137. }
  138.  
  139. function Send-Growl {
  140. [CmdletBinding(DefaultParameterSetName="DataCallback")]
  141. #.Synopsis
  142. #  Send a growl notice
  143. #.Description
  144. #  Send a growl notice with the scpecified values
  145. #.Parameter Caption
  146. #  The short caption to display
  147. #.Parameter Message
  148. #  The message to send (most displays will resize to accomodate)
  149. #.Parameter NoticeType
  150. #  The type of notice to send. This MUST be the name of one of the registered types, and senders should bear in mind that each registered type has user-specified settings, so you should not abuse the types, but create your own for messages that will recur.
  151. #  For example, the user settings allow certain messages to be disabled, set to a different "Display", or to have their Duration and Stickyness changed, as well as have them be Forwarded to another device, have Sounds play, and set different priorities.
  152. #.Parameter Icon
  153. #  Overrides the default icon of the message (accepts .ico, .png, .bmp, .jpg, .gif etc)
  154. #.Parameter Priority
  155. #  Overrides the default priority of the message (use sparingly)
  156. #.Example
  157. #  Send-Growl "Greetings" "Hello World!"
  158. #
  159. #  The Hello World of Growl.
  160. #.Example
  161. #  Send-Growl "You've got Mail!" "Message for you sir!" -icon ~\Icons\mail.png
  162. #
  163. #  Displays a message with a couple of movie quotes and a mail icon.
  164. #
  165. PARAM (
  166.    [Parameter(Mandatory=$true, Position=0)]
  167.    [ValidateScript( {$global:PowerGrowlerNotices.Contains($AppName)} )]
  168.    [string]$AppName
  169. ,
  170.    [Parameter(Mandatory=$true, Position=1)][Alias("Type")]  
  171.    [ValidateScript( {$global:PowerGrowlerNotices.$AppName.Notices.ContainsKey($_)} )]  
  172.    [string]$NoticeType
  173. ,
  174.    [Parameter(Mandatory=$true, Position=2)]
  175.    [string]$Caption
  176. ,
  177.    [Parameter(Mandatory=$true, Position=3)]
  178.    [string]$Message
  179. ,
  180.    [Parameter(Mandatory=$true, Position=4, ParameterSetName="UrlCallback")]
  181.    [Uri]$Url
  182. ,  
  183.    [Parameter(Mandatory=$true, Position=4, ParameterSetName="DataCallback")]
  184.    [string]$CallbackData
  185. ,  
  186.    [Parameter(Mandatory=$true, Position=5, ParameterSetName="DataCallback")]
  187.    [string]$CallbackType
  188. ,
  189.    [string]$Icon
  190. ,
  191.    [Growl.Connector.Priority]$Priority = "Normal"
  192. )
  193.  
  194.    $notice = New-Object Growl.Connector.Notification $appName, $NoticeType, (Get-Date).Ticks.ToString(), $caption, $Message
  195.    
  196.    if($Icon) { $notice.Icon = Convert-Path (Resolve-Path $Icon) }
  197.    if($Priority) { $notice.Priority = $Priority }
  198.    
  199.    if($DebugPreference -gt "SilentlyContinue") { Write-Output $notice }
  200.    if( Test-Path Variable:Local:Url ) {
  201.       $context = new-object Growl.Connector.CallbackContext
  202.       ## These two things aren't used? Probably shouldn't so all this work :)
  203.       $context.Data = $(if(Test-Path Variable:Local:CallbackData){$CallbackData}else{$Url.ToString()})
  204.       $context.Type = $(if(Test-Path Variable:Local:CallbackType){$CallbackType}else{"$NoticeType+Url"})
  205.       $urlCb = new-object Growl.Connector.UrlCallbackTarget
  206.       Write-Host $Url -Fore Cyan
  207.       $urlCb.Url = $Url
  208.       $context.SetUrlCallbackTarget($urlcb)
  209.       $script:PowerGrowler.Notify($notice, $context)
  210.    } elseif( (Test-Path Variable:Local:CallbackData) -and (Test-Path Variable:Local:CallbackType) ) {
  211.       $context = new-object Growl.Connector.CallbackContext
  212.       $context.Data = $CallbackData
  213.       $context.Type = $CallbackType
  214.       Write-Host $context.GetUrlCallbackTarget() -Fore Magenta
  215.       $script:PowerGrowler.Notify($notice, $context)
  216.    } else {          
  217.       $script:PowerGrowler.Notify($notice)
  218.    }
  219. }
  220.  
  221. Export-ModuleMember -Function Send-Growl, Set-GrowlPassword, Register-GrowlCallback, Register-GrowlType

Submit a correction or amendment below (
click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:


Remember me