Powershell run as system display popup to user?

This topic contains 10 replies, has 5 voices, and was last updated by  Mike Wingeier 4 months, 1 week ago.

  • Author
  • #90848

    Mike Wingeier

    I am writing a script to update VPN software on client systems, and I need to be able to interact with the user via a popup to let them know. The script itself just needs to inform the user, stop the VPN processes, install several MSIs, and then inform the user upon completion. When I run this as the user, then the software cannot install. When I run it as system, then the software installs and the user does not get the popups.
    With a batch file, I had access to a startasuser.exe (syntax example: &cmd /c startasuser.exe ///silent reg import %RegFile%
    ), which would let me run something in the user context. I have not found that ability in Powershell, and I cannot seem to execute that from Powershell since it calls another instance of command.exe by itself and then runs the arguments. Is there a Powershell solution to this? Any assistance is greatly appreciated.

  • #90850

    Jeremy Corbello

    How are you prompting your users? Are you using the .NET MessageBox class?

  • #90853

    Mike Wingeier

    I'm embarrassed to say I think so. I don't know what calls .NET and what doesn't. I use the following:

    if ($VPNActive) { (new-object -ComObject wscript.shell).Popup("Your Cisco AnyConnect VPN software needs updating. Please save any work and then click 'OK'." ,1800 ,"Cisco AnyConnect",0x30 + 0x0) }

  • #90854

    Jeremy Corbello

    Don't know if this'll work, but try this instead of the New-Object

    [System.Windows.Forms.MessageBox]::Show('Your Cisco AnyConnect VPN softare needs updating. Please save any work and then click OK.')

    I'm going to fumble through this with you, this definitely isn't my strong spot with PowerShell lol

  • #90884

    Mike Wingeier

    No luck there, but thanks for the suggestion. While I was digging into the error log, I found it is not happy with one of my stop process commands. If it got to that point though, it blew past the message box and didn't show it.

    • #90890

      Jeremy Corbello

      So basically the question now becomes one of the following:
      How do I enable an interactive PowerShell session through a Scheduled Task?
      What System processes can PowerShell take advantage of to push a prompt/message?

      I'll start looking into these as well. I'm really curious now.

  • #90920


    “When I run this as the user, then the software cannot install.

    That is because PowerShell will use the session identity of the user using PoSH, not the user logged on to the machine.
    This is a security boundary in Windows not a PoSH issue.

    “With a batch file, I had access to a “

        startasuser.exe (syntax example: &cmd /c startasuser.exe ///silent reg import %RegFile%) 

    “I have not found that ability in Powershell”

    You can use MS SysInternals tools, psexec to do this same thing, this way...

        psexec \\computer -u user -i -d command

    See these resources:

    Utilities like Telnet and remote control programs like Symantec's PC Anywhere let you execute programs on remote systems, but they can be a pain to set up and require that you install client software on the remote systems that you wish to access. PsExec is a light-weight telnet-replacement that lets you execute processes on other systems, complete with full interactivity for console applications, without having to manually install client software. PsExec's most powerful uses include launching interactive command-prompts on remote systems and remote-enabling tools like IpConfig that otherwise do not have the ability to show information about remote systems.

    Note: some anti-virus scanners report that one or more of the tools are infected with a "remote admin" virus. None of the PsTools contain viruses, but they have been used by viruses, which is why they trigger virus notifications.

    Try something like this example. Maybe a bit more that you want, but an idea for you.

        function Show-BalloonTip
                [string]$Title = "Message from PowerShell",
                [ValidateSet('Info','Warning','Error','None')][string]$Icon = 'Info'
            Add-Type -AssemblyName  System.Windows.Forms
            # we use private variables only. No need for global scope
            $balloon = New-Object System.Windows.Forms.NotifyIcon 
            $cleanup = 
                # this gets executed when the user clicks the balloon tip dialog
                # take the balloon from the event arguments, and dispose it
                # take the event handler names also from the event arguments,
                # and clean up
                Unregister-Event  -SourceIdentifier $event.SourceIdentifier
                Remove-Job -Name $event.SourceIdentifier
                $name2 = "M" + $event.SourceIdentifier
                Unregister-Event  -SourceIdentifier $name2
                Remove-Job -Name $name2
            $showBalloon = 
                # this gets executed when the user clicks the tray icon
            # use unique names for event handlers so you can open multiple balloon tips
            $name = [Guid]::NewGuid().Guid
            # subscribe to the balloon events
            $null = Register-ObjectEvent -InputObject $balloon -EventName BalloonTipClicked -Source $name -Action $cleanup
            $null = Register-ObjectEvent -InputObject $balloon -EventName MouseClick -Source "M$name" -Action $showBalloon
            # use the current application icon as tray icon
            $path = (Get-Process -id $pid).Path
            $balloon.Icon  = [System.Drawing.Icon]::ExtractAssociatedIcon($path) 
            # configure the balloon tip
            $balloon.BalloonTipIcon  = $Icon
            $balloon.BalloonTipText  = $Text
            $balloon.BalloonTipTitle  = $Title
            # make the tray icon visible
            $balloon.Visible  = $true 
            # show the balloon tip
  • #90946


    If you're running as System user, it usually goes to the Session 0 window in Windows 10. I'm not sure how to put it on the console window except with psexec.

  • #90968

    Steve Cookson

    Try msg.exe. I used this in an old VBS script that ran as a scheduled task to notify anyone logged into the server
    strCmd = "c:\WINDOWS\system32\msg.exe * Starting the nightly shutdown of service: " & vServiceName

    You should be able to use the same command and concept from powershell.

  • #91055

    Mike Wingeier

    I looked at msg.exe, it worked in testing. Once I got it to my environment at work and ran it as system, it would give me an error 5 indicating lack of permissions. It's looking like I may just have to go to a command file with this one.

  • #91261

    Mike Wingeier

    I ended up going with a mixture of PoSH and batch.

    1. A PoSH script runs as system, figures out if the adapter is active and sets a flag file.
    2. A command file runs as the user, picks up the flag and displays a popup warning that the install will disconnect them.
    3. A PoSH script installs the new software after the box is dismissed or times out.
    4. A command file runs as the user and displays the finish popup.

    It feels like I could have done a more compact job, but the restrictions on my environment got in the way, it does work. Thanks for all the help.

You must be logged in to reply to this topic.