Passaggio all'ora legale 31 marzo 2024 02:00 03:00 sposta avanti l'orologio di 1 ora (si dorme 1 ora in meno)
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:
Manage VPN - Windows FormManage VPN - Windows Form

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
Warning mancanza privilegiWarning mancanza privilegi

Il modo migliore per eseguirlo con elevati privilegi è creare un collegamento o un file bat e impostare il relativo flag:
flag elevati privilegiflag elevati privilegi

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.
Potrebbe interessarti anche: