Problem using Register-ObjectEvent in the PowerShell Console.

Welcome Forums General PowerShell Q&A Problem using Register-ObjectEvent in the PowerShell Console.

This topic contains 8 replies, has 4 voices, and was last updated by

 
Participant
3 months, 2 weeks ago.

  • Author
    Posts
  • #132915

    Participant
    Topics: 1
    Replies: 3
    Points: 29
    Rank: Member

    Hi guys,

    I am trying to set up some PowerShell code that listens for a System Event, namely when a Display Setting in Windows is changed, then play a beep sound (the beep will later be replaced by a script that selects an appropriately sized wallpaper).

    I'm noticing that the code below works perfectly fine when run from the ISE, but doesn't seem to work from the Shell.  When I change a Display setting (in this case the screen resolution), nothing happens.

    Can anyone explain what i'm doing wrong?  and what the difference is between the ISE and Shell?

    
    $Event = [Microsoft.Win32.SystemEvents]
    $EventName = 'DisplaySettingsChanged'
    $Action = {
    [console]::beep()
    Write-Host "Beep"
    }
    Register-ObjectEvent -InputObject $Event -EventName $EventName -Action $Action
    
    
  • #133376

    Participant
    Topics: 0
    Replies: 78
    Points: 416
    Helping Hand
    Rank: Contributor

    Hi Bobby – Check to run Get-Event whether the event is registered or not, and run Get-Job to check whether the action is triggered or not. Thank you.

    • #133512

      Participant
      Topics: 1
      Replies: 3
      Points: 29
      Rank: Member

      The results are identical in both the Shell and the ISE, but the code only works in the ISE.  The ISE seems to be constantly running in the background, where the Shell isn't. Not really sure what the difference is.

      
      PS H:\> $Event = [Microsoft.Win32.SystemEvents]
      $EventName = 'DisplaySettingsChanged'
      $Action = {
      [console]::beep()
      Write-Host "Beep"
      }
      Register-ObjectEvent -InputObject $Event -EventName $EventName -Action $Action
      
      Id Name PSJobTypeName State HasMoreData Location Command
      — —- ————- —– ———– ——– ——-
      1 2ad636ba-a79... NotStarted False ...
      
      PS H:\> Get-Job
      
      Id Name PSJobTypeName State HasMoreData Location Command
      — —- ————- —– ———– ——– ——-
      1 2ad636ba-a79... NotStarted False ...
      
      PS H:\> Get-Event
      
      PS H:\> Get-EventSubscriber
      
      SubscriptionId : 1
      SourceObject : Microsoft.Win32.SystemEvents
      EventName : DisplaySettingsChanged
      SourceIdentifier : 2ad636ba-a79b-4b93-b094-cd5914b53140
      Action : System.Management.Automation.PSEventJob
      HandlerDelegate :
      SupportEvent : False
      ForwardEvent : False
      
      PS H:\> Beep
      Beep
      
      
  • #133562

    Participant
    Topics: 0
    Replies: 78
    Points: 416
    Helping Hand
    Rank: Contributor

    Are you using Windows PowerShell or PowerShell Core?

    • #133937

      Participant
      Topics: 1
      Replies: 3
      Points: 29
      Rank: Member

      Thanks for the responses guys.  I am using Windows Power Shell, not Core.

      Name Value
      —- —–
      PSVersion 5.1.16299.820
      PSEdition Desktop
      PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
      BuildVersion 10.0.16299.820
      CLRVersion 4.0.30319.42000
      WSManStackVersion 3.0
      PSRemotingProtocolVersion 2.3
      SerializationVersion 1.1.0.1

      The code works in the ISE, where the beeping sound fires off when I change resolution settings. I'm still unsure why it doesn't work in the Shell/Console.  I understand that Register-ObjectEvent is session based, but shouldn't it still work until I close the PowerShell Window?

      I think I will have a look into WMI Event Consumers as Logan suggested.

       

  • #133686

    Participant
    Topics: 4
    Replies: 76
    Points: 328
    Helping Hand
    Rank: Contributor

    For what it is worth, the Register-ObjectEvent only lives within the current session. If the process stops or restarts it will need to be declared again in that new session. If persistence is desired you may want to consider WMI Event Consumers. They are bound to a WQL Query (WMI Filter) and then reside in the WMI repository, persisting reboots, etc.

    • #133938

      Participant
      Topics: 1
      Replies: 3
      Points: 29
      Rank: Member

      Thank for the prompt response Logan.  I don't know too much about WMI Event Consumers, but persistence is certainly desired.  I'm basically trying to achieve a persistent script that will change wallpapers depending on screen resolution.  Is there an equivalent WMI class I can query to listen for this type of event ie) when display settings are changed?

       

  • #133797

    Moderator
    Topics: 8
    Replies: 739
    Points: 2,071
    Helping Hand
    Rank: Community Hero

    @Bobby20 Can you try this in PS core 6.2.0 – Preview 3 and raise an issue here.

  • #133953

    Participant
    Topics: 4
    Replies: 76
    Points: 328
    Helping Hand
    Rank: Contributor

    Thank for the prompt response Logan. I don't know too much about WMI Event Consumers, but persistence is certainly desired. I'm basically trying to achieve a persistent script that will change wallpapers depending on screen resolution. Is there an equivalent WMI class I can query to listen for this type of event ie) when display settings are changed?

    I am still learning about WMI consumers, there is not a lot of well documented stuff on the interwebs. Mostly the same couple of examples for monitoring a directory for changes to filenames, or formatting a USB drive upon insertion. I have a couple of solutions I have crafted for my own purposes and to learn more about the concepts. I have learned a lot and plan on writing a couple of blog posts on the topic and sharing my original examples based on methodology adapted by Ed Wilson, Boe Prox, and Trevor Sullivan on their blog posts. Its a VERY in-depth topic and I don't have time to dive into all of it. I will share with you the starting point for it all, a working WQL query.

    
    $query = "SELECT * FROM __InstanceModificationEvent WITHIN .1 WHERE TargetInstance ISA 'Win32_VideoController'"
    
    

    You can use wbemtest.exe to test queries and examine TargetInstance objects in depth. I will also share some of the blogs I have used as a jumping off point to develop my solutions.

    CodeProject (Good examples of consumers in MOF format)
    https://www.codeproject.com/articles/28226/%2fArticles%2f28226%2fCreating-WMI-Permanent-Event-Subscriptions-Using-M

    Boe Prox Blog on WMI Consumers
    PowerShell and Events: Permanent WMI Event Subscriptions

    Ed Wilson
    https://blogs.technet.microsoft.com/heyscriptingguy/2010/12/07/use-powershell-to-monitor-and-respond-to-events-on-your-server/

     

    A word of caution.... These bindings are PERMENANT and require explicit removal from WMI or a re-image of the box to get rid of. If you are not paying close attention, or are not completely comfortable with finding and removing bindings in WMI be careful! Pay attention to what you are doing and make sure you are on a DEV box.

The topic ‘Problem using Register-ObjectEvent in the PowerShell Console.’ is closed to new replies.

denizli escort samsun escort muğla escort ataşehir escort kuşadası escort