A volte può capitare di dover lavorare in assenza di strumenti di inventory dei sistemi appropriati e con ambienti a dir poco legacy – chi ha detto Windows 7? – e cosa si può fare se ci viene richiesto di produrre reportistica che contenga lo stato attuale del parco macchine?
Mi è di recente capitata una simile richiesta, che ho potuto esaudire velocemente usando un paio di script PowerShell insieme a PsExec di Microsoft, dato che si trattava di un ambiente puramente Windows.
Potete scaricare qui da GitHub i due script.
Scaricate anche PsExec e piazzatelo in una directory sul pc da cui lancerete lo script.
Premesse indispensabili: ci sono strumenti anche open source per l’inventory, ma in questo caso non ho deciso di utilizzarli, perchè avevo bisogno di una soluzione veloce e non volevo un altro server da manutenere, né installare altro software su tutti i client. Inoltre, avrei potuto usare il remoting della PowerShell al posto di PsExec, ma per varie ragioni questa scelta non era percorribile nel mio caso.
La soluzione è basata su due script, Get-PcInventoryData.ps1 e Deploy-PcInventory.ps1: il primo è quello che eseguono i computer per produrre l’inventario e salvare i risultati in un file CSV con la data di esecuzione nel nome, il secondo è quello che va eseguito dalla workstation dell’admin per distribuire e lanciare lo script su tutti i computer.
Il setup è molto semplice: va creata innanzitutto una share di rete su un server in cui appoggiare lo script Get-PcInventoryData.ps1 e su cui sarà scritto il file CSV con i risultati. A livello di permessi, fate in modo che il gruppo Domain Computers (o comunque i computer da processare) abbiano il permesso di WRITE su questa directory per poter scrivere il file CSV.
Questa directory va poi impostata nella variabile $logPath nello script Deploy-PcInventory.ps1 e Get-PcInventoryData.ps1.
In Deploy-PcInventory.ps1 va personalizzata anche la variabile con il log degli errori ($failedLogDir). Deve essere passato poi allo script un file di testo con l’elenco dei computer da processare ($targetPcs), un file con i nomi dei computer uno per riga.
Infine, alla riga 37 va modificato il path locale in cui si trova PsExec (io ho usato “C:\Scripts”) ed il path UNC della share di rete dove abbiamo messo lo script Get-PcInventoryData.ps1:
Start-Process C:\scripts\PsExec.exe -ArgumentList "-s \\$($target) powershell.exe -inputformat none -ExecutionPolicy bypass -command \\server\path\toscript\Get-PcInventoryData.ps1" -Wait
Lo script produce un inventario piuttosto basilare, con nome macchina, versione OS, data di installazione, info sulla CPU, numero dei banchi di RAM, totale RAM e dimensione del primo disco rigido installato.
Può però essere facilmente esteso, aggiungendo altre query in Get-PcInventoryData.ps1 , la struttura è molto semplice. In caso di modifica va cambiata anche la linea con la variabile dei risultati:
$results = "$hostname,$osVersion,$installDate,$cpuInfo,$memorySticks,$memoryTotal,$physicalDiskSize"
Stessa modifica in Deploy-PcInventory.ps1 poi qui:
Set-Content -Path $logPath$logfile "Hostname,OsInfo,InstallDate,CpuInfo,MemorySticks,MemoryTotal,PhysicalDiskSize"
A questo punto potete eseguire sulla vostra workstation lo script di deploy: dovete lanciarlo come utente che abbia privilegi di admin sui computer che dovete inventariare. Se questo non fosse possibile, modificate la riga 37 dello script che abbiamo già visto, aggiungendo agli argomenti di PsExec anche user e password di un admin dei computer (una volta finito poi toglieteli dallo script!) per collegarsi e lanciare lo script:
Start-Process C:\scripts\PsExec.exe -ArgumentList "-s -u DOMINIO\MioUtente -p LaMiaPassword! \\$($target) powershell.exe -inputformat none -ExecutionPolicy bypass -command \\server\path\toscript\Get-PcInventoryData.ps1" -Wait
Ultima nota: sarebbe meglio usare Get-CimInstance per estrarre le info dai computer, ma purtroppo in questo caso mi sono trovato a dover supportare anche Windows 7 e Get-WmiObject è stata quindi una scelta obbligata.
L’output prodotto è un file CSV come questo:
Magari più avanti espanderò lo script con più info, adattandolo anche ad essere eseguito senza PsExec.