Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » PowerShell - Powershell запуск процесса в другом сеансе

Ответить
Настройки темы
PowerShell - Powershell запуск процесса в другом сеансе

Новый участник


Сообщения: 9
Благодарности: 0

Профиль | Отправить PM | Цитировать


Доброго дня!
Имеется следующая ситуация:
1. Терминальный сервер, несколько пользователей сидят одновременно.
2. Есть несколько пользователей, например: администратор, user1,user2,user3 ....
3. программа запускается в всех пользователей, для примера c:\test\администратор\program.exe, c:\test\user1\program.exe,c:\test\user2\program.exe ....
4. Требуется передать команду программе "prorgam.exe" запустив процесс с ключом для примера /exit.

Но если я например в у пользователя администратор запущу программу от пользователя user1, то это просто запустить новый экземпляр. А требуется передать именно в тот сеанс.
Получается задача: запустить приложение в другом сеансе, причем уже позже windows 7: windows 2008/win 10.

Насколько я понял, что начиная с windows 7 microsoft изменило правила распределения рабочих столов. теперь попасть в другой сеанс или из 0 сессии очень сложно.

Помогите запустить процесс в других сеансах, в powershell.
Это идентично запуску приложение через ключ: PsExec64.exe -d -i -s c:\test\администратор\program.exe


Нашел следующий код:
Код: Выделить весь код
$process = "C:\\Windows\\System32\\calc.exe"
$arguments = $null

Add-Type -TypeDefinition @"
using System;
using System.IO;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace SecureDesktopLauncher
{
  public static class WinApi
  {
    [Flags]
    public enum ACCESS_MASK : uint
    {
      DELETE = 0x00010000,
      READ_CONTROL = 0x00020000,
      WRITE_DAC = 0x00040000,
      WRITE_OWNER = 0x00080000,
      SYNCHRONIZE = 0x00100000,

      STANDARD_RIGHTS_REQUIRED = 0x000f0000,

      STANDARD_RIGHTS_READ = 0x00020000,
      STANDARD_RIGHTS_WRITE = 0x00020000,
      STANDARD_RIGHTS_EXECUTE = 0x00020000,

      STANDARD_RIGHTS_ALL = 0x001f0000,

      SPECIFIC_RIGHTS_ALL = 0x0000ffff,

      ACCESS_SYSTEM_SECURITY = 0x01000000,

      MAXIMUM_ALLOWED = 0x02000000,

      GENERIC_READ = 0x80000000,
      GENERIC_WRITE = 0x40000000,
      GENERIC_EXECUTE = 0x20000000,
      GENERIC_ALL = 0x10000000,

      DESKTOP_READOBJECTS = 0x00000001,
      DESKTOP_CREATEWINDOW = 0x00000002,
      DESKTOP_CREATEMENU = 0x00000004,
      DESKTOP_HOOKCONTROL = 0x00000008,
      DESKTOP_JOURNALRECORD = 0x00000010,
      DESKTOP_JOURNALPLAYBACK = 0x00000020,
      DESKTOP_ENUMERATE = 0x00000040,
      DESKTOP_WRITEOBJECTS = 0x00000080,
      DESKTOP_SWITCHDESKTOP = 0x00000100,

      WINSTA_ENUMDESKTOPS = 0x00000001,
      WINSTA_READATTRIBUTES = 0x00000002,
      WINSTA_ACCESSCLIPBOARD = 0x00000004,
      WINSTA_CREATEDESKTOP = 0x00000008,
      WINSTA_WRITEATTRIBUTES = 0x00000010,
      WINSTA_ACCESSGLOBALATOMS = 0x00000020,
      WINSTA_EXITWINDOWS = 0x00000040,
      WINSTA_ENUMERATE = 0x00000100,
      WINSTA_READSCREEN = 0x00000200,

      WINSTA_ALL_ACCESS = 0x0000037f
    }

    [Flags]
    public enum CreateProcessFlags : uint
    {
      DEBUG_PROCESS = 0x00000001,
      DEBUG_ONLY_THIS_PROCESS = 0x00000002,
      CREATE_SUSPENDED = 0x00000004,
      DETACHED_PROCESS = 0x00000008,
      CREATE_NEW_CONSOLE = 0x00000010,
      NORMAL_PRIORITY_CLASS = 0x00000020,
      IDLE_PRIORITY_CLASS = 0x00000040,
      HIGH_PRIORITY_CLASS = 0x00000080,
      REALTIME_PRIORITY_CLASS = 0x00000100,
      CREATE_NEW_PROCESS_GROUP = 0x00000200,
      CREATE_UNICODE_ENVIRONMENT = 0x00000400,
      CREATE_SEPARATE_WOW_VDM = 0x00000800,
      CREATE_SHARED_WOW_VDM = 0x00001000,
      CREATE_FORCEDOS = 0x00002000,
      BELOW_NORMAL_PRIORITY_CLASS = 0x00004000,
      ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000,
      INHERIT_PARENT_AFFINITY = 0x00010000,
      INHERIT_CALLER_PRIORITY = 0x00020000,
      CREATE_PROTECTED_PROCESS = 0x00040000,
      EXTENDED_STARTUPINFO_PRESENT = 0x00080000,
      PROCESS_MODE_BACKGROUND_BEGIN = 0x00100000,
      PROCESS_MODE_BACKGROUND_END = 0x00200000,
      CREATE_BREAKAWAY_FROM_JOB = 0x01000000,
      CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000,
      CREATE_DEFAULT_ERROR_MODE = 0x04000000,
      CREATE_NO_WINDOW = 0x08000000,
      PROFILE_USER = 0x10000000,
      PROFILE_KERNEL = 0x20000000,
      PROFILE_SERVER = 0x40000000,
      CREATE_IGNORE_SYSTEM_DEFAULT = 0x80000000,
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct PROCESS_INFORMATION
    {
      public IntPtr hProcess;
      public IntPtr hThread;
      public int dwProcessId;
      public int dwThreadId;
    }

    public enum SECURITY_IMPERSONATION_LEVEL
    {
      SecurityAnonymous,
      SecurityIdentification,
      SecurityImpersonation,
      SecurityDelegation
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct STARTUPINFO
    {
      public Int32 cb;
      public string lpReserved;
      public string lpDesktop;
      public string lpTitle;
      public Int32 dwX;
      public Int32 dwY;
      public Int32 dwXSize;
      public Int32 dwYSize;
      public Int32 dwXCountChars;
      public Int32 dwYCountChars;
      public Int32 dwFillAttribute;
      public Int32 dwFlags;
      public Int16 wShowWindow;
      public Int16 cbReserved2;
      public IntPtr lpReserved2;
      public IntPtr hStdInput;
      public IntPtr hStdOutput;
      public IntPtr hStdError;
    }

    public enum TOKEN_TYPE
    {
      TokenPrimary = 1,
      TokenImpersonation
    }

    public enum TOKEN_INFORMATION_CLASS : int
    {
      TokenUser = 1,
      TokenGroups,
      TokenPrivileges,
      TokenOwner,
      TokenPrimaryGroup,
      TokenDefaultDacl,
      TokenSource,
      TokenType,
      TokenImpersonationLevel,
      TokenStatistics,
      TokenRestrictedSids,
      TokenSessionId,
      TokenGroupsAndPrivileges,
      TokenSessionReference,
      TokenSandBoxInert,
      TokenAuditPolicy,
      TokenOrigin,
      MaxTokenInfoClass
    };

    public const int READ_CONTROL = 0x00020000;
    public const int STANDARD_RIGHTS_REQUIRED = 0x000F0000;
    public const int STANDARD_RIGHTS_READ = READ_CONTROL;
    public const int STANDARD_RIGHTS_WRITE = READ_CONTROL;
    public const int STANDARD_RIGHTS_EXECUTE = READ_CONTROL;
    public const int STANDARD_RIGHTS_ALL = 0x001F0000;
    public const int SPECIFIC_RIGHTS_ALL = 0x0000FFFF;
    public const int TOKEN_ASSIGN_PRIMARY = 0x0001;
    public const int TOKEN_DUPLICATE = 0x0002;
    public const int TOKEN_IMPERSONATE = 0x0004;
    public const int TOKEN_QUERY = 0x0008;
    public const int TOKEN_QUERY_SOURCE = 0x0010;
    public const int TOKEN_ADJUST_PRIVILEGES = 0x0020;
    public const int TOKEN_ADJUST_GROUPS = 0x0040;
    public const int TOKEN_ADJUST_DEFAULT = 0x0080;
    public const int TOKEN_ADJUST_SESSIONID = 0x0100;

    public const int TOKEN_ALL_ACCESS_P =
      STANDARD_RIGHTS_REQUIRED |
      TOKEN_ASSIGN_PRIMARY |
      TOKEN_DUPLICATE |
      TOKEN_IMPERSONATE |
      TOKEN_QUERY |
      TOKEN_QUERY_SOURCE |
      TOKEN_ADJUST_PRIVILEGES |
      TOKEN_ADJUST_GROUPS |
      TOKEN_ADJUST_DEFAULT;

    public const int TOKEN_ALL_ACCESS =
      TOKEN_ALL_ACCESS_P |
      TOKEN_ADJUST_SESSIONID;

    public const int TOKEN_READ =
      STANDARD_RIGHTS_READ |
      TOKEN_QUERY;

    public const int TOKEN_WRITE =
      STANDARD_RIGHTS_WRITE |
      TOKEN_ADJUST_PRIVILEGES |
      TOKEN_ADJUST_GROUPS |
      TOKEN_ADJUST_DEFAULT;

    public const int TOKEN_EXECUTE = STANDARD_RIGHTS_EXECUTE;

    [DllImport("advapi32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool OpenProcessToken(
      IntPtr ProcessHandle,
      UInt32 DesiredAccess,
      out IntPtr TokenHandle);

    [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern bool CreateProcessAsUser(
      IntPtr hToken,
      string lpApplicationName,
      string lpCommandLine,
      IntPtr lpProcessAttributes,
      IntPtr lpThreadAttributes,
      bool bInheritHandles,
      uint dwCreationFlags,
      IntPtr lpEnvironment,
      string lpCurrentDirectory,
      ref STARTUPINFO lpStartupInfo,
      out PROCESS_INFORMATION lpProcessInformation);

    [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public extern static bool DuplicateTokenEx(
      IntPtr hExistingToken,
      uint dwDesiredAccess,
      IntPtr lpTokenAttributes,
      SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
      TOKEN_TYPE TokenType,
      out IntPtr phNewToken);

    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool SetTokenInformation(
      IntPtr TokenHandle,
      TOKEN_INFORMATION_CLASS TokenInformationClass,
      ref UInt32 TokenInformation,
      UInt32 TokenInformationLength);

    [DllImport("user32.dll", SetLastError = true)]
    public static extern bool LockWorkStation();

    [DllImport("wtsapi32.dll", SetLastError = true)]
    public static extern bool WTSQueryUserToken(
      UInt32 sessionId,
      out IntPtr Token);

    [DllImport("kernel32.dll")]
    public static extern uint WTSGetActiveConsoleSessionId();
  }

  public static class Program
  {
    public static void Launch(string process, string arguments = "")
    {
      string currentDirectory = Path.GetDirectoryName(process);

      IntPtr currentToken = IntPtr.Zero;
      IntPtr newToken = IntPtr.Zero;
      IntPtr interactiveUserToken = IntPtr.Zero;

      UInt32 dwSessionId = WinApi.WTSGetActiveConsoleSessionId();

      WinApi.OpenProcessToken(
        Process.GetCurrentProcess().Handle,
        WinApi.TOKEN_DUPLICATE,
        out currentToken);

      WinApi.DuplicateTokenEx(
        currentToken,
        (uint)WinApi.ACCESS_MASK.GENERIC_ALL,
        IntPtr.Zero,
        WinApi.SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
        WinApi.TOKEN_TYPE.TokenImpersonation,
        out newToken);

      WinApi.SetTokenInformation(
        newToken,
        WinApi.TOKEN_INFORMATION_CLASS.TokenSessionId,
        ref dwSessionId,
        sizeof(UInt32));

      if (WinApi.WTSQueryUserToken(
        WinApi.WTSGetActiveConsoleSessionId(),
        out interactiveUserToken))
      {
        WinApi.STARTUPINFO siInteractive = new WinApi.STARTUPINFO();

        siInteractive.cb = Marshal.SizeOf(siInteractive);
        siInteractive.lpDesktop = @"Winsta0\default";

        WinApi.PROCESS_INFORMATION piInteractive =
          new WinApi.PROCESS_INFORMATION();

        WinApi.CreateProcessAsUser(
          interactiveUserToken,
          null,
          "rundll32.exe user32.dll,LockWorkStation",
          IntPtr.Zero,
          IntPtr.Zero,
          false,
          (uint)WinApi.CreateProcessFlags.CREATE_NEW_CONSOLE |
            (uint)WinApi.CreateProcessFlags.INHERIT_CALLER_PRIORITY,
          IntPtr.Zero,
          currentDirectory,
          ref siInteractive,
          out piInteractive);
      }
      else
      {
        WinApi.LockWorkStation();
      }

      System.Threading.Thread.Sleep(1000);

      WinApi.STARTUPINFO si = new WinApi.STARTUPINFO();

      si.cb = Marshal.SizeOf(si);
      si.lpDesktop = @"Winsta0\Winlogon";

      WinApi.PROCESS_INFORMATION pi = new WinApi.PROCESS_INFORMATION();

      string commandline = "\"" + process + "\" " + arguments;

      WinApi.CreateProcessAsUser(
        newToken,
        null,
        commandline,
        IntPtr.Zero,
        IntPtr.Zero,
        true,
        (uint)WinApi.CreateProcessFlags.CREATE_NEW_CONSOLE |
          (uint)WinApi.CreateProcessFlags.INHERIT_CALLER_PRIORITY,
        IntPtr.Zero,
        currentDirectory,
        ref si,
        out pi);
    }
  }
}
"@

[SecureDesktopLauncher.Program]::Launch($process, $arguments)
Мне главное найти способ как запустить у всех сеансов которые я перечислю. (найду где запущены процессы)

Отправлено: 11:19, 09-10-2019

 

Ветеран


Сообщения: 3125
Благодарности: 657

Профиль | Отправить PM | Цитировать


Цитата morgan-12l1:
Требуется передать команду программе "prorgam.exe" запустив процесс с ключом для примера /exit »
это целиком и полностью зависит от внутреннего устройства prorgam.exe

Что должно произойти если у пользователя запущено два экземпляра prorgam.exe, и он выполняет prorgam.exe /exit ?

Вам лучше искать решение для конкретного ПО.

Можно наклепать watcher, который запускается в фоне при логоне пользователя, и уже в него передавать команду.

Отправлено: 11:13, 10-10-2019 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Новый участник


Сообщения: 9
Благодарности: 0

Профиль | Отправить PM | Цитировать


В данном случаи, требуется просто передать команду. Если запущено несколько процессов в 1 сеансе - оба закроются.
Сложность в том, что этот скрипт будет запускаться когда потребуется только.
сейчас главная задача: захватить токен,и запустить с ним процесс в других сеансах

Отправлено: 12:21, 10-10-2019 | #3



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Скриптовые языки администрирования Windows » PowerShell - Powershell запуск процесса в другом сеансе

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
[решено] Как запретить запуск двух и более копий 1С8 в Терминальном сеансе пользователя! sigmatik Хочу все знать 20 15-06-2019 11:48
Не понятная активность процесса Powershell.exe carloscom Лечение систем от вредоносных программ 8 22-11-2017 09:38
Доступ - Как запустить программу в другом сеансе ОС? mar1boro Microsoft Windows 2000/XP 7 02-11-2010 01:55
C/C++ - Запуск процесса до авторизации пользователя EvgeniyQQQ Программирование и базы данных 8 14-01-2008 04:48
Периодический запуск процесса (WinAPI) darxeth Программирование и базы данных 1 26-02-2004 15:11




 
Переход