Visualizzazione post con etichetta NET SESSION. Mostra tutti i post
Visualizzazione post con etichetta NET SESSION. Mostra tutti i post

venerdì 25 luglio 2025

Windows: Limite massimo di connessioni simultanee in Windows 10 e 11

Sia Windows 10 che Windows 11, indipendentemente dall'edizione specifica (Home, Pro, Enterprise), supportano un massimo di 20 sessioni in entrata simultanee. Questo significa che, se un computer con Windows 10/11 viene impiegato come server di file o di stampa "rudimentale", gli utenti esterni potrebbero riscontrare un errore nel tentativo di connessione una volta superato questo limite. Il messaggio d'errore tipico è eloquente: "Impossibile effettuare altre connessioni al computer remoto adesso perché è stato superato il numero massimo di connessioni che il computer può accettare."

Questa limitazione è esplicitamente indicata nel Contratto di Licenza per l'Utente Finale (EULA) di Windows. Il EULA specifica che un massimo di 20 dispositivi possono accedere da remoto al software installato sul dispositivo con licenza, esclusivamente per l'utilizzo di funzionalità specifiche quali servizi file, servizi di stampa, servizi di informazione Internet, condivisione della connessione Internet e servizi di telefonia. È interessante notare come il contratto permetta un numero illimitato di dispositivi per la sincronizzazione dei dati, evidenziando la chiara distinzione tra l'uso desktop e quello server.

La ragione di queste restrizioni è chiara: Microsoft mira a orientare gli utenti verso le edizioni server di Windows per scenari di utilizzo che richiedono capacità di rete superiori, incoraggiando l'acquisto di licenze Windows Server o, in alternativa, l'adozione di soluzioni open-source come Samba.


Verifica e gestione dei Limiti di Connessione

Per verificare il limite corrente delle sessioni in entrata su un sistema Windows 10/11, è possibile utilizzare il comando 
net config server
nel Prompt dei comandi. L'output mostrerà il parametro "N. massimo di utenti con accesso" (Maximum Logged On Users), che per le edizioni desktop sarà invariabilmente 20. In contrasto, le edizioni Windows Server offrono limiti significativamente più elevati, ad esempio 16.777.216 per le connessioni SMB.

Un altro parametro importante da considerare è il "Tempo di inattività sessione (min)" (Idle session time (min))
. Per impostazione predefinita, Windows disconnette una sessione inattiva dopo 15 minuti.
Ridurre questo valore, ad esempio a 5 minuti utilizzando il comando 
net config server /autodisconnect:5
può contribuire a liberare sessioni inattive più rapidamente, rendendo disponibili nuove connessioni.
Limite connessioni simultanee
FIG 1 - Limite connessioni simultanee



Intervento Manuale e Automazione per la Gestione delle Sessioni

Quando il numero massimo di connessioni viene raggiunto, è possibile intervenire manualmente per disconnettere alcune sessioni. 

Metodo 1 - Utilizzando Gestione computer
Avviare Gestione computer (compmgmt.msc). Navigare su Utilità di sistema->Cartelle condivise->Sessioni per visualizzare tutte le connessioni di rete attive al computer. 
Per eliminare una connessione basta cliccarci su con il tasto destro del mouse e selezionare Chiudi sessione.
Gestione computer, Sessioni attive
FIG 2 - Gestione computer, Sessioni attive



Metodo 2 - Utilizzando il Prompt dei comandi
Il comando 
net session
elenca tutte le connessioni di rete attive al computer. 
Per disconnettere una sessione specifica, si può utilizzare 
net session \\<indirizzo_IP_o_hostname> /d
Per reimpostare tutte le connessioni attive, il comando è 
net session /delete
Prompt dei comandi, Net Session
FIG 3 - Prompt dei comandi, Net Session



Metodo 3 - Utilizzando PowerShell
Per un approccio più proattivo e automatizzato, è possibile sfruttare PowerShell. Di seguito è riportato un esempio di script PowerShell che, al raggiungimento di 19 connessioni concorrenti (lasciando un piccolo buffer prima del limite massimo), identifica e disconnette le due sessioni più inattive. Questo script può essere adattato per implementare logiche di disconnessione più complesse basate su specifiche esigenze.

# Definizione del numero di sessioni più vecchie da terminare quando si raggiunge il limite.
$sessionsToKillCount = 2

# Definisce la soglia di connessioni a partire dalla quale lo script agirà.
$connectionThreshold = 19

# Recupera le sessioni di rete attive.
$netSessionOutput = net session 2>$null | Select-String -Pattern '\\'

# Calcola il numero attuale di connessioni analizzando le righe filtrate.
$currentConnections = ($netSessionOutput | Measure-Object -Line).Lines

# Controlla se il numero di connessioni attuali supera la soglia definita.
if ($currentConnections -ge $connectionThreshold) {
    Write-Host "Raggiunta la soglia di $connectionThreshold connessioni ($currentConnections attuali). Procedo alla disconnessione delle sessioni inattive." -ForegroundColor Yellow

    # Inizializza un array vuoto per contenere gli oggetti sessione parsati.
    $parsedSessions = @()

    # Itera su ogni riga di output di 'net session' per estrarre i dettagli della sessione.
    foreach ($line in $netSessionOutput) {
        # Suddivide la riga in parti utilizzando uno o più spazi come delimitatore,
        # limitando lo split a 4 parti per gestire correttamente i nomi utente/computer con spazi.
        $parts = $line -split '\s+', 4

        # Verifica che ci siano abbastanza parti per evitare errori se il formato della riga è inatteso.
        if ($parts.Count -ge 4) {
            # Crea un oggetto personalizzato (PSObject) per ogni sessione.
            $sessionObject = [PSCustomObject]@{
                Computer = $parts[0].Trim();       # Il nome del computer o IP remoto
                Username = $parts[1].Trim();       # Il nome utente della sessione
                Opens    = [int]$parts[2].Trim();  # Il numero di file/risorse aperte (convertito a int)
                IdleTime = $parts[3].Trim();       # Il tempo di inattività della sessione (stringa da parsare)
            }
            $parsedSessions += $sessionObject
        } else {
            Write-Warning "Skipping malformed line: '$line'"
        }
    }

    # Ordina le sessioni per tempo di inattività in ordine decrescente (le più inattive per prime).
    $oldestSessions = $parsedSessions | Sort-Object -Property IdleTime -Descending | Select-Object -First $sessionsToKillCount

    # Itera sulle sessioni più vecchie identificate e disconnettile.
    foreach ($sessionToDisconnect in $oldestSessions) {
        Write-Host "Disconnessione della sessione da $($sessionToDisconnect.Computer) (Utente: $($sessionToDisconnect.Username), Inattività: $($sessionToDisconnect.IdleTime))." -ForegroundColor Cyan
        # Disconnette la sessione
        net session "$($sessionToDisconnect.Computer)" /d /y
        # Aggiungiamo un piccolo ritardo per evitare di sovraccaricare il sistema o che i comandi si accavallino.
        Start-Sleep -Milliseconds 200
    }

    Write-Host "Disconnessione delle sessioni completata." -ForegroundColor Green
} else {
    Write-Host "Numero di connessioni attuali ($currentConnections) inferiore alla soglia di $connectionThreshold. Nessuna azione richiesta." -ForegroundColor Green
}


Questo script può essere schedulato tramite l'
Utilità di Pianificazione di Windows (Task Scheduler) per essere eseguito a intervalli regolari (ad esempio, ogni 5 o 10 minuti), garantendo che le sessioni inattive vengano rimosse automaticamente, liberando risorse preziose.


Considerazioni Legali e Tecniche

È importante sottolineare che, sebbene in passato siano esistite patch per il file 'tcpip.sys' che permettevano di aggirare il limite di sessioni nelle edizioni desktop di Windows (similmente alla libreria RDP Wrapper per Remote Desktop), tali soluzioni non sono state osservate per Windows 10 e 11. In ogni caso, l'utilizzo di tali modifiche costituisce una violazione diretta del Contratto di Licenza per l'Utente Finale di Microsoft, esponendo l'organizzazione a rischi legali e di sicurezza.
In conclusione, la gestione dei limiti di connessioni concorrenti in Windows 10 e 11 è una best practice essenziale per gli ambienti IT che utilizzano queste piattaforme in ruoli multi-utente. Comprendere le restrizioni, monitorare le sessioni e implementare soluzioni di automazione, come gli script PowerShell, permette di mitigare l'impatto di questi limiti, garantendo un'esperienza utente fluida e prevenendo interruzioni inaspettate. Per scenari che richiedono un'elevata capacità di connessione o funzionalità server complete, l'investimento in un sistema operativo server dedicato rimane la soluzione più robusta e conforme alle licenze.




giovedì 28 luglio 2016

Programmazione Batch: Verificare se lo script è stato eseguito come Amministratore (privilegi elevati)

In alcuni casi può essere utile verificare se lo script batch da noi realizzato è stato eseguito come amministratore (con privilegi elevati). Un modo veloce per effettuare la verifica all'interno dello script è attraverso una particolare variabile d'ambiente: %errorlevel%. Questa variabile contiene un valore relativo all'esito di gran parte dei comandi/programmi: quando un comando viene portato a termine correttamente il valore di %errorlevel% sarà uguale a 0.

Alcuni comandi, come openfiles, NET SESSION, ecc. richiedono privilegi elevati per essere eseguiti e questo li rende adatti al nostro scopo infatti, tentando di eseguire questi comandi normalmente (senza privilegi elevati), verranno terminati con errore e alla variabile %errorlevel% verrà assegnato un valore diverso da 0 (FIG 1).


Variabile d'ambiente %errorlevel%
FIG 1 - Variabile d'ambiente %errorlevel%


Nello script batch che è possibile scaricare dal link DOWNLOAD la verifica viene effettuata proprio con il comando openfiles. L'output del comando viene scartato dirottandolo su NUL (>nul 2>&1) e viene verificata la variabile d'ambiente %errorlevel%: se la variabile ha valore 0 allora il nostro script è stato eseguito con privilegi elevati e possiamo proseguire con le altre istruzioni, in caso contrario lo script termina senza eseguire altre operazioni. Le istruzioni principali del nostro script sono dunque le seguenti:


openfiles>nul 2>&1
if %errorlevel%==0 goto AdminOK