PowerShell & WSUS: che coppia !
Sicuramente converrete con me che la gestione di WSUS sia tediosa, lenta, lacunosa ... non si può certo dire che la Web-UI sia il massimo ;-)
Poichè ero stufo di "smanettare" a mano sia i miei server WSUS che quelli dei clienti, ho pensato bene di cominciare a investigare il connubio tra WSUS e PowerShell.
Non che avessi grandi dubbi, ma il risultato è spettacolare; vediamo con ordine come e perchè.
WSUS dispone di un set di classi .Net per l'amministrazione, definite in WSUS 2.0 e che saranno presto estese in WSUS 3.0 (ora in RC); queste sono illustrate in alcuni esempi VB.Net forniti da Microsoft in un download separato da WSUS, oltre ad essere documentate sull'MSDN.
Dove ci sono classi .Net ... WPS va a nozze ! Quindi mettiamoci all'opera, installiamo PowerShell sul server WSUS e cominciamo caricando gli assembly per interagire con WSUS:
[System.Reflection.Assembly]::LoadWithPartialName('microsoft.updateservices.common')
[System.Reflection.Assembly]::LoadWithPartialName('microsoft.updateservices.administration')
Magari il primo non ci servirà subito, ma può sempre tornare utile.
Ora instanziamo il primo oggetto, che ci consentirà poi di accedere al nostro WSUS:
$wsus=new-object 'Microsoft.UpdateServices.Administration.AdminProxy'
A questo punto possiamo utilizzare le solite sintassi di PowerShell, per sfruttare Reflection e chiedere come è fatto un oggetto:
$wsus | get-member # oppure | gm
Adesso connettiamoci all'istanza di WSUS che gira in locale, e facciamoci dare qualche informazione di configurazione:
$wsusrv = $wsus.GetUpdateServerInstance()
$wsusrv.GetConfiguration()
$wsusrv.GetDatabaseConfiguration()
Carino ? Aspettate, c'è da leccarsi le dita :-)
Chiediamo un sommario di Status e se vi sono componenti in errore (es: il classico "SelfUpdate Tree is not working")
$wsusrv.GetStatus()
$wsusrv.GetComponentsWithErrors()
Ora passsiamo all'azione: chiediamo l'elenco dei "gruppi" di WSUS, creiamone uno al volo e richiediamo la lista (magari controllando anche sulla Web UI per sicurezza):
$wsusrv.GetComputerTargetGroups() | sort -prop Name
$wsusrv.CreateComputerTargetGroup('Prova')
$wsusrv.GetComputerTargetGroups() | sort -prop Name
Cool! Potremmo creare in modo massivo/batch tutti i Gruppi che ci servono sempre con un semplice comando WPS:
'Test-Server', 'Test-Client', 'No-Patch' | % { $wsusrv.CreateComputerTargetGroup( $_)}
Lavoriamo ora con l'estrazione di informazioni sui computer "target", con alcuni esempi:
# Tutti i Target, salviamoli in una variabile
$WsusComputers = $wsusrv.GetComputerTargets()
# Solo alcune proprietà e con Sort
$WsusComputers | select -prop FullDomainName,IPAddress | sort FullDomainName
# Ci sono macchine virtuali di Virtual Server/Virtual PC ?
$WsusComputers | where { $_.Model -eq 'Virtual Machine'} | sort FullDomainName
# Cadaveri in WSUS ?
$WsusComputers | where {$_.LastReportedStatusTime -lt (get-date).AddDays(-30)} | select -prop FullDomainName,IPAddress,LastReportedStatusTime | sort -desc LastReportedStatusTime
Stra-Stra-Cool ! Ma non è finita ;-) Adesso passiamo a manipolare gli Updates:
# Estraiamo gli Updates "obsoleti" ovvero quelli Superseded ma non Declined
$OldUpd = $wsusrv.GetUpdates() | where {($_.IsDeclined -eq $False) -and ($_.IsSuperseded -eq $True)}
# Quanti sono ?
$OldUpd.Count
# Ci interessa manipolare solo le definizioni AntiSpam/AntiVirus/ecc.
$oldDefinition = $OldUpd | where {$_.UpdateClassificationTitle -eq 'Definition Updates'}
# Facciamoci dare qualche informazione di controllo
$oldDefinition | fl -prop Title,Description,ArrivalDate
# ... e decliniamole automaticamente !
$oldDefinition | % {$_.Decline()}
Beh ... che dire ? Ogni giorno PowerShell rivela il suo potenziale immenso, quasi inesplorato.
Tornerò presto sull'uso di WSUS e WPS, perchè ci sono notevoli spazi di integrazione, per la reportistica, alerting, automazione di approvazioni ed esclusioni, manutenzione del DB, integrazione AD, ecc.
MCSA, MCSE, MCT su NT/2000/2003
MCTS: Windows Server 2008 Active Directory/Application Platform/Network Infrastructure