none
Read-Host from a hidden Powershell session in a scheduled task! RRS feed

  • Question

  • Hi,

      I have a scheduled task (using an .xml to set task parameters) that runs a Powershell script.  The script is run with -WindowStyle Hidden, so the user doesn't see it.  However, sometimes I want to ask the user to enter their password, so I try to run a child Powershell process that runs Read-Host, but I don't see the Read-Host prompt.  I would like to use Powershell to get the password because of the security the -AsSecureString argument gives me.

      I assume that the child Powershell process is inheriting it's parent's Hidden aspect.  I know that because the task is set to run whether the task's account is logged on or not, that the parent task will be run hidden for other accounts.

      I'm running on Windows 8.1, the task runs with highest privileges, and it runs at the logon of any user, whether the task's account is logged on or not.

      How can I do this, and get back the user's input?

      thanks, Rob




    • Edited by Warthogboy Thursday, August 11, 2016 7:40 PM
    Thursday, August 11, 2016 6:04 PM

Answers

  • What you are trying to do can only be safely done fro a custom designed service that communicates with a small process that runs in the users session.  There are many systems out there that use this kind of a technique.  The user session has a small process that calls the service and passes the newly selected password to the service and the service sets the registry. This kind of service is tricky to build if you do not have systems level programming experience.


    \_(ツ)_/

    • Marked as answer by Warthogboy Friday, August 12, 2016 5:52 PM
    Friday, August 12, 2016 3:54 PM

All replies

  • Here's one quick-and-dirty way:


    [Void] [Reflection.Assembly]::LoadWithPartialName("Microsoft.VisualBasic")
    $response = [Microsoft.VisualBasic.Interaction]::InputBox('Enter your input.', 'Sample Input Box')
    


    -- Bill Stewart [Bill_Stewart]

    Thursday, August 11, 2016 6:38 PM
    Moderator
  • Thanks, Bill!

    This is going to be run in a secure environment.  I need to obscure the user's answer (their password), and Powershell has that nice -AsSecureString argument that allows me to do that, as well as securing the data in other ways, so I was hoping to use that.  I'll edit my post to say so.

    Thursday, August 11, 2016 7:37 PM
  • Use Get-Credential.

    -- Bill Stewart [Bill_Stewart]

    Thursday, August 11, 2016 8:05 PM
    Moderator
  • You cannot display anything in a hidden process.  If the main process is hidden then all child Windows will be hidden.

    \_(ツ)_/

    Thursday, August 11, 2016 8:07 PM
  • You'd need to test. I would recommend minimized instead of hidden to avoid problems.

    -- Bill Stewart [Bill_Stewart]

    Thursday, August 11, 2016 8:14 PM
    Moderator
  • Just tested. If the main PowerShell window is -WindowsStyle Hidden, the [Microsoft.VisualBasic.Interaction]::InputBox method still appears on the screen. So does Get-Credential.


    -- Bill Stewart [Bill_Stewart]

    Thursday, August 11, 2016 8:51 PM
    Moderator
  • Normally all children are hidden with the parent. These two must be associated with a non-hidden parent.  Desktop?

    \_(ツ)_/

    Thursday, August 11, 2016 9:01 PM
  • Thanks for testing. However, with very slightly modified code:

    [Void] [Reflection.Assembly]::LoadWithPartialName("Microsoft.VisualBasic")
    $Pass = [Microsoft.VisualBasic.Interactive]::InputBox('You recently changed your password.  Please enter your new password.', 'Input Info')

    I get this result:

    Exception calling "InputBox" with "2" argument(s): "Showing a modal dialog box or form when the application is not running in UserInteractive mode is not a valid operation. Specify the ServiceNotification or DefaultDesktopOnly style to display a notification from a service application."

    I'll try running the task minimized instead and see what happens, although I haven't asked if running minimized will be acceptable.

    Thursday, August 11, 2016 9:48 PM
  • Another tack I took was to use GetConsoleWindow() and ShowWindow() to try to make the task window visible and then hide it again, but that didn't work either.  It never became visible.
    Thursday, August 11, 2016 9:50 PM
  • The scheduler behave a bit different then a service.  It locks down many settings to prevent issue.  Be sure you have this set to only run when a user is logged in or it definitely won't allow you to display a dialog.

    \_(ツ)_/

    Thursday, August 11, 2016 9:59 PM
  • If I run only when the task's user account is logged on, it won't do what I want.  I want it to run when any user is logged on.

    Gonna have to come back to this thread tomorrow.  Thanks for your time and suggestions!!

    Thursday, August 11, 2016 10:35 PM
  • You have not given enough information about what it is you're really trying to do.

    -- Bill Stewart [Bill_Stewart]

    Friday, August 12, 2016 2:01 PM
    Moderator
  • We run our software on a customer's machine in a medical environment.  We create a standard user account that is auto-logged on.  If that user changes their password, which is ok, the autologon fails because it doesn't have the new password.

    We have a scheduled task that runs under another account that we also create, an admin, that checks several things on the machine whenever any user logs on.  I am trying to leverage that task to prompt the auto-logged on user for the new password when I detect that it has changed.  I will then modify the autologon registry entries to have the new password so the next time they boot the machine, they will be auto-logged on again.

    Friday, August 12, 2016 2:51 PM
  • This reminds me of Raymond Chen's topic "when people ask for security holes as features".

    A better solution, in my opinion, is to disallow password changes on that account.


    -- Bill Stewart [Bill_Stewart]

    Friday, August 12, 2016 3:45 PM
    Moderator
  •  :D    I hear you.  How would this be a security hole, in your opinion?
    Friday, August 12, 2016 3:51 PM
  • What you are trying to do can only be safely done fro a custom designed service that communicates with a small process that runs in the users session.  There are many systems out there that use this kind of a technique.  The user session has a small process that calls the service and passes the newly selected password to the service and the service sets the registry. This kind of service is tricky to build if you do not have systems level programming experience.


    \_(ツ)_/

    • Marked as answer by Warthogboy Friday, August 12, 2016 5:52 PM
    Friday, August 12, 2016 3:54 PM
  • I'm not saying its a security hole for sure; it just reminded me of that topic.

    In any case, the entire problem is bypassed if the interactive user can't change the password on the account.


    -- Bill Stewart [Bill_Stewart]

    Friday, August 12, 2016 3:55 PM
    Moderator
  •  :D    I hear you.  How would this be a security hole, in your opinion?

    Is this because you are trying to build a Kiosk?  If so there are other methods of approaching this.

    \_(ツ)_/

    Friday, August 12, 2016 3:57 PM
  • @Bill, I understand - I can ask if that would be acceptable.  I'm not the guy who makes those decisions.  It would make things easier from my perspective; I just don't know if from a customer's point of view it would be okay.

    Friday, August 12, 2016 5:14 PM
  •  

    Is this because you are trying to build a Kiosk?  If so there are other methods of approaching this.

    \_(ツ)_/

      Sort of... however, there are a number of accounts who can use the software, including Service people, with different levels of access, so I don't know if it falls neatly into that category.

    That custom service sounds promising, though I'm not qualified to write it.  There are some people here who are, though.  I'll find out if that's a reasonable effort to make for this task.  I was hoping a few lines of Powershell might do the job.

    Friday, August 12, 2016 5:25 PM
  • In Windows sessions run in isolation.  We cannot normally access another session. Even an administrator is prevented from accessing the contents of another session.  To access a different session we can use the debug API to "attach" to an external process even when running in a different session.  Of course to access across sessions with the debugger we have to alter the system permanently within a boot session.  It is not a normal mechanism because it opens a hole in the security.  The capability is  made available for developers to debug system processes and drivers.  For many things we must install a special version of Windows called a "checked build".

    So what you are asking violates the design and security of Windows.

    As I noted, to do this you would need either a service and client or a system com application and a com stub similar to using COM to access Word or Excel across process boundaries.

    Kiosk mode has facilities to do this password and user mechanism.  It cannot be done the way you are trying to do it.


    \_(ツ)_/

    Friday, August 12, 2016 5:33 PM
  •  

    Is this because you are trying to build a Kiosk?  If so there are other methods of approaching this.

    \_(ツ)_/

      Sort of... however, there are a number of accounts who can use the software, including Service people, with different levels of access, so I don't know if it falls neatly into that category.

    That custom service sounds promising, though I'm not qualified to write it.  There are some people here who are, though.  I'll find out if that's a reasonable effort to make for this task.  I was hoping a few lines of Powershell might do the job.


    If you have people who are capable of writing a service then that would likely be the easiest and safest way to accomplish this.  Also a COM server running under SYSTEM would possibly be even easier.

    \_(ツ)_/

    Friday, August 12, 2016 5:35 PM
  • I don't understand how running a scheduled task in the user's session is accessing another session.  Is it because the task runs as a different account, and therefore starts a separate session from the current user's?
    Friday, August 12, 2016 5:37 PM
  • I don't understand how running a scheduled task in the user's session is accessing another session.  Is it because the task runs as a different account, and therefore starts a separate session from the current user's?

    You are trying to run a hidden task.  By default a hidden task and a hidden Main Window cannot display a child window.  If the task runs under admin it will not have access to the users session.  You get one or the other but not both.

    As Bill said you can run minimized.  You an create a small form and display it when the task is triggered. 

    The biggest issue is that anyone can discover the password by typing one line when the password is saved inn the registry.  If the user is a domain user then the password to a domain account is basically visible to anyone.

    In a Kiosk e usually don't use a domain account.  Access to resources is done through a web site or through a custom program and no other programs are allowed to run.

    Research kiosk mode and companies who supply custom kiosk software that makes it easy to implement and manage kiosks.


    \_(ツ)_/

    Friday, August 12, 2016 5:43 PM
  • Thank you very much for explaining!  I really appreciate the time you both have taken to help me with this.  I'll pass this on and we'll design something that is more secure, and that gets past the session issue.
    Friday, August 12, 2016 5:51 PM