Powershell Using Start-Process in PSSession to Open Notepad

后端 未结 4 557
孤独总比滥情好
孤独总比滥情好 2020-12-03 19:29

I\'ve created a pssession on a remote computer and entered that possession. From within that session I use start-process to start notepad. I can confirm that notepad is ru

4条回答
  •  Happy的楠姐
    2020-12-03 20:28

    There are only 2 workarounds that I know of that can make this happen.

    1. Create a task schedule as the logged in user, with no trigger and trigger it manually.
    2. Create a service that starts the process with a duplicated token of the logged in user.

    For the task schedule way I will say that new-scheduledtask is only available in Windows 8+. For windows 7 you need to connect to the Schedule Service to create the task like this (this example also starts the task at logon);

                    $sched = new-object -ComObject("Schedule.Service")
                    $sched.connect()
                    $schedpath = $sched.getFolder("\")
                    $domain = "myDomain"
                    $user="myuser"
    
                    $domuser= "${domain}\${user}"
    
                    $task = $sched.newTask(0) # 0 - reserved for future use
                    $task.RegistrationInfo.Description = "Start My Application"
                    $task.Settings.DisallowStartIfOnBatteries=$false
                    $task.Settings.ExecutionTimeLimit="PT0S" # there's no limit
                    $task.settings.priority=0 # highest
                    $task.Settings.IdleSettings.StopOnIdleEnd=$false
                    $task.settings.StopIfGoingOnBatteries=$false
    
                    $trigger=$task.Triggers.create(9)  # 9 - at logon
                    $trigger.userid="$domuser"  # at logon
    
                    $action=$task.actions.create(0) # 0 - execute a command
                    $action.path="C:\windows\system32\cmd.exe"
                    $action.arguments='/c "c:\program files\vendor\product\executable.exe"'
                    $action.WorkingDirectory="c:\program files\vendor\product\"
    
                    $task.principal.Id="Author"
                    $task.principal.UserId="$domuser"
                    $task.principal.LogonType=3 # 3 - run only when logged on
                    $task.principal.runlevel=1 # with elevated privs
    
                    # 6 - TASK_CREATE_OR_UPDATE
                    $schedpath.RegisterTaskDefinition("MyApplication",$viztask,6,$null,$null,$null)
    
    

    Creating a service is way more complicated, so I'll only outline the calls needed to make it happen. The easy way is to use the invoke-asservice script on powershell gallery: https://www.powershellgallery.com/packages/InvokeAsSystem/1.0.0.0/Content/Invoke-AsService.ps1

    Use WTSOpenServer and WTSEnumerateSessions to get the list of sessions on the machine. You also need to use WTSQuerySessionInformation on each session to get additional information like username. Remember to free your resources using WTSFreeMemory and WTSCloseServer You'll end up with some data which looks like this (this is from the qwinsta command);

     SESSIONNAME       USERNAME                 ID  STATE   
     services                                    0  Disc
    >rdp-tcp#2         mheath                    1  Active 
     console                                     2  Conn
     rdp-tcp                                 65536  Listen
    

    Here's an SO post about getting this data; How do you retrieve a list of logged-in/connected users in .NET?

    This is where you implement your logic to determine which session to target, do you want to display it on the Active desktop regardless of how it's being presented, over RDP or on the local console? And also what will you do if there is no one logged on? (I've setup auto logon and call a lock desktop command at logon so that a logged in user is available.) You need to find the process id of a process that is running on the desktop as that user. You could go for explorer, but your machine might be Server Core, which explorer isn't running by default. Also not a good idea to target winlogon because it's running as system, or dwm as it's running as an unprivileged user. The following commands need to run in a service as they require privileges that only system services have. Use OpenProcess to get the process handle, use OpenProcessToken to get the security token of the process, duplicate the token using DuplicateTokenEx then call ``CreateProcessAsUser``` and finally Close your handles.

    The second half of this code is implemented in invoke-asservice powershell script.

    You can also use the sysinternals tool psexec, I didn't list it as a 3rd way because it just automates the process of creating a service.

提交回复
热议问题