Бывает, что у пользователя виснет терминальная сессия, хотелось бы дать ему возможность как-нить её "убить". Как это может сделать админ через диспетчер служб терминалов.
» Разрешить отключение терминальных сессий пользователями
Привет
Команда reset session
Позволяет сбросить (удалить) сеансы с сервера терминалов.
reset session {sessionname | sessionid} [/server:servername] [/v]
Аргументы
sessionname
Отображает имя сбрасываемого сеанса. Для определения имени сеанса используйте команду Query session.
sessionid
Отображает код сбрасываемого сеанса.
/server:servername
Определяет сервер терминалов, содержащий сбрасываемый сеанс. Иначе используется текущий сервер терминалов.
/v
А так жми F1 в диспетчере много полезного еще найдешь
Команда reset session
Позволяет сбросить (удалить) сеансы с сервера терминалов.
reset session {sessionname | sessionid} [/server:servername] [/v]
Аргументы
sessionname
Отображает имя сбрасываемого сеанса. Для определения имени сеанса используйте команду Query session.
sessionid
Отображает код сбрасываемого сеанса.
/server:servername
Определяет сервер терминалов, содержащий сбрасываемый сеанс. Иначе используется текущий сервер терминалов.
/v
А так жми F1 в диспетчере много полезного еще найдешь
Я залогинился на САМ теpминальный сеpвеp по консольной сессии под Администpатоpом. Видимо, по логике, с дpугого клиента могу подключиться, а с самого сеpвеpа к какому либо клиенту - не удастся :--( Возможно все же подключиться или вообще никак?
И еще я вот что хотел узнать. Что такое "консоль" в понятии Windows и в общем понятии?
Почему моя сессия - консольная? Я поpыскал на эту тему в Инете, однако ответа не
нашел :--) Бывают RDP-сессии, консольная сессии. Есть еще Listener
(слушатель)-сессии, это что? Какие еще бывают сессии?
И еще я вот что хотел узнать. Что такое "консоль" в понятии Windows и в общем понятии?
Почему моя сессия - консольная? Я поpыскал на эту тему в Инете, однако ответа не
нашел :--) Бывают RDP-сессии, консольная сессии. Есть еще Listener
(слушатель)-сессии, это что? Какие еще бывают сессии?
qwinsta /server:имя сервера
Вывод информации о сеансах на сервере
rwinsta ID /server:имя сервера
ID взять из логов qwinsta
сброс сессии ID
tsdiscon ID /server:имя сервера
ID взять из логов qwinsta
отключение сессии ID
tsdiscon простой logoff
Вывод информации о сеансах на сервере
rwinsta ID /server:имя сервера
ID взять из логов qwinsta
сброс сессии ID
tsdiscon ID /server:имя сервера
ID взять из логов qwinsta
отключение сессии ID
tsdiscon простой logoff
Цитата:
Бывают RDP-сессии, консольная сессии. Есть еще Listene
RDP - это сессии подключенных пользователей. (Remote Desktop Protocol)
Консольная - это сессия на самом сервере - на его мониторе и клаве с мышкой
Listener - сессия ожидающая подключения пользователя
vasua
можно сделать через групповую политику сброс таких сессий.
можно сделать через групповую политику сброс таких сессий.
а это право можно делигировать ?
чтобы простой пользователь мог сбрасывать ?
чтобы простой пользователь мог сбрасывать ?
такой вопрос, хочу написать батник, который выкидывал определенных пользователей из терминала если они подключены в определенное время. как мне написать чтобы пользователей выкинуло с логином Вася, Пуся и тп... или выкинуть всех кроме Админа ? если можно то полностью команду написать
батник будет стартовать перед выгрузкой в 1С, пользователи у которых остался открытый сеанс чтобы выкинуло из терминала.
батник будет стартовать перед выгрузкой в 1С, пользователи у которых остался открытый сеанс чтобы выкинуло из терминала.
А вариант написать скрипт, который бы ждал завершения работы 1С, а потом принудительно делал logoff???
Я сделал так
Код:
Set WshShell = WScript.CreateObject("WScript.Shell")
WSHShell.Run """C:\Program Files (x86)\1cv81\bin\1cv8.exe""",5,true
WSHShell.Run "logoff"
Я сделал так
Код:
Set WshShell = WScript.CreateObject("WScript.Shell")
WSHShell.Run """C:\Program Files (x86)\1cv81\bin\1cv8.exe""",5,true
WSHShell.Run "logoff"
тоже интересует, как убить сессию из под пользователя не являющемся админом?
никто не знает чтоли?
adamst
Насчет батника не знаю, в свое время писал программу на C#
Компилишь консольное приложение и назначаешь его на выполнение в нужное время.
через диспетчер задач. В качестве параметра - имя терминального сервера.
В массиве pwusers пишешь логины тех, кого не надо трогать.
Остальных вышибаешь из сессии.
[more]
Код:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace TSLogout
{
class Program
{
[DllImport("wtsapi32.dll")]
static extern IntPtr WTSOpenServer([MarshalAs(UnmanagedType.LPStr)] String pServerName);
[DllImport("wtsapi32.dll")]
static extern void WTSCloseServer(IntPtr hServer);
[DllImport("wtsapi32.dll")]
static extern void WTSLogoffSession(IntPtr hServer, int sessionId, bool wait);
[DllImport("wtsapi32.dll")]
static extern Int32 WTSEnumerateSessions(
IntPtr hServer,
[MarshalAs(UnmanagedType.U4)] Int32 Reserved,
[MarshalAs(UnmanagedType.U4)] Int32 Version,
ref IntPtr ppSessionInfo,
[MarshalAs(UnmanagedType.U4)] ref Int32 pCount);
[DllImport("wtsapi32.dll")]
static extern void WTSFreeMemory(IntPtr pMemory);
[DllImport("Wtsapi32.dll")]
static extern bool WTSQuerySessionInformation(
System.IntPtr hServer, int sessionId, WTS_INFO_CLASS wtsInfoClass, out System.IntPtr ppBuffer, out uint pBytesReturned);
[StructLayout(LayoutKind.Sequential)]
private struct WTS_SESSION_INFO
{
public Int32 SessionID;
[MarshalAs(UnmanagedType.LPStr)]
public String pWinStationName;
public WTS_CONNECTSTATE_CLASS State;
}
public enum WTS_INFO_CLASS
{
WTSInitialProgram,
WTSApplicationName,
WTSWorkingDirectory,
WTSOEMId,
WTSSessionId,
WTSUserName,
WTSWinStationName,
WTSDomainName,
WTSConnectState,
WTSClientBuildNumber,
WTSClientName,
WTSClientDirectory,
WTSClientProductId,
WTSClientHardwareId,
WTSClientAddress,
WTSClientDisplay,
WTSClientProtocolType
}
public enum WTS_CONNECTSTATE_CLASS
{
WTSActive,
WTSConnected,
WTSConnectQuery,
WTSShadow,
WTSDisconnected,
WTSIdle,
WTSListen,
WTSReset,
WTSDown,
WTSInit
}
public static IntPtr serverHandle = IntPtr.Zero;
static void Main(string[] args)
{
if (args.Length == 0 )
{
Console.WriteLine("No server specified!");
return;
}
string tsserv = args[0];
if (tsserv.Length < 2)
{
Console.WriteLine("No server specified!");
return;
}
serverHandle = OpenServer(tsserv);
if (serverHandle == IntPtr.Zero)
{
Console.WriteLine("Cannot find server " + tsserv);
return;
}
LogoutUsers();
// Console.ReadKey();
}
public static int IsValid(string user)
{
string[] pwusers = { "administrator","vasya","petya","masha" };
for (int i = 0; i < pwusers.Length; i++)
{
if(pwusers[nn].Equals(user,StringComparison.CurrentCultureIgnoreCase))
return 1;
}
return 0;
}
public static IntPtr OpenServer(String Name)
{
IntPtr server = WTSOpenServer(Name);
return server;
}
public static void CloseServer(IntPtr ServerHandle)
{
WTSCloseServer(ServerHandle);
}
public static void LogoutUsers()
{
List<String> resultList = new List<string>();
try
{
IntPtr SessionInfoPtr = IntPtr.Zero;
IntPtr userPtr = IntPtr.Zero;
IntPtr domainPtr = IntPtr.Zero;
Int32 sessionCount = 0;
Int32 retVal = WTSEnumerateSessions(serverHandle, 0, 1, ref SessionInfoPtr, ref sessionCount);
Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));
Int32 currentSession = (int)SessionInfoPtr;
uint bytes = 0;
if (retVal != 0)
{
for (int nn = 0; nn < sessionCount; nn++)
{
string user;
WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)currentSession, typeof(WTS_SESSION_INFO));
currentSession += dataSize;
WTSQuerySessionInformation(serverHandle, si.SessionID, WTS_INFO_CLASS.WTSUserName, out userPtr, out bytes);
WTSQuerySessionInformation(serverHandle, si.SessionID, WTS_INFO_CLASS.WTSDomainName, out domainPtr, out bytes);
user = Marshal.PtrToStringAnsi(userPtr);
if (user.Length == 0 || IsValid(user) == 1)
continue;
else
WTSLogoffSession(serverHandle, si.SessionID, false);
// Console.WriteLine("Domain and User: " + Marshal.PtrToStringAnsi(domainPtr) + "\\" + user);
}
WTSFreeMemory(SessionInfoPtr);
}
}
finally
{
CloseServer(serverHandle);
}
}
}
}
Насчет батника не знаю, в свое время писал программу на C#
Компилишь консольное приложение и назначаешь его на выполнение в нужное время.
через диспетчер задач. В качестве параметра - имя терминального сервера.
В массиве pwusers пишешь логины тех, кого не надо трогать.
Остальных вышибаешь из сессии.
[more]
Код:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace TSLogout
{
class Program
{
[DllImport("wtsapi32.dll")]
static extern IntPtr WTSOpenServer([MarshalAs(UnmanagedType.LPStr)] String pServerName);
[DllImport("wtsapi32.dll")]
static extern void WTSCloseServer(IntPtr hServer);
[DllImport("wtsapi32.dll")]
static extern void WTSLogoffSession(IntPtr hServer, int sessionId, bool wait);
[DllImport("wtsapi32.dll")]
static extern Int32 WTSEnumerateSessions(
IntPtr hServer,
[MarshalAs(UnmanagedType.U4)] Int32 Reserved,
[MarshalAs(UnmanagedType.U4)] Int32 Version,
ref IntPtr ppSessionInfo,
[MarshalAs(UnmanagedType.U4)] ref Int32 pCount);
[DllImport("wtsapi32.dll")]
static extern void WTSFreeMemory(IntPtr pMemory);
[DllImport("Wtsapi32.dll")]
static extern bool WTSQuerySessionInformation(
System.IntPtr hServer, int sessionId, WTS_INFO_CLASS wtsInfoClass, out System.IntPtr ppBuffer, out uint pBytesReturned);
[StructLayout(LayoutKind.Sequential)]
private struct WTS_SESSION_INFO
{
public Int32 SessionID;
[MarshalAs(UnmanagedType.LPStr)]
public String pWinStationName;
public WTS_CONNECTSTATE_CLASS State;
}
public enum WTS_INFO_CLASS
{
WTSInitialProgram,
WTSApplicationName,
WTSWorkingDirectory,
WTSOEMId,
WTSSessionId,
WTSUserName,
WTSWinStationName,
WTSDomainName,
WTSConnectState,
WTSClientBuildNumber,
WTSClientName,
WTSClientDirectory,
WTSClientProductId,
WTSClientHardwareId,
WTSClientAddress,
WTSClientDisplay,
WTSClientProtocolType
}
public enum WTS_CONNECTSTATE_CLASS
{
WTSActive,
WTSConnected,
WTSConnectQuery,
WTSShadow,
WTSDisconnected,
WTSIdle,
WTSListen,
WTSReset,
WTSDown,
WTSInit
}
public static IntPtr serverHandle = IntPtr.Zero;
static void Main(string[] args)
{
if (args.Length == 0 )
{
Console.WriteLine("No server specified!");
return;
}
string tsserv = args[0];
if (tsserv.Length < 2)
{
Console.WriteLine("No server specified!");
return;
}
serverHandle = OpenServer(tsserv);
if (serverHandle == IntPtr.Zero)
{
Console.WriteLine("Cannot find server " + tsserv);
return;
}
LogoutUsers();
// Console.ReadKey();
}
public static int IsValid(string user)
{
string[] pwusers = { "administrator","vasya","petya","masha" };
for (int i = 0; i < pwusers.Length; i++)
{
if(pwusers[nn].Equals(user,StringComparison.CurrentCultureIgnoreCase))
return 1;
}
return 0;
}
public static IntPtr OpenServer(String Name)
{
IntPtr server = WTSOpenServer(Name);
return server;
}
public static void CloseServer(IntPtr ServerHandle)
{
WTSCloseServer(ServerHandle);
}
public static void LogoutUsers()
{
List<String> resultList = new List<string>();
try
{
IntPtr SessionInfoPtr = IntPtr.Zero;
IntPtr userPtr = IntPtr.Zero;
IntPtr domainPtr = IntPtr.Zero;
Int32 sessionCount = 0;
Int32 retVal = WTSEnumerateSessions(serverHandle, 0, 1, ref SessionInfoPtr, ref sessionCount);
Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));
Int32 currentSession = (int)SessionInfoPtr;
uint bytes = 0;
if (retVal != 0)
{
for (int nn = 0; nn < sessionCount; nn++)
{
string user;
WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)currentSession, typeof(WTS_SESSION_INFO));
currentSession += dataSize;
WTSQuerySessionInformation(serverHandle, si.SessionID, WTS_INFO_CLASS.WTSUserName, out userPtr, out bytes);
WTSQuerySessionInformation(serverHandle, si.SessionID, WTS_INFO_CLASS.WTSDomainName, out domainPtr, out bytes);
user = Marshal.PtrToStringAnsi(userPtr);
if (user.Length == 0 || IsValid(user) == 1)
continue;
else
WTSLogoffSession(serverHandle, si.SessionID, false);
// Console.WriteLine("Domain and User: " + Marshal.PtrToStringAnsi(domainPtr) + "\\" + user);
}
WTSFreeMemory(SessionInfoPtr);
}
}
finally
{
CloseServer(serverHandle);
}
}
}
}
При сбоях работы провайдера, приводящему к сбою сессии, для завершения сеансов мои пользователи пользуются следующим батником:
Код:
@echo off
echo Перед тем, как продолжить, сохраните и закройте все свои подключения к удаленному рабочему столу. После чего нажмите Enter
pause
FOR /F "skip=1" %%i in ('qwinsta #Имя пользователя на сервере# /SERVER:#Адрес сервера#') do logoff %%i /SERVER:#Адрес сервера#
Код:
@echo off
echo Перед тем, как продолжить, сохраните и закройте все свои подключения к удаленному рабочему столу. После чего нажмите Enter
pause
FOR /F "skip=1" %%i in ('qwinsta #Имя пользователя на сервере# /SERVER:#Адрес сервера#') do logoff %%i /SERVER:#Адрес сервера#
Вот такой вариант.
На сервере создаём новую группу пользователей. В "Настройках служб терминалов" во вкладке разрешения даём это группе полные права. А далее добавляем в эту группу тех сотрудников, котрым мы хотим дать возможность принудительного сбрасывания оставленных сессий. Этот сотрудник убивает сессии через tsadmin.
На сервере создаём новую группу пользователей. В "Настройках служб терминалов" во вкладке разрешения даём это группе полные права. А далее добавляем в эту группу тех сотрудников, котрым мы хотим дать возможность принудительного сбрасывания оставленных сессий. Этот сотрудник убивает сессии через tsadmin.
vlary
А чем можно попроще откомпилировать это?
А чем можно попроще откомпилировать это?
Цитата:
А чем можно попроще откомпилировать это?C:\WINDOWS\Microsoft.NET\Framework\(версия)\csc.exe sourcefile.cs
C:\WINDOWS\Microsoft.NET\Framework\(версия)\csc.exe /? выдаст справку
надо исправить:
Код: if(pwusers[nn].Equals(user,StringComparison.CurrentCultureIgnoreCase))
Код: if(pwusers[nn].Equals(user,StringComparison.CurrentCultureIgnoreCase))
slalom Совершенно справедливо. Приводил программу из частного к общему виду, кое-что не причесал до конца.
дел
объясните как пользоваться reset session.
Есть такая ситуация что пользователи по RDP выходят из сеанса, а он у них висит на завершении и не может завершится, при отключении (выход крестиком) и подключении они снова попадают на синий экран завершения. В таком случае я из диспетчера прибиваю сеанс, но сидеть постоянно на месте и караулить не могу.
нужно чтобы они сами запускали к примеру батник с уже всеми прописанными параметрами (например прописать там что сервер 192,168,0,1 и юзер-101 завершить) узнавать ID сеанса и прочие параметры юзеры не смогут (блондинки работают)
Есть такая ситуация что пользователи по RDP выходят из сеанса, а он у них висит на завершении и не может завершится, при отключении (выход крестиком) и подключении они снова попадают на синий экран завершения. В таком случае я из диспетчера прибиваю сеанс, но сидеть постоянно на месте и караулить не могу.
нужно чтобы они сами запускали к примеру батник с уже всеми прописанными параметрами (например прописать там что сервер 192,168,0,1 и юзер-101 завершить) узнавать ID сеанса и прочие параметры юзеры не смогут (блондинки работают)
Наверно самый простой способ это через политики выставить сброс отключенного сеанса через 1 мин. и все. у меня на работе так и сделано
Делегирование права не нужно просто выставь в настройке терминального сервера отключение
Делегирование права не нужно просто выставь в настройке терминального сервера отключение
Цитата:
Есть такая ситуация что пользователи по RDP выходят из сеанса, а он у них висит на завершении и не может завершится, при отключении (выход крестиком) и подключении они снова попадают на синий экран завершения.
При такой ситуации сервер терминалов ни при чём. Надо сбросить процесс mstsс.exe на локальной машине.
var wbemFlagReturnImmediately = 0x10;
var wbemFlagForwardOnly = 0x20;
var objWMIService = GetObject("winmgmts:\\\\.\\root\\CIMV2");
var colItems = objWMIService.ExecQuery("SELECT * FROM Win32_Process", "WQL", wbemFlagReturnImmediately | wbemFlagForwardOnly);
var enumItems = new Enumerator(colItems);
for (; !enumItems.atEnd(); enumItems.moveNext())
{
var objItem = enumItems.item();
if(objItem.Name == "mstsc.exe")
{
ret = objItem.Terminate;
if (ret == 0)
{
WScript.Echo ("Терминальная Сессия сброшена");
WScript.Quit();
}
else
{
WScript.Echo ("Код ошибки = "+ret);
WScript.Quit();
}
}
else
{
continue;
}
}
WScript.Echo ("Терминальная Сессия не была активна");
Цитата:
Цитата:
Есть такая ситуация что пользователи по RDP выходят из сеанса, а он у них висит на завершении и не может завершится, при отключении (выход крестиком) и подключении они снова попадают на синий экран завершения.
При такой ситуации сервер терминалов ни при чём. Надо сбросить процесс mstsс.exe на локальной машине.
var wbemFlagReturnImmediately = 0x10;
var wbemFlagForwardOnly = 0x20;
var objWMIService = GetObject("winmgmts:\\\\.\\root\\CIMV2");
var colItems = objWMIService.ExecQuery("SELECT * FROM Win32_Process", "WQL", wbemFlagReturnImmediately | wbemFlagForwardOnly);
var enumItems = new Enumerator(colItems);
for (; !enumItems.atEnd(); enumItems.moveNext())
{
var objItem = enumItems.item();
if(objItem.Name == "mstsc.exe")
{
ret = objItem.Terminate;
if (ret == 0)
{
WScript.Echo ("Терминальная Сессия сброшена");
WScript.Quit();
}
else
{
WScript.Echo ("Код ошибки = "+ret);
WScript.Quit();
}
}
else
{
continue;
}
}
WScript.Echo ("Терминальная Сессия не была активна");
Я все понимаю, но неужели тяжело сделать батник, который скачан? Либо выкладывать полный гайд, что 10 летний ребенок разберет и скомпилит.
Это не помощь, это гемморой, честно.
Сомневаюсь что автор появится, но подвисшие после закрытия "1С" сессии, порядком надоели.
Один скрип из ветки про терминалы я попробовал - не пашет.
Может все-таки по этому методу(см.выше), кто-нибудь нормальный faq выложит? буду очень благодарен.
Мало того что набор софта нужен, так еще и понять как и куда это сунуть...
Тут беда в том, что открытые, но не зависшие сессии в 89% не желательно закрытьвать.
Вот я делал как-то батник для своих пользователей.
VTERMIN1 имя терминального сервера .
Суть такая берется имя пользователя (%USERNAME%) и если оно совпадает с именем пользователя на терминальном сервере, то этот сеанс сбрасывается. Иногда бывают траблы с регистром имен пользователей. Но я всех приучил писать учетку с маленькой буквы.
for /f "tokens=2,3" %%i in ('qwinsta /server:VTERMIN1') do (
if %%i==%USERNAME% rwinsta /server:VTERMIN1 %%j /V
)
VTERMIN1 имя терминального сервера .
Суть такая берется имя пользователя (%USERNAME%) и если оно совпадает с именем пользователя на терминальном сервере, то этот сеанс сбрасывается. Иногда бывают траблы с регистром имен пользователей. Но я всех приучил писать учетку с маленькой буквы.
for /f "tokens=2,3" %%i in ('qwinsta /server:VTERMIN1') do (
if %%i==%USERNAME% rwinsta /server:VTERMIN1 %%j /V
)
Мне кажется, что все, написанное в данном посте не помощь, а просто издевательство.
то, что сессии виснут чаще раза в год - говорит о кривой настройке терминальника...
Цитата:
то, что сессии виснут чаще раза в год - говорит о кривой настройке терминальника...
Подскажите пожалуйста вкратце - основные моменты чтобы "настройки терминальника небыли кривыми".
Страницы: 1
Предыдущая тема: apache+mod_perl
Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.