[Программирование, .NET, PowerShell, Алгоритмы, Разработка под Windows] Powershell настоящий язык программирования. Скрипт оптимизации рутины в техподдержке
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Работая в компании 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 – примечание Пример таблицы доступен по ссылкеNumberNameVPNnameServerAddressRemoteNetworkVPNLoginVPNPassVPNTypel2tpPskRDPcompRDPuserRDPpassDefaultGatewayPortWinboxWinboxLoginWinboxPwdLinkInform1Тест1Test1a.b.c.d192.168.10.0/24: 10.10.0.0/24vpnuserpassWordpptpnone192.168.10.1userpassWordTRUE8291AdminAdminhttp://yandex.ruтест2Тест2Test2e.f.j.k192.168.2.0/24vpnuserpassWordl2tpKdoSDtdP192.168.2.1userpassWordFALSE8291AdminAdminСкриншот работающего приложения с затертыми данными:
Далее следует листинг приложения с комментариями и пояснениями. Если интересно, но непонятно, задавайте вопросы, постараюсь прокомментировать
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 и использовать как полноценное приложение
===========
Источник:
habr.com
===========
Похожие новости:
- [Программирование, Java, Промышленное программирование, Тестирование веб-сервисов] Как подружить Redis Cluster c Testcontainers?
- Обновление OpenVPN 2.5.3. Отключение Opera VPN и VyprVPN в РФ
- [Программирование] Локальное время и дата рождения или зачем UTC
- [Программирование, Венчурные инвестиции, Развитие стартапа, Образование за рубежом, Бизнес-модели] Перевод Курса по стартапам и бизнесу от Стэнфордского Университета. Лекция №2. Команда и реализация стартапа (перевод)
- [Программирование микроконтроллеров] Программируемое реле easyE4
- [Высокая производительность, Тестирование IT-систем, IT-компании] Следствие вели: пропажа FC-линков HBA Emulex на сервере Atos BullSequana S1600
- [Разработка веб-сайтов, Программирование, Haskell, Функциональное программирование] Создаем веб-приложение на Haskell с использованием Reflex. Часть 4
- [Open source, Программирование, Системное программирование, Компиляторы, Rust] Rust 1.53.0: IntoIterator для массивов, "|" в шаблонах, Unicode-идентификаторы, поддержка имени HEAD-ветки в Cargo (перевод)
- [Конференции, Интервью] Реактивное программирование из первых рук
- [Настройка Linux, Информационная безопасность, Сетевые технологии, Разработка под Linux, IT-компании] Cloudflare представила WARP для Linux
Теги для поиска: #_programmirovanie (Программирование), #_.net, #_powershell, #_algoritmy (Алгоритмы), #_razrabotka_pod_windows (Разработка под Windows), #_powershell, #_autsorsing (аутсорсинг), #_avtomatizatsija (автоматизация), #_avtomatizatsija_rutiny (автоматизация рутины), #_vpn, #_winform, #_winforms, #_winbox, #_tehpodderzhka (техподдержка), #_programmirovanie (программирование), #_programmirovanie (
Программирование
), #_.net, #_powershell, #_algoritmy (
Алгоритмы
), #_razrabotka_pod_windows (
Разработка под Windows
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 13:59
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Работая в компании 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
Далее следует листинг приложения с комментариями и пояснениями. Если интересно, но непонятно, задавайте вопросы, постараюсь прокомментировать 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) =========== Источник: habr.com =========== Похожие новости:
Программирование ), #_.net, #_powershell, #_algoritmy ( Алгоритмы ), #_razrabotka_pod_windows ( Разработка под Windows ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 13:59
Часовой пояс: UTC + 5