[Программирование, .NET, PowerShell, Алгоритмы, Разработка под Windows] Powershell настоящий язык программирования. Скрипт оптимизации рутины в техподдержке

Автор Сообщение
news_bot ®

Стаж: 6 лет 9 месяцев
Сообщений: 27286

Создавать темы news_bot ® написал(а)
20-Июн-2021 15:31

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

Похожие новости: Теги для поиска: #_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