Finding RDP sessions on servers using PowerShell |

Adding the qwinsta command

Because we have to use an external command in our script we will simply use the command inline with other script actions. The interesting thing about this is that we can run the command easily and pass the computer name parameter which we have assigned to $ServerName:

qwinsta /server:$ServerName

To be able to leverage the PowerShell goodness we have to assign the output to a variable so that we can reuse it as needed:

$queryResults = qwinsta /server:$ServerName

Luckily PowerShell makes it just that easy to capture the output of external commands as well as native CmdLets.

Managing the qwinsta output of querying rdp sessions

When you look at the script you can see that the QWINSTA command line is not quite as simple as I’ve shown above. This is because the output of the QWINSTA command isn’t in a neat and tidy one line format like we really would prefer:

This is why we have a much more complex command line in the script:

$queryResults = (qwinsta /server:$ServerName | foreach { (($_.trim() -replace “s ”,”,”))} | ConvertFrom-Csv)

Query – получение информации о сеансах удаленных рабочих столов.

query session /server:rdserver /mode – отобразить сведения о параметрах последовательного порта – скорость передачи, длина посылки, тип контроля четности, длина стоповых бит.

query session /server:SERVER /counter – отобразить статистические сведения о сеансах удаленного рабочего стола сервера SERVER. В этом случае, кроме списка активных сеансов, отображается еще и статистика в виде :


Всего сеансов создано: 185955

Всего сеансов отключено: 186146

Всего сеансов переподключено: 261

query session 1446 – отобразить сведения о сеансе с идентификатором ID=1446

query session admin /server:rdpserver – отобразить сведения о сеансе пользователя admin

qwinsta – отобразить информацию о всех сеансах всех пользователей текущего компьютера. Локальные сеансы отображаются с именем console, удаленные – rdp-tcp#N

Для получения сведений о терминальных серверах домена используется команда:


QUERY TERMSERVER [имясервера] [/DOMAIN:домен] [/ADDRESS] [/CONTINUE]

Параметры командной строки:

имя_сервера – Задает сервер, обслуживающий сеансы подключения к удаленному рабочему столу.

/DOMAIN:домен – Отображение информации для указанного домена (по умолчанию для текущего домена).

/ADDRESS – Отображение адресов сети и узлов.

/CONTINUE – Не останавливаться при заполнении каждого экрана.

Примеры использования:

query termserver – отобразить информацию о всех терминальных серверах текущего домена.

query termserver RDserver /ADDRESS – отобразить информацию о терминальном сервере RDserver текущего домена, включая его адрес.

qappsrv.exe /domain:MyDom – отобразить информацию о терминальных серверах домена MyDom .

Для отображения сведений о процессах используется команда:


QUERY PROCESS [* | < ID процесса > | < пользователь > | < имя сеанса > | /ID:nn < имя программы >] /SERVER:< сервер >]

:/>  Способы устранения ошибки запуска cmd.exe

Параметры командной строки:

* – Отображать все видимые процессы.

ID процесса – Отображение процесса, заданного этим идентификатором.

пользователь – Отображение всех процессов для данного имени пользователя.

имя сеанса – Отображение всех процессов для указанного сеанса.

/ID:nn – Отображение всех процессов для сеанса nn.

имя программы – Отображение всех процессов, связанных с этой программой.

/SERVER:имя_сервера Опрашиваемый сервер, обслуживающий сеансы подключения к удаленному рабочему столу.

Примеры использования QPROCESS:

QUERY PROCESS /? – отобразить подсказку по использованию команды.

QUERY PROCESS * – отобразить сведения обо всех видимых процессах

QUERY PROCESS – при выполнении команды без параметров, отображаются сведения о процессах текущего пользователя.

QUERY PROCESS /server:winsrv – отобразить процессы текущего пользователя на сервере с именем winsrv

QUERY PROCESS /server:192.168.0.1 – отобразить процессы текущего пользователя на сервере с IP-адресом 192.168.0.1

QUERY PROCESS user1 – отобразить сведения о процессах, выполняющихся в контексте пользователя с именем user1

query process система – отобразить сведения о системных процессах.

QUERY PROCESS svchost.exe – отобразить сведения о процессах, связанных с исполняемым файлом svchost.exe

При получении сведений о процессах, связанных с исполняемым файлом, указывать расширение обязательно. Например:

query process services.exe – отобразить сведения о процессах, связанных с исполняемым файлом services.exe

query process services – отобразить сведения о процессах, связанных с сеансом services

query process console – отобразить все процессы сеанса console – локального пользователя Windows.

query process rdp-tcp#0 – отобразить все процессы, связанные с удаленным сеансом rdp-tcp#0.

QPROCESS /ID:144 – отобразить процессы сеанса с идентификатором 144

Пример отображаемой информации:

system
smss.exe
csrss.exe
wininit.exe
csrss.exe
winlogon.exe
services.exe
dwm.exe
svchost.exe
svchost.exe
taskhostex.exe
explorer.exe
cmd.exe
conhost.exe
qprocess.exe

При большом объеме информации, можно использовать команду QUERY PROCESS в цепочке с командой more :

Query Process | more

Для получения сведений о пользователях используется команда:


QUERY USER [< пользователь > | < имя сеанса > | < ID сеанса >] [/SERVER:< сервер >]

Параметры командной строки:

пользователь – Имя пользователя.

имя сеанса – Имя сеанса.

ID сеанса – Идентификатор сеанса.

/SERVER:сервер – Опрашиваемый сервер (по умолчанию – текущий).

Примеры использования команды QUERY USER:

QUERY USER /? – отобразить подсказку по использованию команды.

QUERY USER – при выполнении команды QUERY USER без параметров, отображаются сведения о всех пользователях, вошедших в систему на данный момент времени.

Пример отображаемой информации:

При выполнении команды, отображаются имена пользователей, тип сеанса, идентификатор, статус, время бездействия и время входа в систему. В примере, пользователь user1 вошел в систему локально ( сеанс console, а пользователь user2 – удаленно (сеанс rdp-tcp#0)

QUERY USER /server:winsrv – отобразить информацию о пользователях, вошедших в систему на компьютере с именем winsrv. Результат выполнения команды зависит от прав пользователя по отношению к удаленной системе и настроек брандмауэра.

:/>  Batch Script - Quick Guide

QUSER /server:192.168.0.1 – отобразить информацию о пользователях, вошедших в систему на компьютере с IP-адресом 192.168.0.1

Весь список команд CMD Windows

Qwinsta – «ошибка [5] – отказано в доступе»

Найдено на веб-сайте Dell, это сработало для меня с той же проблемой. “Это означает, что удаленному компоненту RPC не удалось выполнить запрошенную операцию. Это связано с тем, что по умолчанию ему не разрешено работать со службой терминала (удаленный рабочий стол) через RPC. Чтобы изменить этот параметр, чтобы включить API удаленного рабочего стола через RPC, вам необходимо найдите следующий раздел реестра:

HKLM SYSTEM CurrentControlSet Control Терминальный сервер

Затем добавьте значение DWORD с именем «AllowRemoteRPC» и измените его значение на 1. “

В моем случае он был установлен на «0». Я поменял его на 1, и все было хорошо.

The magic of qwinsta

One of the challenges with this activity is that PowerShell does not have a native CmdLet to extract RDP information from servers. Luckily, we can use a hybrid approach here to solve that problem.

WIndows ships with two tools named QWINSTA.exe and RWINSTA.exe for querying and resetting Remote Desktop Services sessions. For our purposes we will use QWINSTA (apparently stands for Query WINdows STAtion).

You can find the options in the command line by typing QWINSTA /? as shown here:

The process to get rdp sessions with powershell and qwinsta

There is a simple flow to the script which is:

Сброс зависших rdp сессий

Всем у кого в хозяйстве есть терминальные сервера на Windows приходится сталкиваться с зависшими сессиями.

Сессии частенько зависают, если пользователь просто закрыл окно терминала.

Естественно, все мы настраиваем параметры сброса сессий по времени и отключению пользователя, но бывает что сессии все равно не завершаются и тогда мы используем команды:

qwinsta — просмотр сессий

и

rwinsta — сброс сессий

Абсолютно уверен что скриптик, который сам отслеживает и сбрасывет зависшие сессии, написали многие, но не выложили в сеть потому что это просто, я выложу для тех кто ищет и кому это нужно прямо сейчас:

Скрипт получает список сессий qwinsta, выбирает сессии со статусом Диск (“*ЁбЄ*” — это тоже «Диск», просто в кривой кодировке, добавлено на всякий случай) и rwinsta сбрасывает сесии.
В скриптике rwinsta — закомментирована, чтоб сессии сбрасывались раскомментируйте.
В текущем виде скрипт просто покажет вам зависшие сессии.

# Сброс зависших сессий, добавьте в расписание на своем скрипт сервере
Function RDP_Resetfailure($server){
	$ts = qwinsta /server:$server
	$td = ($ts | where { ($_ -like "*Disc*" -or $_ -like "*Диск*" -or $_ -like "*ЁбЄ*" ) -and $_ -notlike "*services*"})
	$tdselect = $td # Для отладки или внесения в лог: Login Id State
        $td = $td -ireplace ("[a-z][0-9]","") # убираем логины содержащие цифры
	$td = $td -ireplace ("[^0-9]","") # оставляем только id сессий
	for($i=0; $i -lt $td.Count; $i  ){
		Write-Host Reset RDP Failture session ID: $td[$i] $tdselect[$i]      #отладка просмотр id сессий
		#rwinsta $td[$i] /server:$server            # сброс зависших сессий, раскомментируйте эту строку
	}
}

$server = "MyRDPServer"
RDP_Resetfailure($server)


Добавка для тех кто предпочитает сбрасывать вручную или выборочно:

# Для корректного отображения русской кодировки в консоли
[Console]::outputEncoding = [System.Text.Encoding]::GetEncoding('cp866') 

Function RDP_Resetfailure($server){
	$ts = qwinsta /server:$server
	$td = ($ts | where { ($_ -like "*Disc*" -or $_ -like "*Диск*" -or $_ -like "*ЁбЄ*" ) -and $_ -notlike "*services*"})
    $tdselect = $td # Для отладки или внесения в лог: Login Id State
        $td = $td -ireplace ("[a-z][0-9]","") # убираем логины содержащие цифры
	$td = $td -ireplace ("[^0-9]","") # оставляем только id сессий
    Clear-Host
    Write-Host "
    Список зависших сессий:
    "
	for($i=0; $i -lt $td.Count; $i  ){
		Write-Host Reset RDP Failture session ID: $td[$i] $tdselect[$i]      #отладка просмотр id сессий
	}

    Write-Host
    if($td[0]){
        Write-Host "
        - Для сброса всех сесcий введите 0 
        - Или введите ID сбрасывемой сессии
        ====================================
        "
        $r = Read-Host -Prompt "Ваш выбор"
        Write-Host =============================
        # ==== Сброс всех сессий! =====
        if($r -eq 0 ){
            Write-Host
            Write-Host ==== Сброс всех сессий! =====
            for($i=0; $i -lt $td.Count; $i  ){
		        Write-Host Reset RDP Failture session ID: $td[$i] $tdselect[$i]      #отладка просмотр id сессий
		        #rwinsta $td[$i] /server:$server            # сброс зависших сессий, раскомментируйте эту строку
                Write-Host
	        }
        }

        # Сброс сессии ID
        if($r -gt 0 ){
            $tdu = $tdselect | where { $_ -match ' ' $r  }
            Write-Host Reset RDP Failture session ID: $r $tdu
            #rwinsta $r /server:$server # сброс зависшей сессии, раскомментируйте эту строку
        }
    }
}

$server = "MyRDPServer"
RDP_Resetfailure($server)

Logging and emailing the results of powershell and qwinsta querying rdp sessions

The logging of the output is quite simple. We just want to collect each line as we loop through the sessions and the add the content into a variable ($SessionList).

Once we have completed querying each of the computers, the loop exits and then we put together our email message using the Send-MailMessage CmdLet:

Send-MailMessage -To $emailTo -Subject $subject -Body $SessionList -SmtpServer $smtpServer -From $emailFrom -Priority $priority

The parameters for the Send-MailMessage command come from those defined in the static variables at the beginning of the script and with the $SessionList which was created during the script run.

Оставьте комментарий

Adblock
detector