Visualizzazione post con etichetta Windows. Mostra tutti i post
Visualizzazione post con etichetta Windows. Mostra tutti i post

lunedì 4 agosto 2025

Windows: Risoluzione dell'errore "Impossibile trovare l'assembly a cui fa riferimento" (0x80073701)

Durante l'aggiunta/rimozione di ruoli/funzionalità su Windows Server o sui client Windows 10/11 è possibile imbattersi in un errore specifico: 

La richiesta di aggiungere o rimuovere funzionalita' sul server specificato non e' riuscita. Impossibile installare uno o piu' ruoli, servizi ruolo o funzionalita'.
Impossibile trovare l'assembly a cui fa riferimento. Errore : 0x80073701

Questo messaggio indica che i file sorgente necessari per il componente richiesto sono mancanti o corrotti all'interno dell'immagine di Windows, rendendo impossibile l'operazione.


Controlli preliminari e riavvio del sistema

Prima di procedere con la risoluzione, è fondamentale verificare se ci siano aggiornamenti in attesa di riavvio. La mancata finalizzazione di un aggiornamento può bloccare altre operazioni di sistema.
Aprire un prompt dei comandi con privilegi elevati e digitare:
dism /online /get-packages /format:table | Select-String "Installazione in sospeso"
o nella versione inglese del sistema operativo
dism /online /get-packages /format:table | Select-String "Pending"
Installazione in sospeso
FIG 1 - Installazione in sospeso

Se vengono rilevati pacchetti con lo stato "Installazione in sospeso" (Pending Reboot), riavviare il computer. In alcuni rari casi, un pacchetto potrebbe rimanere in questo stato anche dopo diversi riavvii. In questa eventualità, provare a rinominare il file C:\Windows\Winsxs\Pending.xml in Pending.xml.old e riavviare nuovamente il sistema.
Pending.xml
FIG 2 - Pending.xml



Ripristino dell'integrità dell'immagine di sistema

Una volta verificato che non ci siano riavvii pendenti, il passo successivo è utilizzare lo strumento DISM (Deployment Imaging and Servicing Management) per verificare e riparare l'immagine di Windows.

Eseguire un controllo dell'integrità dell'immagine di sistema con il seguente comando:
DISM /Online /Cleanup-Image /CheckHealth
Se il comando restituisce il messaggio "The component store is repairable" (l'archivio dei componenti è riparabile), procedere con la riparazione.

Per riparare l'immagine, utilizzare il comando RestoreHealth. Questo comando scaricherà i file necessari da Windows Update per ripristinare i componenti danneggiati.
DISM /Online /Cleanup-Image /RestoreHealth

Dopo aver riparato l'archivio dei componenti, eseguire una scansione dei file di sistema per assicurarsi che non ci siano file danneggiati. Lo strumento SFC (System File Checker) utilizzerà l'archivio dei componenti appena riparato come fonte per i file originali.
sfc /scannow
sfc /scannnow
FIG 3 - sfc /scannnow



Analisi del log CBS e intervento manuale

Se le funzionalità di Windows continuano a non installarsi, è necessario esaminare il log di Servicing Stack per identificare la causa specifica dell'errore. Il file di log si trova in %windir%\Logs\CBS\CBS.log.
Cercare nel file di log un errore che indichi file di sistema mancanti relativi a un aggiornamento precedentemente installato. L'errore si presenterà in un formato simile a questo:

CBS Failed to pin deployment while resolving Update: Package_for_KB5012170~31bf3856ad364e35~amd64~~20348.880.1.1 from file: (null) [HRESULT = 0x80073701 – ERROR_SXS_ASSEMBLY_MISSING]

In questo esempio, l'errore è associato all'aggiornamento KB5012170.
Log CBS
FIG 4 - Log CBS



Download e installazione manuale dell'aggiornamento

Il modo più semplice per risolvere questo problema è scaricare manualmente l'aggiornamento specifico dal Catalogo di Microsoft Update e installarlo. Se l'installazione tramite il file .msu non dovesse funzionare, si può estrarre il pacchetto e aggiungerlo all'immagine di Windows:

Per estrarre il pacchetto MSU utilizzare il comando:
expand -f:* windows10.0-kb5012170-x64 c:\temp

Aggiungere  il pacchetto all'immagine di sistema di Windows in esecuzione :
DISM.exe /Online /Add-Package /PackagePath:c:\Temp\Windows10.0-KB5012170-x64.cab


Ignorare i pacchetti danneggiati (Procedura avanzata)

ATTENZIONE: Questo metodo non è supportato ufficialmente da Microsoft e può compromettere l'integrità del sistema. Eseguire un backup completo dell'immagine di Windows o creare un punto di ripristino prima di procedere.

Se l'aggiornamento non è disponibile per il download o non è applicabile, è possibile istruire Windows a ignorare il pacchetto danneggiato modificando il registro di sistema.

  • Aprire l'Editor del Registro di sistema (regedit).
  • Navigare alla chiave
    HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing
  • Impostare il proprio account come proprietario della chiave Component Based Servicing (l'owner predefinito è TrustedInstaller) e imopstare i permessi di controllo completo.
  • Individuare la sottochiave del pacchetto da ignorare (ad es. Package_for_KB5012170).
  • Modificare il valore del parametro CurrentState in 0 (Not present). Il valore precedente potrebbe essere 112 (Installed).
  • Ripristinare i permessi originali sulla chiave di registro, lasciando all'amministratore solo l'accesso in sola lettura.
  • Riavviare il computer e verificare se le funzionalità di Windows possono essere installate.

Per identificare tutti i pacchetti con l'errore ASSEMBLY_MISSING, puoi filtrare il log CBS con il seguente comando PowerShell:
Select-String -Path "c:\windows\logs\cbs\cbs.log" -Pattern "Failed to pin"


Aggiornamento in-place (ultima risorsa)

Se tutte le soluzioni precedenti non hanno successo, l'opzione finale è un aggiornamento in-place del sistema operativo. Questo processo reinstallerà Windows mantenendo i file personali, le impostazioni e le applicazioni.
Scaricare l'immagine ISO più recente della propria versione di Windows.
Montare il file ISO e avviare il programma setup.exe.
Selezionare l'opzione "Mantieni file personali e app" quando richiesto per l'aggiornamento.
Questo metodo può risolvere problemi di integrità complessi che non possono essere corretti con i normali strumenti di riparazione, offrendo una soluzione completa. 






giovedì 31 luglio 2025

Windows : Risolvere l'Errore 0xc1900208 di Windows Update

Gli aggiornamenti di Windows sono cruciali per la sicurezza e la stabilità dei sistemi, ma possono spesso essere interrotti da errori inaspettati. Tra questi, l'errore 0xc1900208 è un problema ricorrente che ha afflitto gli utenti sia con gli aggiornamenti di Windows 10 che, più recentemente, con l'aggiornamento 24H2 di Windows 11. Questo errore, che si manifesta con l'impossibilità di procedere con l'installazione dell'aggiornamento, indica la presenza di software o driver incompatibili sul sistema.

Causa dell'Errore 0xc1900208

L'errore 0xc1900208 è una segnalazione diretta da parte di Windows Update che una o più componenti hardware o software installate sul sistema sono in conflitto con il processo di aggiornamento. Il sistema operativo esegue una scansione preliminare per verificare la compatibilità e, se rileva elementi "bloccanti" con una compatibilità "Hard" (ovvero, un blocco critico), interrompe l'aggiornamento per prevenire potenziali instabilità o malfunzionamenti.


Identificazione del Software o Driver Incompatibile

Il processo di risoluzione inizia con l'identificazione precisa del componente che sta causando il blocco. Fortunatamente, Windows Update fornisce un log dettagliato della scansione di compatibilità, eliminando la necessità di una ricerca manuale.

Accedere al File C:\$WINDOWS.~BT\Sources\Panther\ScanResult.xml.

Analizzare il contenuto del File XML ricercando le voci che indicano un blocco relativo a software o a driver:
- Software bloccante
Per verificare se l'errore è causato da un software non compatibile, ricercare le righe contenenti 
CompatibilityInfo BlockingType="Hard"
Il campo Title nella stessa riga indicherà il nome del programma responsabile del blocco. 
Ad esempio, in FIG 1, risulta che il software che sta impedendo l'aggiornamento è ExplorerPatcher.
Applicazione Bloccante
FIG 1 - Applicazione Bloccante


- Driver bloccante
Scorrere il file fino alla sezione Driver Packages quindi identificare i driver che presentano l'attributo 
BlockMigration="True"
In FIG2, i driver bloccanti sono oem113.inf e oem143.inf. 
Driver Bloccanti
FIG 2 - Driver Bloccanti

Gestione del Software Bloccante

Una volta identificato un programma bloccante, la soluzione più diretta è la sua disinstallazione o l'aggiornamento a una versione compatibile (se disponibile).

Gestione dei Driver Bloccanti

La gestione dei driver richiede maggiore cautela, poiché la rimozione di un driver errato può compromettere l'avvio del sistema

I file .inf (come oem113.inf) sono descrittori del driver. Per identificare il driver effettivo, seguire questi passaggi:
  • Aprire la cartella c:\windows\INF.
  • Cercare il file oemXXX.inf identificato nel ScanResult.xml.
  • Aprire il file .inf con un editor di testo (ad esempio, Blocco Note).
  • Cercare all'interno del file il nome del driver o dell'applicazione associata.

Una volta individuato il nome del driver è possibile tentare di aggiornarlo, disabilitarlo o rimuoverlo:
Aggiornamento: La prima e più sicura opzione è tentare di aggiornare il driver alla sua versione più recente. Questo può essere fatto tramite Windows Update, il sito web del produttore del dispositivo o l'utilizzo di strumenti di gestione dei driver. 

Disabilitazione (Temporanea): In alcuni casi, se l'aggiornamento non è possibile o se il driver non è critico per l'operatività di base, si potrebbe considerare di disabilitarlo temporaneamente tramite Gestione Dispositivi. Tuttavia, questa è una soluzione temporanea e non risolve la radice del problema di compatibilità.

Rimozione (con Cautela): La rimozione del driver è l'ultima risorsa e deve essere eseguita con estrema cautela. Prima di procedere, è imperativo creare un punto di ripristino del sistema o un backup completo. Se il driver è essenziale per un componente hardware, la sua rimozione potrebbe rendere il dispositivo inutilizzabile o impedire l'avvio del sistema. È consigliabile procedere con la rimozione solo se si è certi che il driver non sia critico o se si dispone di un driver sostitutivo pronto per l'installazione. La rimozione è possibile tramite Gestione Dispositivi o dal prompt dei comandi come amministratore eseguendo il comando
pnputil /delete-driver oemXXX.inf /uninstall /force


Tentativo di Aggiornamento di Windows

Dopo aver rimosso o aggiornato il software e/o i driver bloccanti, è possibile riprovare l'aggiornamento di Windows. In Windows 11 accedere alle Impostazioni (WIN+I), selezionare Windows Update quindi cliccare sul pulsante Riprova o Verifica disponibilità aggiornamenti.

Windows Update
FIG 3 - Windows Update





mercoledì 30 luglio 2025

Windows: Come eliminare il contenuto dei registri eventi di sistema

Esistono centinaia di file di registro eventi utilizzati in Windows da vari componenti del sistema operativo e da software di terze parti. Per impostazione predefinita, Windows memorizza i file di registro con estensione EVTX nella directory %SystemRoot%\System32\Winevt\Logs\.

È possibile cancellare i log dei registri eventi di sistema utilizzando il Visualizzatore Eventi (lo snap-in eventvwr.msc), il prompt dei comandi oppure utilizzando PowerShell. Quando si cancella il contenuto di un registro eventi, nel registro eventi Sistema viene generato un evento, con ID 104 o 1102, che indica la pulizia del log, chi l'ha eseguita e quando. È una traccia utile per l'audit.

Registro Eventi Sistema, ID evento 104, Log Clear
FIG 1 - Registro Eventi Sistema, ID evento 104, Log Clear

In questo articolo verranno mostrati in dettaglio i tre metodi più comuni per eliminare il contenuto dei registri eventi.

Metodo 1 - Visualizzatore Eventi (Event Viewer)

Per chi preferisce un approccio visivo (tramite GUI), la console Event Viewer (eventvwr.msc) è la soluzione più immediata: 
  1. Aprire la console di Visualizzatore eventi (premere la combinazione WIN+R e, nella finestra Esegui, digitare eventvwr.msc seguito Invio).
  2. Nel pannello di sinistra, navigare fino al registro eventi che si desidera ripulire (ad esempio, "Applicazione", "Sistema" o "Sicurezza").
  3. Cliccare con il tasto destro del mouse sul nome del registro eventi e selezionare "Cancella registro".

    Cancella registro
    FIG 2 - Cancella registro

  4. Verrà chiesto se si desidera salvare il contenuto del registro prima di cancellarlo. Questa è un'ottima pratica per la risoluzione dei problemi futuri o per la conformità.

    Richiesta conferma di cancellazione
    FIG 3 - Richiesta conferma di cancellazione

Questo metodo è perfetto per una pulizia rapida di un singolo log ma non è consigliato se si intende eseguire l'operazione su un numero elevato di log.


Metodo 2 - Prompt dei comandi

Per eliminare i log del registro eventi tramite il Prompt dei comandi si può utilizzare il tool wevtutil.exe.

Il primo passo consiste nell'individuare il nome del log che si intende eliminare. Per visualizzare l'elenco dei log disponibili avviare il Prompt dei comandi come amministratore e utilizzare il comando
WevtUtil enum-logs
oppure la versione breve
WevtUtil el
Elenco registri eventi
FIG 4 - Elenco registri eventi


Supponiamo di voler eliminare i log contenuti nel registro Applicazione. Il comando da utilizzare è 
WevtUtil cl Application

Per eseguire un backup prima di cancellare il contenuto del registro
WevtUtil cl Application /bu:Application_Bak.evtx
WevtUtil, Backup e cancellazione log del registro eventi Applicazione
FIG 5 - WevtUtil, Backup e cancellazione log del registro eventi Applicazione


Per pulire tutti i log presenti in tutti i registri eventi in un colpo solo, è possibile utilizzare il comando
for /F "tokens=*" %1 in ('wevtutil.exe el') DO wevtutil.exe cl "%1"

Nel caso in cui volessimo utilizzare il comando all'interno di un file BAT la sintassi è leggermente diversa e il comando diventa
for /F "tokens=*" %%1 in ('wevtutil.exe el') DO wevtutil.exe cl "%%1"


Metodo 3 - PowerShell

Avviare la console PowerShell come amministratore. Per visualizzare l'elenco dei registri eventi
Get-WinEvent -ListLog *

Per ciascun registro eventi vengono visualizzati ulteriori dettagli come la dimensione massima, il numero di eventi contenuto e la modalità di log.
Get-WinEvent, Visualizza elenco registri eventi
FIG 6 - Get-WinEvent, Visualizza elenco registri eventi


Per eliminare il contenuto di un registro eventi si utilizza il cmdlet Clear-EventLog. Ad esempio, per eliminare il contenuto del registro eventi Applicazione:
Clear-EventLog –LogName Application
Clear-EventLog, cancellazione log del registro eventi Applicazione
FIG 7 - Clear-EventLog, cancellazione log del registro eventi Applicazione


Per eliminare il contenuto di più registri eventi basta separarli con una virgola. Ad esempio per eliminare il contenuto del registro Sicurezza e Sistema:
Clear-EventLog –LogName Security,System

Per eliminare il contenuto di tutti i registri eventi:
Get-WinEvent -ListLog * -Force | % { Wevtutil.exe cl $_.Logname }
Oppure
wevtutil el | Foreach-Object {wevtutil cl "$_"}


A volte, è possibile imbattersi in un errore di "accesso negato" con alcuni log. Questo può accadere se il log è in uso o se mancano i permessi necessari. In questi casi, un tentativo manuale tramite Event Viewer potrebbe risolvere il problema.




martedì 29 luglio 2025

Windows: Spegnere lo Schermo tramite riga di comando

Spegnere il monitor quando non è in uso può essere utile per ridurre significativamente il consumo energetico, sia su laptop che su desktop, e si rivela particolarmente utile durante l'esecuzione di lunghe attività o script che non richiedono l'interazione visiva con lo schermo

Per visualizzare il timeout attuale dello schermo, è possibile utilizzare la GUI del Pannello di Controllo navigando nelle opzioni di risparmio energia (control.exe powercfg.cpl,,3) oppure, per un approccio più rapido e scriptabile, si può ricorrere al Prompt dei Comandi o PowerShell con il comando:
powercfg /q

Questo comando elenca dettagliatamente tutte le impostazioni del piano di alimentazione attivo. Per un'analisi più specifica del timeout del display, si possono cercare le seguenti informazioni all'interno dell'output:

Disattiva schermo dopo
FIG 1 - Disattiva schermo dopo


  GUID sottogruppo: 7516b95f-f776-4464-8c53-06167f40cc99  (Schermo)
    Alias GUID: SUB_VIDEO
    GUID impostazioni risparmio energia: 3c0bc021-c8a8-4e07-a973-6b14cbcb2b7e  (Disattiva schermo dopo)
      Alias GUID: VIDEOIDLE
      Minima impostazione possibile: 0x00000000
      Massima impostazione possibile: 0xffffffff
      Incremento impostazioni possibile: 0x00000001
      Unità impostazioni possibili: Secondi
    Indice impostazione alimentazione CA corrente: 0x00000384
    Indice impostazione alimentazione CC corrente: 0x000000b4


Nell'esempio sopra, il valore 0x00000384 (in esadecimale) corrisponde a 900 secondi, ovvero 15 minuti, per lo spegnimento automatico del display quando il dispositivo è collegato alla corrente alternata (CA). Analogamente, 0x00000b4 rappresenta 180 secondi o 3 minuti per la modalità a batteria (CC).
Opzioni risparmio energia
FIG 2 - Opzioni risparmio energia



Configurare il Timeout di spegnimento del Display tramite riga di comando

Per modificare il tempo dopo il quale il display si spegne automaticamente all'interno del piano di alimentazione corrente, è possibile utilizzare i seguenti comandi:
  • Per la corrente alternata (AC), impostando un timeout di 5 minuti:
    powercfg -change -monitor-timeout-ac 5
  • Per la corrente continua (DC), impostando un timeout di 5 minuti:
    powercfg -change -monitor-timeout-dc 5
Questi comandi consentono una gestione granulare e scriptabile delle impostazioni di risparmio energetico del monitor.


Spegnimento immediato del Display tramite PowerShell

Per situazioni in cui è necessario spegnere il display immediatamente, Windows offre una soluzione tramite PowerShell che sfrutta le API di sistema. Questo metodo è particolarmente utile per script automatizzati o per creare scorciatoie personalizzate.

Esegui il seguente comando in un prompt dei comandi o direttamente tramite la finestra Esegui (Win+R):
cmd.exe /c powershell (Add-Type '[DllImport(\"user32.dll\")]^public static extern int SendMessage(int hWnd, int hMsg, int wParam, int lParam);' -Name a -Pas)::SendMessage(-1,0x0112,0xF170,2)


Questo comando richiama la funzione SendMessage dell'API user32.dll per inviare un messaggio di spegnimento al monitor.





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.




lunedì 21 luglio 2025

Windows: Individuare quale utente ha installato o rimosso un programma

In ambienti IT complessi e distribuiti, dove molteplici amministratori operano su un'infrastruttura condivisa, la necessità di mantenere una tracciabilità dettagliata delle modifiche al software è cruciale. Ogni modifica al parco software di un'azienda, sia essa un'installazione o una disinstallazione, può avere implicazioni significative. L'introduzione di nuove applicazioni può portare a vulnerabilità di sicurezza se non gestite correttamente, mentre la rimozione non autorizzata di software essenziale può causare interruzioni operative. Identificare rapidamente l'autore di tali azioni non solo facilita l'audit e la conformità normativa, ma permette anche una risposta tempestiva a eventuali problemi di configurazione o di sicurezza.

MsiInstaller e Registo Eventi di Windows

Il sistema operativo Windows, attraverso il suo meccanismo di logging degli eventi, registra in dettaglio le attività svolte. In particolare, quando si installano o disinstallano applicazioni "classiche" basate sul programma di installazione MSI (Microsoft Installer), eventi specifici vengono scritti nel log di sistema. Il provider `MsiInstaller` è il principale responsabile della registrazione di queste operazioni.

Due eventi chiave nel log "Applicazione" sono di particolare interesse:
  • ID Evento 11707: Indica il completamento con successo dell'installazione di un'applicazione MSI.
  • ID Evento 11724: Indica la disinstallazione di un'applicazione MSI.

Analisi Manuale tramite il Visualizzatore Eventi

Per iniziare l'indagine, è possibile utilizzare la console del Visualizzatore eventi di Windows (eventvwr.msc). Una volta aperta, seguire questi passaggi:
  1. Navigare su Registri di Windows->Applicazione.
  2. Nel pannello di destra, selezionare Filtra registro corrente....
  3. Nel campo "ID evento:", inserire '11707, 11724'.
  4. Nel campo "Origini evento:", selezionare 'MsiInstaller'.
  5. Cliccare su OK.
Filtro registro corrente
FIG 1 - Filtro registro corrente


Verrà visualizzato un elenco filtrato di eventi relativi all'installazione e alla rimozione di programmi. Ogni evento contiene una descrizione dettagliata dell'operazione, inclusi il nome del prodotto coinvolto e l'esito. Ad esempio:
Product: Python 3.13.5 Add to Path (64-bit) -- Installation completed successfully.
Prodotto: Adobe Acrobat Reader - Italiano -- Removal completed successfully.

La proprietà "Utente" di ogni evento rivela l'account che ha eseguito l'azione, fornendo immediatamente la necessaria attribuzione.
Registro Eventi Applicazione, Origine MsiInstaller
FIG 2 - Registro Eventi Applicazione, Origine MsiInstaller

Automazione con PowerShell per una Ricerca Rapida

Per ambienti con un elevato volume di eventi o per necessità di automazione, PowerShell offre un metodo più efficiente per interrogare i log degli eventi. Il seguente script PowerShell permette di filtrare rapidamente gli eventi di installazione e disinstallazione per un'applicazione specifica, fornendo il nome utente associato:

Get-WinEvent -FilterHashtable @{LogName="Application"; ID=11707,11724; ProviderName='MsiInstaller'} | Where-Object { $_.Message -like '*NomeApplicazione*' } | Select TimeCreated, @{Name='Username'; Expression={(New-Object System.Security.Principal.SecurityIdentifier($_.userid)).Translate([System.Security.Principal.NTAccount]).Value}}, Message

Sostituire `'*NomeApplicazione*'` con una parte del nome del programma che si desidera tracciare (ad esempio, `'*Python*'`).


Get-WinEvent -FilterHashtable @{...}
Questo cmdlet è utilizzato per recuperare eventi dai log di Windows.

LogName="Application"
Specifica il log degli eventi "Applicazione".

ID=11707,11724
Filtra per gli ID evento di installazione e disinstallazione.

ProviderName='MsiInstaller'
Limita la ricerca agli eventi generati dal provider MsiInstaller.

Where-Object { $_.Message -like '*NomeApplicazione*' }
Filtra ulteriormente gli eventi in base al contenuto del messaggio, cercando il nome dell'applicazione di interesse.

Select TimeCreated, @{Name='Username'; Expression={(New-Object System.Security.Principal.SecurityIdentifier($_.userid)).Translate([System.Security.Principal.NTAccount]).Value}}, Message
Seleziona le proprietà desiderate:
  • TimeCreated: L'ora in cui l'evento è stato generato.
  • Username: Questa è una proprietà calcolata. Il campo 'userid' nell'evento contiene il Security Identifier (SID) dell'utente. Questa espressione PowerShell converte il SID in un nome di account utente leggibile ('NTAccount'), rendendo l'informazione immediatamente utile.
  • Message: Il messaggio completo dell'evento, contenente i dettagli dell'operazione.
PowerShell, Get-WinEvent
FIG 3 - PowerShell, Get-WinEvent


Considerazioni Aggiuntive e Best Practices

  • Log Retention Policy: Assicurarsi che la policy di conservazione dei log degli eventi sia adeguatamente configurata per mantenere i dati per un periodo sufficiente. Una policy troppo restrittiva potrebbe causare la sovrascrittura di informazioni preziose.
  • Gestione Centralizzata dei Log: In ambienti di grandi dimensioni, è consigliabile implementare un sistema centralizzato di gestione dei log (SIEM o un log collector dedicato). Questo non solo facilita la ricerca e l'analisi su più sistemi, ma migliora anche la sicurezza dei log, proteggendoli da manipolazioni locali.
  • Alternative di Installazione: È importante notare che questo metodo è primariamente efficace per installazioni e disinstallazioni che utilizzano l'installer MSI. Software installati tramite altri metodi (ad esempio, XCOPY deployment, Windows Store Apps, o script personalizzati) potrebbero non generare eventi MsiInstaller e richiedere metodi di monitoraggio alternativi.
  • Least Privilege: Implementare sempre il principio del privilegio minimo per gli account utente e di servizio. Questo riduce la superficie di attacco e limita le possibilità di modifiche non autorizzate al software.




venerdì 18 luglio 2025

Windows: Scrivere i log nel Visualizzatore eventi di Windows con PowerShell e CMD

Il Registro Eventi di Windows è uno strumento integrato nel sistema operativo che registra eventi, errori e avvisi relativi a diverse componenti del sistema e alle applicazioni installate. Questi registri sono fondamentali per il monitoraggio del sistema, la diagnostica dei problemi e la sicurezza e sono accessibili attraverso il Visualizzatore Eventi (Event Viewer) anch'esso incluso nel sistema operativo .

Per le nostre applicazioni/script, anziché affidarci esclusivamente a file di log testuali, possiamo sfruttare le potenzialità del registro eventi di Windows.

In questo articolo vedremo come scrivere informazioni nel Registro Eventi utilizzando PowerShell e il Prompt dei Comandi (CMD), due strumenti indispensabili per ogni amministratore di sistema.

1. Scrivere Eventi con PowerShell

Il cmdlet principale per scrivere eventi nel Visualizzatore Eventi è 
Write-EventLog

Per scrivere un evento informativo nel  registro eventi Applicazione si può utilizzare il comando:
Write-EventLog -LogName Application -Source "Application" -EntryType Information -EventID 1 -Message "Messaggio personalizzato"

-LogName:
Specifica il nome del registro eventi di destinazione (es. "Application", "System", "Security").
-Source:
Definisce l'origine dell'evento. Se l'origine non esiste, PowerShell tenterà di crearla, ma è buona pratica crearla esplicitamente prima.
-EntryType:
Indica il tipo di evento. I valori accettati sono: Error, Information, FailureAudit, SuccessAudit, Warning.
-EventID:
Specifica un identificatore numerico per l'evento, utile per la categorizzazione e il filtraggio.
-Message:
Il testo descrittivo dell'evento.
PowerShell, Creare un evento nel Registro Eventi
FIG 1 - PowerShell, Creare un evento nel Registro Eventi

Visualizzatore Eventi
FIG 2 - Visualizzatore Eventi

Creazione e Utilizzo di una Origine Evento Personalizzata
Per una migliore organizzazione e identificazione, è consigliabile creare un'origine evento personalizzata per i propri script. Questo permette di filtrare facilmente gli eventi generati dalle proprie applicazioni.

Per creare una nuova origine evento:
New-EventLog -LogName Application -Source "MioScript"

Questo comando registra "MioScript" come nuova origine nel registro eventi "Applicazione".

Per scrivere un evento con l'origine personalizzata:
Write-EventLog -LogName Application -Source "MioScript" -EntryType Warning –EventID 1 –Message "Messaggio personalizzato"
Creazione e utilizzo di una origine evento personalizzata
FIG 3 - Creazione e utilizzo di una origine evento personalizzata

Dopo aver eseguito questi comandi, aprire il Visualizzatore Eventi (digitando eventvwr.msc nella finestra Esegui o nel Prompt dei Comandi), espandere "Registri di Windows" quindi selezionare il registro "Applicazione" e verificare la presenza del nuovo evento con la descrizione personalizzata.
Visualizzatore eventi, Evento con origine personalizzata
FIG 4 - Visualizzatore eventi, Evento con origine personalizzata


Gestione dei Registri Eventi Personalizzati
Oltre ai Registri Eventi predefiniti, è possibile crearne di personalizzati per raggruppare eventi specifici. Questo è particolarmente utile per applicazioni complesse o per la segregazione dei log.

Il cmdlet New-EventLog consente anche di creare un intero log eventi personalizzato, specificando più origini associate:
New-EventLog -LogName MioRegistroEventi -source 'Origine1','Origine2','Origine3'


Importante: Affinché un nuovo log eventi personalizzato appaia nel Visualizzatore Eventi, è necessario inviargli almeno un evento.

Quando si scrivono eventi in un registro eventi personalizzato, è una buona pratica verificare se il registro esiste già per evitare errori:

If ([System.Diagnostics.EventLog]::SourceExists('MioRegistroEventi') -eq $False) {
 New-EventLog -LogName MioRegistroEventi -source 'Origine1','Origine2','Origine3'
}
Write-EventLog -LogName MioRegistroEventi -Source Origine1 -EntryType Information -EventID 1 -Message "Test"

Un nuovo file .evtx verrà creato nella cartella %SystemRoot%\System32\Winevt\Logs per ogni registro personalizzato.

All'interno del Visualizzatore Eventi il nuovo registro eventi sarà visibile all'interno di "Registri applicazioni e servizi".
Nuovo Registro Eventi
FIG 5 - Nuovo Registro Eventi



2. Scrivere Eventi con CMD

Per gli script batch (.bat/.cmd), lo strumento da utilizzare è eventcreate.exe.

Per aggiungere un evento informativo al registro eventi "Applicazione":
eventcreate /t information /l application /id 1 /d "Messaggio personalizzato"

/t
Specifica il tipo di evento (es. ErrorInformationSuccessWarning).
/l:
Indica il nome del registro eventi di destinazione (es. "Application", "System", "Security").
/id:
L'ID numerico dell'evento.
/d:
La descrizione dell'evento.

EventCreate, Creazione Evento da Prompt dei Comandi
FIG 6 - EventCreate, Creazione Evento da Prompt dei Comandi



3. Query e Filtraggio dei Registri Eventi

Una volta che gli eventi sono stati registrati, il cmdlet Get-WinEvent è lo strumento più potente per cercarli e filtrarli in PowerShell. Questo cmdlet è più moderno e versatile rispetto a Get-EventLog (che opera solo sui log classici).
Get-WinEvent -FilterHashtable @{logname='MioRegistroEventi';id=1}|ft TimeCreated,Id,Message | Select-Object -First 15

Questa query filtra gli eventi nel log "MioRegistroEventi" con EventID pari a 1 e visualizza le prime 15 occorrenze, mostrando la data di creazione, l'ID e il messaggio.
PowerShell, Query registro eventi
FIG 7 - PowerShell, Query registro eventi



4. Considerazioni

Considerazioni su PowerShell Core
Nelle versioni più recenti di PowerShell Core (7.x e successive), il cmdlet Write-EventLog non è supportato nativamente per impostazione predefinita. Tentare di usarlo genererà un errore.

Per usare Write-EventLog in PowerShell Core, è necessario importare il modulo Microsoft.PowerShell.Management con l'opzione -UseWindowsPowerShell:

Import-Module Microsoft.PowerShell.Management -UseWindowsPowerShell

Questo consente a PowerShell Core di accedere ai cmdlet di gestione specifici di Windows PowerShell.


Permessi di Accesso
Per scrivere eventi nel Visualizzatore Eventi utilizzando Write-EventLog o eventcreate.exe, l'account utente che esegue lo script deve essere membro del gruppo Administrators locale. Un utente non amministratore può solo inviare eventi a log eventi personalizzati che sono stati creati da un amministratore.