Работая в компании IT-аутсорса в качестве руководителя 3 линии поддержки, задумался, как автоматизировать подключение сотрудников по RDP, через VPN к серверам десятков клиентов.
Таблички с адресами, паролями и прочими настройками серверов, конечно, хорошо, но поиск клиента и вбивание адресов с аккаунтами занимает довольно существенное время.
Держать все подключения к VPN в Windows не самая лучшая идея, да и при переустановке оного, создавать VPNы тоже не доставляет удовольствие.
Плюс к тому, в большинстве случаев, требуется установить VPN подключение к клиенту без использования шлюза. дабы не гонять весь интернет-трафик через клиента.
Задача, к тому же, осложняется тем, что у некоторых клиентов pptp, у кого-то l2tp, у некоторых несколько подсетей, туннели и т.п.
В результате, для начала был написан скрипты на Powershell для каждого клиента, но позже, узнав, что в Powershell можно использовать Winforms они переродились в некое приложение, написанное с помощью того же Powershell.
До написания этого скрипта-приложения программированием не занимался вообще, разве что лет 20 назад что-то пописывал на VBS в MS Excel и MS Access, поэтому не гарантирую красивость кода и принимаю критику от опытных программистов, как можно было бы сделать красивее.
В Powershell, начиная с Windows 8 и, конечно в Windows 10, появилась прекрасная возможность создавать VPN подключения командой Add-VpnConnection и указывать какие маршруты использовать с этими соединениями командой Add-VpnConnectionRoute, для использования VPN без шлюза.
На основании этих команд и создано данное приложение. Но, обо всем по порядку.
Для начала, создаем в Google Disk таблицу с именованными столбцами:
Number; Name; VPNname; ServerAddress; RemoteNetwork; VPNLogin; VPNPass; VPNType; l2tpPsk; RDPcomp; RDPuser; RDPpass; DefaultGateway; PortWinbox; WinboxLogin; WinboxPwd; Link; Inform

-
VPNname – произвольное имя для VPN соединения
-
ServerAddress – адрес VPN сервера
-
RemoteNetwork – адреса подсети или подсетей клиента, разделенные «;»
-
VPNLogin; VPNPass – учетная запись VPN
-
VPNType -тип VPN (пока используется pptp или l2tp)
-
l2tpPsk – PSK для l2tp, в случае pptp оставляем пустым
-
RDPcomp – адрес сервера RPD
-
RDPuser; RDPpass – учетная запись RPD
-
DefaultGateway принимает значение TRUE или FALSE и указывает на то, использовать ли «Шлюз по умолчанию» для этого соединения. В 90% случаев = FALSE
-
PortWinbox; WinboxLogin; WinboxPwd – порт, логин и пароль для Winbox, поскольку у нас большинство клиентов использует Mikrotik)
-
Link – ссылка на расширенную информацию о компании, например, на диске Google, или в любом другом месте, будет выводиться в информационном поле для быстрого доступа к нужной информации
Inform – примечание
Пример таблицы доступен по ссылке
|
Number |
Name |
VPNname |
ServerAddress |
RemoteNetwork |
VPNLogin |
VPNPass |
VPNType |
l2tpPsk |
RDPcomp |
RDPuser |
RDPpass |
DefaultGateway |
PortWinbox |
WinboxLogin |
WinboxPwd |
Link |
Inform |
|
1 |
Тест1 |
Test1 |
a.b.c.d |
192.168.10.0/24: 10.10.0.0/24 |
vpnuser |
passWord |
pptp |
none |
192.168.10.1 |
user |
passWord |
TRUE |
8291 |
Admin |
Admin |
тест |
|
|
2 |
Тест2 |
Test2 |
e.f.j.k |
192.168.2.0/24 |
vpnuser |
passWord |
l2tp |
KdoSDtdP |
192.168.2.1 |
user |
passWord |
FALSE |
8291 |
Admin |
Admin |
Скриншот работающего приложения с затертыми данными:

Далее следует листинг приложения с комментариями и пояснениями. Если интересно, но непонятно, задавайте вопросы, постараюсь прокомментировать
function Get-Clients #Функция принимает строку адреса файла в Google Drive и возвращает в виде массива данных о клиентах { param ( [string]$google_url = "" ) [string]$xlsFile = $google_url $csvFile = "$env:temp\clients.csv" $Comma = ',' Invoke-WebRequest $xlsFile -OutFile $csvFile $clients = Import-Csv -Delimiter $Comma -Path "$env:temp\clients.csv" Remove-Item -Path $csvFile return $clients } function Main { <# Функция, срабатываемая при запуске скрипта #> Param ([String]$Commandline) #Иннициализируем переменные и присваиваем начальные значения. Здесь же, указываем путь к таблице с клиентами $Global:Clients = $null $Global:Current $Global:CurrentRDPcomp $Global:google_file = "https://docs.google.com/spreadsheets/d/1O-W1YCM4x3o5W1w6XahCJZpkTWs8cREXVF69gs1dD0U/export?format=csv" # Таблица скачивается сразу в виде csv-файла $Global:Clients = Get-Clients ($Global:google_file) # Присваиваем значения из таблицы массиву #Скачиваем Winbox64 во временную папку $download_url = "https://download.mikrotik.com/winbox/3.27/winbox64.exe" $Global:local_path = "$env:temp\winbox64.exe" If ((Test-Path $Global:local_path) -ne $true) { $WebClient = New-Object System.Net.WebClient $WebClient.DownloadFile($download_url, $Global:local_path) } #Разрываем все текущие VPN соединения (на всякий случай) foreach ($item in get-vpnconnection | where { $_.ConnectionStatus -eq "Connected" }) { Rasdial $item.Name /disconnect } #Удаляем все, ранее созданные программой временные соединения, если вдруг не удалились при некорректном закрытии приложения get-vpnconnection | where { $_.Name -match "tmp" } | Remove-VpnConnection -Force #Запускаем приложение Show-MainForm_psf } #Собственно, само приложение function Show-MainForm_psf { [void][reflection.assembly]::Load('System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089') [void][reflection.assembly]::Load('System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a') #Создаем форму и объекты формы [System.Windows.Forms.Application]::EnableVisualStyles() $formКлиентыАльбус = New-Object 'System.Windows.Forms.Form' $statusbar1 = New-Object 'System.Windows.Forms.StatusBar' $groupboxTools = New-Object 'System.Windows.Forms.GroupBox' $buttonPing = New-Object 'System.Windows.Forms.Button' $buttonВыход = New-Object 'System.Windows.Forms.Button' $buttonWindox = New-Object 'System.Windows.Forms.Button' $buttonПеречитатьДанные = New-Object 'System.Windows.Forms.Button' $buttonPingAll = New-Object 'System.Windows.Forms.Button' $groupboxRDP = New-Object 'System.Windows.Forms.GroupBox' $comboboxRDP = New-Object 'System.Windows.Forms.ComboBox' $textboxRDPLogin = New-Object 'System.Windows.Forms.TextBox' $textboxRdpPwd = New-Object 'System.Windows.Forms.TextBox' $buttonПодключитьRDP = New-Object 'System.Windows.Forms.Button' $groupboxVPN = New-Object 'System.Windows.Forms.GroupBox' $buttonПодключитьVPN = New-Object 'System.Windows.Forms.Button' $buttonОтключитьVPN = New-Object 'System.Windows.Forms.Button' $checkboxШлюзПоумолчанию = New-Object 'System.Windows.Forms.CheckBox' $richtextboxinfo = New-Object 'System.Windows.Forms.RichTextBox' $listbox_clients = New-Object 'System.Windows.Forms.ListBox' $InitialFormWindowState = New-Object 'System.Windows.Forms.FormWindowState' #---------------------------------------------- # Обработчики событий #---------------------------------------------- $formКлиентыАльбус_Load = { #При загрузке формы очистить поле информации и заполнить поле с клиентами (их названиями) $richtextboxinfo.Clear() $Global:Clients | ForEach-Object { [void]$listbox_clients.Items.Add($_.Name) } # В листбокс добавляем всех наших клиентов по именам и массива при загрузке формы } $listbox_clients_SelectedIndexChanged = { #Прочитать из массива информацию о клиенте при выборе его в поле listbox_clients (массив, как мы помним считан из файла с диска Google) $statusbar1.Text = 'Выбран клиент: ' + $listbox_clients.SelectedItem.ToString() # Пишем клиента в статусбар $Global:Current = $Global:Clients.Where({ $_.Name -eq $listbox_clients.SelectedItem.ToString() }) If ($Current.PortWinbox -ne 0) # Если порт Winbox указан, то у клиента Mikrotik, включаем соответствующую кнопку { $buttonWindox.Enabled = $true $buttonWindox.Text = "Winbox" } $VPNname = $Global:Current.VPNname + "-tmp" #Добавляем к имени VPN соединения "-tmp" для указания метки временного соединения, чтобы при выходе удалить только их switch ($Global:Current.VPNType) #В зависимости от типа VPN пишем на кнопке "Подключить pptp VPN" или "Подключить l2tp VPN", если у клиента нет VPN, то пишем "Здесь нет VPN" { "pptp" { $buttonПодключитьVPN.Enabled = $true $buttonПодключитьVPN.Text = "Подключить pptp VPN" } "l2tp" { $buttonПодключитьVPN.Enabled = $true $buttonПодключитьVPN.Text = "Подключить l2tp VPN" } DEFAULT { $buttonПодключитьVPN.Enabled = $false $buttonПодключитьVPN.Text = "Здесь нет VPN" } } switch ($Global:Current.DefaultGateway) #Смотрим в массиве, используется ли у клиента "Шлюз по-умолчанию" и заполняем соответствующий чекбокс { "FALSE" { $checkboxШлюзПоумолчанию.Checked = $false } "Нет" { $checkboxШлюзПоумолчанию.Checked = $false } "TRUE" { $checkboxШлюзПоумолчанию.Checked = $true } "Да" { $checkboxШлюзПоумолчанию.Checked = $true } DEFAULT { $checkboxШлюзПоумолчанию.Checked = $false } } $VPNStatus = (ipconfig | Select-String $VPNname -Quiet) #Проверяем, не установлено ли уже это VPN соединение? If ($VPNStatus) #Если установлено, то разблокируем кнопку "Подключить RDP" { $buttonПодключитьRDP.Enabled = $true } else { $buttonПодключитьRDP.Enabled = $false } $richtextboxinfo.Clear() #Очищаем информационное поле # И заполняем информацией о клиенте из массива $richtextboxinfo.SelectionColor = 'Black' $richtextboxinfo.Text = "Клиент: " + $Global:Current.Name + [System.Environment]::NewLine + ` "Имя VPN: " + $Global:Current.VPNname + [System.Environment]::NewLine + ` "Тип VPN: " + $Global:Current.VPNType + [System.Environment]::NewLine + ` "Адрес сервера: " + $Global:Current.ServerAddress + [System.Environment]::NewLine + ` "Подсеть клиента: " + $Global:Current.RemoteNetwork + [System.Environment]::NewLine + ` "Адрес сервера RDP: " + $Global:Current.RDPcomp + [System.Environment]::NewLine + [System.Environment]::NewLine + ` "DefaultGateway: " + $Global:Current.DefaultGateway + [System.Environment]::NewLine + [System.Environment]::NewLine + ` "Примечание: " + [System.Environment]::NewLine + $Global:Current.Inform + [System.Environment]::NewLine + ` "Connection '" + $VPNname + "' status is " + $buttonПодключитьRDP.Enabled + [System.Environment]::NewLine $richtextboxinfo.AppendText($Global:Current.Link) $RDPServers = $Global:Current.RDPcomp.Split(';') -replace '\s', '' #Считываем и разбираем RDP серверы клиента из строки с разделителем в массив #Добавляем из в выпадающее поле выбора сервера $comboboxRDP.Items.Clear() $comboboxRDP.Text = $RDPServers[0] foreach ($RDPServer in $RDPServers) { $comboboxRDP.Items.Add($RDPServer) } #Заполняем поля имени и пароля RDP по умолчанию из таблицы о клиенте (при желании, их можно поменять в окне программы) $textboxRdpPwd.Text = $Global:Current.RDPpass $textboxRdpLogin.Text = $Global:Current.RDPuser } # Форма заполнена, при смене выбранного клиента произойдет перезаполнение полей в соответствии с выбранным клиентом $buttonWindox_Click = { #Обработка нажатия кнопки Winbox If ($Global:Current.PortWinbox -ne 0) #Если порт Winbox заполнен, то открываем скачанный ранее Winbox, подставляем туда имя и пароль к нему и запускаем { $runwinbox = "$env:temp\winbox64.exe" $ServerPort = $Global:Current.ServerAddress + ":" + $Global:Current.PortWinbox $ServerLogin = " """ + $Global:Current.WinboxLogin + """" $ServerPass = " """ + $Global:Current.WinboxPwd + """" $Arg = "$ServerPort $ServerLogin $ServerPass " Start-Process -filePath $runwinbox -ArgumentList $Arg } } $buttonПодключитьVPN_Click = { #Обработка нажатия кнопки ПодключитьVPN $VPNname = $Global:Current.VPNname + "-tmp" #Добавляем к имени VPN соединения "-tmp" для указания метки временного соединения, чтобы при выходе удалить только их $richtextboxinfo.Clear() #Очищаем информационное поля для вывода туда информации о процессе подключения $richtextboxinfo.Text = "Клиент: " + $Global:Current.Name + [System.Environment]::NewLine foreach ($item in get-vpnconnection | where { $_.ConnectionStatus -eq "Connected" }) #Разрываем все установленные соединения { $richtextboxinfo.Text = $richtextboxinfo.Text + "Обнаружено активное соединение " + $item.Name + " разрываем его" + [System.Environment]::NewLine Rasdial $item.Name /disconnect } Remove-VpnConnection $VPNname -Force #Удаляем соединение, если ранее оно было создано $RemoteNetworks = $Global:Current.RemoteNetwork.Split(';') -replace '\s', '' #Считываем и разбираем по строкам в массив список подсетей клиента разделенный ; switch ($Global:Current.VPNType) #В зависимости от типа VPNа создаем pptp или l2tp соединение { "pptp" { $richtextboxinfo.Text = $richtextboxinfo.Text + "Создаем pptp подключение " + $VPNname + [System.Environment]::NewLine If ($checkboxШлюзПоумолчанию.Checked -eq $false) #Если не используется "Шлюз по-умолчанию", то создаем VPN соединение без него и прописываем маршруты { $Errcon = (Add-VpnConnection -Name $VPNname -ServerAddress $Global:Current.ServerAddress -TunnelType $Global:Current.VPNType -SplitTunneling -Force -RememberCredential -PassThru) #Здесь происходит создание VPN foreach ($RemoteNetwork in $RemoteNetworks) #Добавляем все подсети клиента к этому VPN { $richtextboxinfo.AppendText('Добавляем маршрут к ' + $RemoteNetwork + [System.Environment]::NewLine) Add-VpnConnectionRoute -ConnectionName $VPNname -DestinationPrefix $RemoteNetwork -PassThru } } else #Если используется "Шлюз по-умолчанию", то создаем VPN соединение с ним и маршруты к клиенту не нужны { $Errcon = (Add-VpnConnection -Name $VPNname -ServerAddress $Global:Current.ServerAddress -TunnelType $Global:Current.VPNType -Force -RememberCredential -PassThru) } } "l2tp" { $richtextboxinfo.Text = $richtextboxinfo.Text + "Создаем l2tp подключение " + $Global:Current.VPNname + [System.Environment]::NewLine If ($checkboxШлюзПоумолчанию.Checked -eq $false) #Если не используется "Шлюз по-умолчанию", то создаем VPN соединение без него и прописываем маршруты { $Errcon = (Add-VpnConnection -Name $VPNname -ServerAddress $Global:Current.ServerAddress -TunnelType $Global:Current.VPNType -L2tpPsk $Global:Current.l2tpPsk -SplitTunneling -Force -RememberCredential -PassThru) #Здесь происходит создание VPN foreach ($RemoteNetwork in $RemoteNetworks) #Добавляем все подсети клиента к этому VPN { $richtextboxinfo.AppendText('Добавляем маршрут к ' + $RemoteNetwork + [System.Environment]::NewLine) Add-VpnConnectionRoute -ConnectionName $VPNname -DestinationPrefix $RemoteNetwork -PassThru } } else #Если используется "Шлюз по-умолчанию", то создаем VPN соединение с ним и маршруты к клиенту не нужны { $Errcon = (Add-VpnConnection -Name $VPNname -ServerAddress $Global:Current.ServerAddress -TunnelType $Global:Current.VPNType -L2tpPsk $Global:Current.l2tpPsk -Force -RememberCredential -PassThru) } } } $richtextboxinfo.AppendText("Устанавливаем " + $Global:Current.VPNType + " подключение к " + $VPNname + [System.Environment]::NewLine) $Errcon = Rasdial $VPNname $Global:Current.VPNLogin $Global:Current.VPNPass #Устанавливаем созданное VPN подключение и выводим информацию в поле $richtextboxinfo.Text = $richtextboxinfo.Text + [System.Environment]::NewLine + $Errcon + [System.Environment]::NewLine If ((ipconfig | Select-String $VPNname -Quiet)) #Проверяем успешность соединения и, если все удачно, разблокируем кнопку RDP и кнопку "Отключить VPN" { $buttonПодключитьRDP.Enabled = $true $buttonОтключитьVPN.Visible = $true $buttonОтключитьVPN.Enabled = $true $statusbar1.Text = $Global:Current.Name + ' подключен' } } $formКлиентыАльбус_FormClosing = [System.Windows.Forms.FormClosingEventHandler]{ #При закрытии формы подчищаем за собой. Разрываем и удаляем все созданные соединения. foreach ($item in get-vpnconnection | where { $_.ConnectionStatus -eq "Connected" }) { $richtextboxinfo.Text = $richtextboxinfo.Text + "Обнаружено активное соединение " + $item.Name + " разрываем его" + [System.Environment]::NewLine Rasdial $item.Name /disconnect } $richtextboxinfo.Text = $richtextboxinfo.Text + "Удаляем все временные соединения" + [System.Environment]::NewLine get-vpnconnection | where { $_.Name -match "tmp" } | Remove-VpnConnection -Force #Удаляем информацию о RPD-серверах из реестра $Global:Clients | ForEach-Object { $term = "TERMSRV/" + $_.RDPcomp cmdkey /delete:$term } } $buttonПодключитьRDP_Click = { #Обработка кнопки ПодключитьRDP $RDPcomp = $comboboxRDP.Text $RDPuser = $textboxRDPLogin.Text $RDPpass = $textboxRdpPwd.Text cmdkey /generic:"TERMSRV/$RDPcomp" /user:"$RDPuser" /pass:"$RDPpass" mstsc /v:$RDPcomp } $buttonОтключитьVPN_Click = { #При отключении VPN подчищаем за собой и оповещаем о процессе в поле информации foreach ($item in get-vpnconnection | where { $_.ConnectionStatus -eq "Connected" }) { $richtextboxinfo.Text = $richtextboxinfo.Text + "Обнаружено активное соединение " + $item.Name + " разрываем его" + [System.Environment]::NewLine Rasdial $item.Name /disconnect } $richtextboxinfo.Text = $richtextboxinfo.Text + "Удаляем все временные соединения" + [System.Environment]::NewLine get-vpnconnection | where { $_.Name -match "tmp" } | Remove-VpnConnection -Force $buttonОтключитьVPN.Visible = $false $buttonПодключитьRDP.Enabled = $false $statusbar1.Text = $Global:Current.Name + ' отключен' } $buttonPingAll_Click={ #Пингуем всех клиентов и оповещаем о результатах $I=0 $richtextboxinfo.Clear() $richtextboxinfo.SelectionColor = 'Black' $clientscount = $Global:Clients.count $Global:Clients | ForEach-Object { if ((test-connection -Count 1 -computer $_.ServerAddress -quiet) -eq $True) { $richtextboxinfo.SelectionColor = 'Green' $richtextboxinfo.AppendText($_.Name +' ('+ $_.ServerAddress +') доступен' + [System.Environment]::NewLine) } else { $richtextboxinfo.SelectionColor = 'Red' $richtextboxinfo.AppendText($_.Name + ' (' + $_.ServerAddress + ') недоступен (или закрыт ICMP)' + [System.Environment]::NewLine) } $richtextboxinfo.ScrollToCaret() $I = $I + 1 Write-Progress -Activity "Ping in Progress" -Status "$i clients of $clientscount pinged" -PercentComplete ($i/$clientscount*100) } $richtextboxinfo.SelectionColor = 'Black' Write-Progress -Activity "Ping in Progress" -Status "Ready" -Completed } $buttonПеречитатьДанные_Click={ #Перечитываем данные из таблицы Google $Global:Clients = Get-Clients ($Global:google_file) $listbox_clients.Items.Clear() $Global:Clients | ForEach-Object { [void]$listbox_clients.Items.Add($_.Name) } } $buttonВыход_Click = { #Выход $formКлиентыАльбус.Close() } $richtextboxinfo_LinkClicked=[System.Windows.Forms.LinkClickedEventHandler]{ #Обработка нажатия на ссылку в окне информации Start-Process $_.LinkText.ToString() } $buttonPing_Click={ #Пингуем ip текущего клиента и выводим результат в поле информации if ((test-connection -Count 1 -computer $Global:Current.ServerAddress -quiet) -eq $True) { $richtextboxinfo.AppendText([System.Environment]::NewLine) $richtextboxinfo.SelectionColor = 'Green' $richtextboxinfo.AppendText($Global:Current.Name + ' (' + $Global:Current.ServerAddress + ') доступен' + [System.Environment]::NewLine) } else { $richtextboxinfo.AppendText([System.Environment]::NewLine) $richtextboxinfo.SelectionColor = 'Red' $richtextboxinfo.AppendText($Global:Current.Name + ' (' + $Global:Current.ServerAddress + ') недоступен (или закрыт ICMP)' + [System.Environment]::NewLine) } } #---------------------------------------------- #Описание объектов формы #---------------------------------------------- # # formКлиентыАльбус # $formКлиентыАльбус.Controls.Add($statusbar1) $formКлиентыАльбус.Controls.Add($groupboxTools) $formКлиентыАльбус.Controls.Add($groupboxRDP) $formКлиентыАльбус.Controls.Add($groupboxVPN) $formКлиентыАльбус.Controls.Add($richtextboxinfo) $formКлиентыАльбус.Controls.Add($listbox_clients) $formКлиентыАльбус.AutoScaleDimensions = '6, 13' $formКлиентыАльбус.AutoScaleMode = 'Font' $formКлиентыАльбус.AutoSize = $True $formКлиентыАльбус.ClientSize = '763, 446' $formКлиентыАльбус.FormBorderStyle = 'FixedSingle' $formКлиентыАльбус.MaximizeBox = $False $formКлиентыАльбус.Name = 'formКлиентыАльбус' $formКлиентыАльбус.SizeGripStyle = 'Hide' $formКлиентыАльбус.StartPosition = 'CenterScreen' $formКлиентыАльбус.Text = 'Клиенты Альбус' $formКлиентыАльбус.add_FormClosing($formКлиентыАльбус_FormClosing) $formКлиентыАльбус.add_Load($formКлиентыАльбус_Load) # # statusbar1 # $statusbar1.Location = '0, 424' $statusbar1.Name = 'statusbar1' $statusbar1.Size = '763, 22' $statusbar1.TabIndex = 17 # # groupboxTools # $groupboxTools.Controls.Add($buttonPing) $groupboxTools.Controls.Add($buttonВыход) $groupboxTools.Controls.Add($buttonWindox) $groupboxTools.Controls.Add($buttonПеречитатьДанные) $groupboxTools.Controls.Add($buttonPingAll) $groupboxTools.Location = '308, 258' $groupboxTools.Name = 'groupboxTools' $groupboxTools.Size = '147, 163' $groupboxTools.TabIndex = 10 $groupboxTools.TabStop = $False $groupboxTools.Text = 'Tools' $groupboxTools.UseCompatibleTextRendering = $True # # buttonPing # $buttonPing.Location = '7, 44' $buttonPing.Name = 'buttonPing' $buttonPing.Size = '133, 23' $buttonPing.TabIndex = 12 $buttonPing.Text = 'Ping' $buttonPing.UseCompatibleTextRendering = $True $buttonPing.UseVisualStyleBackColor = $True $buttonPing.add_Click($buttonPing_Click) # # buttonВыход # $buttonВыход.Location = '7, 125' $buttonВыход.Name = 'buttonВыход' $buttonВыход.Size = '133, 23' $buttonВыход.TabIndex = 15 $buttonВыход.Text = 'Выход' $buttonВыход.UseCompatibleTextRendering = $True $buttonВыход.UseVisualStyleBackColor = $True $buttonВыход.add_Click($buttonВыход_Click) # # buttonWindox # $buttonWindox.Enabled = $False $buttonWindox.Location = '7, 17' $buttonWindox.Name = 'buttonWindox' $buttonWindox.Size = '133, 23' $buttonWindox.TabIndex = 11 $buttonWindox.Text = 'Windox' $buttonWindox.UseCompatibleTextRendering = $True $buttonWindox.UseVisualStyleBackColor = $True $buttonWindox.add_Click($buttonWindox_Click) # # buttonПеречитатьДанные # $buttonПеречитатьДанные.Location = '7, 98' $buttonПеречитатьДанные.Name = 'buttonПеречитатьДанные' $buttonПеречитатьДанные.Size = '133, 23' $buttonПеречитатьДанные.TabIndex = 14 $buttonПеречитатьДанные.Text = 'Перечитать данные' $buttonПеречитатьДанные.UseCompatibleTextRendering = $True $buttonПеречитатьДанные.UseVisualStyleBackColor = $True $buttonПеречитатьДанные.add_Click($buttonПеречитатьДанные_Click) # # buttonPingAll # $buttonPingAll.Location = '7, 71' $buttonPingAll.Name = 'buttonPingAll' $buttonPingAll.Size = '133, 23' $buttonPingAll.TabIndex = 13 $buttonPingAll.Text = 'Ping All' $buttonPingAll.UseCompatibleTextRendering = $True $buttonPingAll.UseVisualStyleBackColor = $True $buttonPingAll.add_Click($buttonPingAll_Click) # # groupboxRDP # $groupboxRDP.Controls.Add($comboboxRDP) $groupboxRDP.Controls.Add($textboxRDPLogin) $groupboxRDP.Controls.Add($textboxRdpPwd) $groupboxRDP.Controls.Add($buttonПодключитьRDP) $groupboxRDP.Location = '308, 128' $groupboxRDP.Name = 'groupboxRDP' $groupboxRDP.Size = '147, 126' $groupboxRDP.TabIndex = 5 $groupboxRDP.TabStop = $False $groupboxRDP.Text = 'RDP' $groupboxRDP.UseCompatibleTextRendering = $True # # comboboxRDP # $comboboxRDP.FormattingEnabled = $True $comboboxRDP.Location = '7, 17' $comboboxRDP.Name = 'comboboxRDP' $comboboxRDP.Size = '133, 21' $comboboxRDP.TabIndex = 6 $comboboxRDP.Text = 'IP RDP сервера' # # textboxRDPLogin # $textboxRDPLogin.Location = '7, 44' $textboxRDPLogin.Name = 'textboxRDPLogin' $textboxRDPLogin.Size = '133, 20' $textboxRDPLogin.TabIndex = 7 $textboxRDPLogin.Text = 'RDP-login' # # textboxRdpPwd # $textboxRdpPwd.Location = '7, 69' $textboxRdpPwd.Name = 'textboxRdpPwd' $textboxRdpPwd.PasswordChar = '*' $textboxRdpPwd.Size = '133, 20' $textboxRdpPwd.TabIndex = 8 $textboxRdpPwd.Text = 'RDP-Password' # # buttonПодключитьRDP # $buttonПодключитьRDP.Enabled = $False $buttonПодключитьRDP.Location = '7, 94' $buttonПодключитьRDP.Name = 'buttonПодключитьRDP' $buttonПодключитьRDP.Size = '133, 20' $buttonПодключитьRDP.TabIndex = 9 $buttonПодключитьRDP.Text = 'Подключить RDP' $buttonПодключитьRDP.UseCompatibleTextRendering = $True $buttonПодключитьRDP.UseVisualStyleBackColor = $True $buttonПодключитьRDP.add_Click($buttonПодключитьRDP_Click) # # groupboxVPN # $groupboxVPN.Controls.Add($buttonПодключитьVPN) $groupboxVPN.Controls.Add($buttonОтключитьVPN) $groupboxVPN.Controls.Add($checkboxШлюзПоумолчанию) $groupboxVPN.Location = '308, 27' $groupboxVPN.Name = 'groupboxVPN' $groupboxVPN.Size = '147, 98' $groupboxVPN.TabIndex = 1 $groupboxVPN.TabStop = $False $groupboxVPN.Text = 'VPN' $groupboxVPN.UseCompatibleTextRendering = $True # # buttonПодключитьVPN # $buttonПодключитьVPN.Enabled = $False $buttonПодключитьVPN.Location = '7, 45' $buttonПодключитьVPN.Name = 'buttonПодключитьVPN' $buttonПодключитьVPN.Size = '133, 20' $buttonПодключитьVPN.TabIndex = 3 $buttonПодключитьVPN.Text = 'Подключить VPN' $buttonПодключитьVPN.UseCompatibleTextRendering = $True $buttonПодключитьVPN.UseVisualStyleBackColor = $True $buttonПодключитьVPN.add_Click($buttonПодключитьVPN_Click) # # buttonОтключитьVPN # $buttonОтключитьVPN.Enabled = $False $buttonОтключитьVPN.Location = '7, 67' $buttonОтключитьVPN.Name = 'buttonОтключитьVPN' $buttonОтключитьVPN.Size = '133, 20' $buttonОтключитьVPN.TabIndex = 4 $buttonОтключитьVPN.Text = 'Отключить VPN' $buttonОтключитьVPN.UseCompatibleTextRendering = $True $buttonОтключитьVPN.UseVisualStyleBackColor = $True $buttonОтключитьVPN.Visible = $False $buttonОтключитьVPN.add_Click($buttonОтключитьVPN_Click) # # checkboxШлюзПоумолчанию # $checkboxШлюзПоумолчанию.Location = '7, 19' $checkboxШлюзПоумолчанию.Name = 'checkboxШлюзПоумолчанию' $checkboxШлюзПоумолчанию.Size = '133, 24' $checkboxШлюзПоумолчанию.TabIndex = 2 $checkboxШлюзПоумолчанию.Text = 'Шлюз по-умолчанию' $checkboxШлюзПоумолчанию.TextAlign = 'MiddleRight' $checkboxШлюзПоумолчанию.UseCompatibleTextRendering = $True $checkboxШлюзПоумолчанию.UseVisualStyleBackColor = $True # # richtextboxinfo # $richtextboxinfo.Cursor = 'Default' $richtextboxinfo.ForeColor = 'WindowText' $richtextboxinfo.HideSelection = $False $richtextboxinfo.Location = '461, 27' $richtextboxinfo.Name = 'richtextboxinfo' $richtextboxinfo.ReadOnly = $True $richtextboxinfo.ScrollBars = 'ForcedVertical' $richtextboxinfo.ShowSelectionMargin = $True $richtextboxinfo.Size = '290, 394' $richtextboxinfo.TabIndex = 16 $richtextboxinfo.Text = '' $richtextboxinfo.add_LinkClicked($richtextboxinfo_LinkClicked) # # listbox_clients # $listbox_clients.FormattingEnabled = $True $listbox_clients.Location = '12, 27' $listbox_clients.Name = 'listbox_clients' $listbox_clients.Size = '290, 394' $listbox_clients.TabIndex = 0 $listbox_clients.add_SelectedIndexChanged($listbox_clients_SelectedIndexChanged) #Save the initial state of the form $InitialFormWindowState = $formКлиентыАльбус.WindowState #Init the OnLoad event to correct the initial state of the form $formКлиентыАльбус.add_Load($Form_StateCorrection_Load) #Clean up the control events $formКлиентыАльбус.add_FormClosed($Form_Cleanup_FormClosed) #Store the control values when form is closing $formКлиентыАльбус.add_Closing($Form_StoreValues_Closing) #Show the Form return $formКлиентыАльбус.ShowDialog() } #Запуск приложения! Main ($CommandLine)
Скрипт можно запускать как скрипт ps1 или скомпилировать в exe через ps2exe и использовать как полноценное приложение
ссылка на оригинал статьи https://habr.com/ru/post/563686/
Добавить комментарий