Gestire i servizi VPN da una finestra Windows in PowerShell
Ho creato questa piccola utility in PowerShell per gestire lo start e stop delle varie VPN che uso per accedere alle reti dei clienti.
Lo scopo è quello di gestire in un punto unico tutte le VPN in modo da non avere servizi attivi se non servono.
Lo script crea una Windows Form con i pulsanti per avviare o fermare il servizio corrispondente:
Perché funzioni è necessario indicare i servizi VPN gestiti nella variabile $serviceNames:
Il modo migliore per eseguirlo con elevati privilegi è creare un collegamento o un file bat e impostare il relativo flag:
Lo scopo è quello di gestire in un punto unico tutte le VPN in modo da non avere servizi attivi se non servono.
Lo script crea una Windows Form con i pulsanti per avviare o fermare il servizio corrispondente:
Perché funzioni è necessario indicare i servizi VPN gestiti nella variabile $serviceNames:
PowerShell
# https://www.sgart.it
# manage-vpn.ps1: gestione start e stop servizi VPN
#
# cpextender Check Point SSL Network Extender
# FA_Scheduler FortiClient VPN Service Scheduler (non si riesce a stoppare)
# client_service VMware Horizon Client
# vpnagent Cisco AnyConnect Secure Mobility Agent
# wgsslvpnsrc WatchGuard SSLVPN Service
# elenco dei servizi gestiti */
$serviceNames = @("cpextender", "FA_Scheduler", "client_service", "vpnagent", "wgsslvpnsrc", "farlocco")
#--------------------------------------------------------------------------
# verifica run with elevate privilege
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
$isElevate = $currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
#--------------------------------------------------------------------------
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
$buttons = [System.Collections.ArrayList]@()
function setWaiting {
param([boolean]$show)
$lblWaiting.visible = $show
}
function getService {
Get-Service | Where-Object { $_.Name -in $serviceNames }
}
# l'evento Click va gestito come variabile, non come function
$HandleClick = {
param($obj)
setWaiting $true
Write-Host "-BEGIN----------------------------------------"
$name = $obj.tag;
# rileggo i servizi
$services = getService
# fermo tutti i servizi tranne quello selezionato
$services | Where-Object { $_.Status -eq "Running" } | ForEach-Object {
Write-Host " Stopping: $($_.Name) - $($_.DisplayName)"
$_ | Stop-Service
}
if ($name -ne "*") {
# avvio il servizio selezionato
$services | Where-Object { $_.Name -eq $name -and $_.Status -eq "Stopped" } |
ForEach-Object {
Write-Host " Starting: $($_.Name) - $($_.DisplayName)"
$_ | Start-Service
}
}
Write-Host "-END------------------------------------------"
updateButtons
}
function updateButtons {
$services = getService
$buttons | ForEach-Object {
$btn = $_
$name = $btn.Tag
$found = $services | Where-Object { $_.Name -eq $name }
$btn.Enabled = $false
If ($found) {
if ($found.StartType -eq "Disabled") {
$btn.Text = $found.DisplayName + "[Disabled]"
}
else {
$btn.Text = $($found.DisplayName)
$btn.Enabled = $true
if ($found.Status -eq "Running") {
$btn.backcolor = "#CCE0AF"
}
elseif ($found.Status -eq "Stopped") {
$btn.backcolor = "#D9786F"
}
else {
$btn.backcolor = "#F4DBA3"
$btn.Text = "[$($found.Status)] $($found.DisplayName)"
}
}
}
else {
$btn.Text = "[$($btn.Tag)] NOT FOUND"
$btn.backcolor = "#cccccc"
}
}
setWaiting $false
$services
}
function createForm ([int]$width, [int]$height) {
# creo la form
$form = New-Object Windows.Forms.Form -Property @{
StartPosition = [Windows.Forms.FormStartPosition]::CenterScreen
Size = New-Object Drawing.Size $width, $height
Text = "Manage VPN - Sgart.it"
Topmost = $true
MaximizeBox = $false
FormBorderStyle = [Windows.Forms.FormBorderStyle]::FixedSingle
}
$maxPerRow = 2; # numero di bottoni per riga
$buttonGap = 20; # distanza tra i bottoni
$buttonTop = 20; # distanza dal borso uperiore
$buttonLeft = 20 # distanza dal bordo sinistro
$internalWidth = $form.ClientSize.Width -$buttonLeft * 2; # dimensione interna della form
$buttonWidth = ($internalWidth - ($maxPerRow -1) *$buttonGap ) / $maxPerRow; # larghezza di un pulsante
$buttonHeight = 50; #altezza di un pulsante
if ($isElevate) {
# creo il bottone stop all
$okButton = New-Object System.Windows.Forms.Button -Property @{
Location = New-Object System.Drawing.Point $buttonLeft, $buttonTop
Size = New-Object System.Drawing.Size $internalWidth, $buttonHeight
Text = "STOP ALL"
Tag = "*"
}
$okButton.Add_Click($HandleClick)
$form.Controls.Add($okButton)
}
else {
#creo la label di warning
$lblAlert = New-Object System.Windows.Forms.Label -Property @{
Location = New-Object System.Drawing.Point $buttonLeft, $buttonTop
Size = New-Object System.Drawing.Size ($Width - $buttonLeft * 2), $buttonHeight
Text = "Warning, elevate privilege required"
ForeColor = "#ff0000"
BackColor = "#eeee00"
TextAlign = [System.Drawing.ContentAlignment]::MiddleCenter
Font = [System.Drawing.Font]::new("Microsoft Sans Serif", 16.0, [System.Drawing.FontStyle]::Bold)
}
$form.Controls.Add($lblAlert)
}
# label di waiting
$lblWaiting = New-Object System.Windows.Forms.Label -Property @{
Location = New-Object System.Drawing.Point 0, 0
Size = New-Object System.Drawing.Size $width, 20
Text = "Waiting..."
ForeColor = "#ffffff"
BackColor = "#ff0000"
TextAlign = [System.Drawing.ContentAlignment]::MiddleCenter
Visible = $false
}
$form.Controls.Add($lblWaiting)
Set-Variable -Name "lblWaiting" -Value $lblWaiting -Scope global
# creo i bottoni di avvio servizi
$buttonTop = $buttonTop * 2 + $buttonHeight
$px = 0;
$py = 0;
$serviceNames | ForEach-Object {
$name = $_
$x = $buttonLeft + ($buttonWidth + $buttonGap) * $px
$y = $buttonTop + ($buttonHeight + $buttonGap ) * $py
#Write-Host "x: $x, y: $y, $item, px: $px, py: $py, $found $($found.name)"
$btn = New-Object System.Windows.Forms.Button -Property @{
Location = New-Object System.Drawing.Point $x, $y
Size = New-Object System.Drawing.Size $buttonWidth, $buttonHeight
Text = $name + " ..."
Tag = $name
}
if ($isElevate) {
$btn.Add_Click($HandleClick)
}
$form.Controls.Add($btn)
[void]$buttons.Add($btn);
$px++
if ($px -ge $maxPerRow) {
$px = 0;
$py++
}
}
#$form.ShowDialog()
$form
}
$form = createForm 550 400
$r = updateButtons
$form.ShowDialog()
Per poter avviare e fermare i servizi, lo script deve essere eseguito con elevati privilegi
Il modo migliore per eseguirlo con elevati privilegi è creare un collegamento o un file bat e impostare il relativo flag:
Non funziona con tutte le VPN, in quanto per alcune non è sufficiente stoppare il relativo servizo windows ma è necessario agire in altro modo. Ad esempio FortiClient VPN Service Scheduler può essere fermato (shutdown) solo agendo sull'icona nella tray bar.