Connecting to an active user session (powershell-gui)

The moment has come when it is necessary to move away from all foreign remote connection programs, at least in our company. Having looked at domestic analogues, we were horrified by the cost and quality of the software. Having thought about what functionality we need to connect 1-line to users, we realized:

  1. GUI

  2. List of PCs to connect to

  3. Controlling a PC without user consent

This means that a simple powershell will be enough for us.

To perform further actions, you must install the module Active Directory for PowerShell

We create a form; in this form we add a combination of login/password for connection and a list of PCs

Add-Type -assembly System.Windows.Forms
$window_form = New-Object System.Windows.Forms.Form
$window_form.Text="Подключение к удаленному рабочему столу"
$window_form.Width = 240
$window_form.Height = 550
$window_form.StartPosition = 'CenterScreen'

$FormLabel1 = New-Object System.Windows.Forms.Label
$FormLabel1.Text = "Введите логин:"
$FormLabel1.Location = New-Object System.Drawing.Point(10,10)
$FormLabel1.AutoSize = $true
$window_form.Controls.Add($FormLabel1)

$FormTextBox1 = New-Object System.Windows.Forms.TextBox
$FormTextBox1.Width = 200
$FormTextBox1.Location = New-Object System.Drawing.Point(10,25)

$FormLabel2 = New-Object System.Windows.Forms.Label
$FormLabel2.Text = "Введите пароль:"
$FormLabel2.Location = New-Object System.Drawing.Point(10,50)
$FormLabel2.AutoSize = $true

$FormTextBox2 = New-Object System.Windows.Forms.TextBox
$FormTextBox2.Width = 200
$FormTextBox2.text = $NULL
$FormTextBox2.Location = New-Object System.Drawing.Point(10,65)

$FormLabel3 = New-Object System.Windows.Forms.Label
$FormLabel3.Text = "Выберете компьютер для подключения:"
$FormLabel3.Location = New-Object System.Drawing.Point(10,90)
$FormLabel3.AutoSize = $true

$ListBox = New-Object System.Windows.Forms.ListBox
$ListBox.Width = 200
$ListBox.Height = 300
$ListBox.Location = New-Object System.Drawing.Point(10,105)

$FormButton = New-Object System.Windows.Forms.Button
$FormButton.Location = New-Object System.Drawing.Size(10,400)
$FormButton.Size = New-Object System.Drawing.Size(200,30)
$FormButton.Text = "Подключится"
$window_form.AcceptButton = $FormButton

$FormButton2 = New-Object System.Windows.Forms.Button
$FormButton2.Location = New-Object System.Drawing.Size(10,440)
$FormButton2.Size = New-Object System.Drawing.Size(200,30)
$FormButton2.Text = "Закрыть"
$window_form.CancelButton = $FormButton3
$FormButton2.Add_Click({$window_form.Close();$window_form.Visible=$false})

$FormLabel4 = New-Object System.Windows.Forms.Label
$FormLabel4.Text = ""
$FormLabel4.Location = New-Object System.Drawing.Point(10,480)
$FormLabel4.AutoSize = $true

$window_form.Controls.Add($FormButton)
$window_form.Controls.Add($FormButton2)
$window_form.Controls.Add($ListBox)
$window_form.Controls.Add($FormTextBox1)
$window_form.Controls.Add($FormTextBox2)
$window_form.Controls.Add($FormLabel1)
$window_form.Controls.Add($FormLabel2)
$window_form.Controls.Add($FormLabel3)
$window_form.Controls.Add($FormLabel4)

$window_form.Add_Shown({$FormTextBox1.Select()})
$window_form.Topmost = $true
$window_form.MaximizeBox = $false

$result = $window_form.ShowDialog()

We have created a form, fill it with your login, make a password field with asterisks and fill it with a list of PCs

# Прописываем ваш домен и имя пользователя
$FormTextBox1.text = "$Env:UserDomain\$Env:UserName"

# Поле пароля делаем скрытым
$FormTextBox2.PasswordChar="*"

# Заполняем свой OU и домен
$OU = "OU=Computers,DC=domain,DC=local"

# Получаем список ПК и вносим его в поле выбора ПК
$comps = (Get-ADComputer -SearchBase $OU -Filter *).Name | Sort-Object
ForEach ($comp in $comps){
    [void] $listBox.Items.Add($comp)
    }

Now we need to perform an action when clicking on the $FormButton button in which we will have to find the active user session of the remote PC and connect to this session

# Действие на нажатие кнопки
$FormButton.Add_Click({

# Получаем имя выбранного ПК из списка
$ps = $listBox.SelectedItem.ToString()

# Передаем логин и пароль в переменную
$pwsecur = ConvertTo-SecureString -String $FormTextBox2.text -AsPlainText -Force
$cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $FormTextBox1.text, $pwsecur

# Находим все сессии удаленного ПК и ищем активную 
 $active_sessions = quser /server:$ps | foreach {($_ -replace "\s\s+",",")} | ConvertFrom-Csv
    ForEach ($active_session in $active_sessions) {    
        #Не проверял работу на англ версии
        if (($active_session.СТАТУС -eq 'Активно') -or ($active_session.STATUS -eq 'Active')){
            $id = $active_session.ID
            }

# Подключаемся к активной сессии
Start-Process -FilePath "mstsc" -ArgumentList "/v:$ps /shadow:$id /control /noconsentprompt" -Credential $Cred -Wait -WindowStyle Maximized

The script is ready, let's run to check it

We can also add checks:

  1. The password field is filled in

  2. PC selected

  3. Login/password pair (correct or not)

  4. PC Availability

With such checks, the full version of the script will look like this

Hidden text
[Console]::outputEncoding = [System.Text.Encoding]::GetEncoding('cp866')

$OU = "OU=Computers,DC=domain,DC=local"

Add-Type -assembly System.Windows.Forms
$window_form = New-Object System.Windows.Forms.Form
$window_form.Text="Подключение к удаленному рабочему столу"
$window_form.Width = 240
$window_form.Height = 550
$window_form.StartPosition = 'CenterScreen'

$FormLabel1 = New-Object System.Windows.Forms.Label
$FormLabel1.Text = "Введите логин:"
$FormLabel1.Location = New-Object System.Drawing.Point(10,10)
$FormLabel1.AutoSize = $true
$window_form.Controls.Add($FormLabel1)

$FormTextBox1 = New-Object System.Windows.Forms.TextBox
$FormTextBox1.Width = 200
$FormTextBox1.text = "$Env:UserDomain\$Env:UserName"
$FormTextBox1.Location = New-Object System.Drawing.Point(10,25)

$FormLabel2 = New-Object System.Windows.Forms.Label
$FormLabel2.Text = "Введите пароль:"
$FormLabel2.Location = New-Object System.Drawing.Point(10,50)
$FormLabel2.AutoSize = $true

$FormTextBox2 = New-Object System.Windows.Forms.TextBox
$FormTextBox2.Width = 200
$FormTextBox2.text = $NULL
$FormTextBox2.PasswordChar="*"
$FormTextBox2.Location = New-Object System.Drawing.Point(10,65)

$FormLabel3 = New-Object System.Windows.Forms.Label
$FormLabel3.Text = "Выберете компьютер для подключения:"
$FormLabel3.Location = New-Object System.Drawing.Point(10,90)
$FormLabel3.AutoSize = $true

$ListBox = New-Object System.Windows.Forms.ListBox
$ListBox.Width = 200
$ListBox.Height = 300
$ListBox.Location = New-Object System.Drawing.Point(10,105)
$comps = (Get-ADComputer -SearchBase $OU -Filter *).Name | Sort-Object
ForEach ($comp in $comps){
    [void] $listBox.Items.Add($comp)
    }

$FormButton = New-Object System.Windows.Forms.Button
$FormButton.Location = New-Object System.Drawing.Size(10,400)
$FormButton.Size = New-Object System.Drawing.Size(200,30)
$FormButton.Text = "Подключится"
$window_form.AcceptButton = $FormButton
$FormButton.Add_Click({
    $ps = $listBox.SelectedItem.ToString()
    If (($FormTextBox2.text).Length -gt 1){
    If ($ps -ne $NULL){
        Function Test-ADAuthentication {
            param($username,$password)
            (new-object directoryservices.directoryentry "",$username,$password).psbase.name -ne $null
        }
        $testcred = Test-ADAuthentication $FormTextBox1.text $FormTextBox2.text
        If ($testcred -eq 'True'){
        If (Test-Connection $ps -Count 1 -Quiet){
        $FormLabel4.Text = "Подключаемся..."
    $pwsecur = ConvertTo-SecureString -String $FormTextBox2.text -AsPlainText -Force
    $cred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $FormTextBox1.text, $pwsecur
    Invoke-Command –ComputerName $ps -Credential $cred –ScriptBlock {New-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services' -Name 'Shadow' -Value '2' -PropertyType 'DWord'}
    Invoke-Command –ComputerName $ps -Credential $cred –ScriptBlock {New-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services' -Name 'AllowRemoteRPC' -Value '1' -PropertyType 'DWord'}
    $active_sessions = quser /server:$ps | foreach {($_ -replace "\s\s+",",")} | ConvertFrom-Csv
    ForEach ($active_session in $active_sessions) {    
        #вот тут не знаю как будет на анг языке
        if (($active_session.СТАТУС -eq 'Активно') -or ($active_session.STATUS -eq 'Active')){
            $id = $active_session.ID
            }
    }
 Start-Process -FilePath "mstsc" -ArgumentList "/v:$ps /shadow:$id /control /noconsentprompt" -Credential $Cred -Wait -WindowStyle Maximized

}else {
    $FormLabel4.Text = "КОМПЬЮТЕР НЕ ДОСТУПЕН!"
}
 }else {
    $FormLabel4.Text = "ЛОГИН ИЛИ ПАРОЛЬ НЕ ВЕРНЫЕ!"
}
 }else {
    $FormLabel4.Text = "ВЫ НЕ ВЫБРАЛИ КОМПЬЮТЕР!"
}
 }else {
    $FormLabel4.Text = "ВЫ НЕ ВВЕЛИ ПАРОЛЬ!"
}
 })

$FormButton2 = New-Object System.Windows.Forms.Button
$FormButton2.Location = New-Object System.Drawing.Size(10,440)
$FormButton2.Size = New-Object System.Drawing.Size(200,30)
$FormButton2.Text = "Закрыть"
$window_form.CancelButton = $FormButton3
$FormButton2.Add_Click({$window_form.Close();$window_form.Visible=$false})

$FormLabel4 = New-Object System.Windows.Forms.Label
$FormLabel4.Text = ""
$FormLabel4.Location = New-Object System.Drawing.Point(10,480)
$FormLabel4.AutoSize = $true

$window_form.Controls.Add($FormButton)
$window_form.Controls.Add($FormButton2)
$window_form.Controls.Add($ListBox)
$window_form.Controls.Add($FormTextBox1)
$window_form.Controls.Add($FormTextBox2)
$window_form.Controls.Add($FormLabel1)
$window_form.Controls.Add($FormLabel2)
$window_form.Controls.Add($FormLabel3)
$window_form.Controls.Add($FormLabel4)

$window_form.Add_Shown({$FormTextBox1.Select()})
$window_form.Topmost = $true
$window_form.MaximizeBox = $false

$result = $window_form.ShowDialog()

Powershell is very good, but running it is terribly inconvenient. There is a great opportunity convert the resulting script in an exe file

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *