Powershell настоящий язык программирования. Скрипт оптимизации рутины в техподдержке

от автора

Работая в компании 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

http://yandex.ru

тест

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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *