Utente:Iron Bishop/chiediSoftware

Da Wikipedia, l'enciclopedia libera.
Vai alla navigazione Vai alla ricerca

In casa spesso abbiamo più computer che montano Microsoft Windows usati da diverse persone, avere un domain controller (ad esempio una macchina GNU/Linux con Samba) è utile per gestire i profili in maniera centralizzata. Ma non solo: con un domain controller possiamo avere una lista di tutto il software installato sulle macchine che fanno parte del dominio.

Ottenere i dati

[modifica | modifica wikitesto]

Questo codice è stato scritto da BKA ed è distribuito sotto licenza GNU GPL.

I dati sul software installato vengono scritti in un file direttamente sul domain controller (DC), nell'area relativa al logon. Lo script (un batch file) che segue va associato al logon dell'utente. L'output è un file di testo che contiene i dati del software installato per ogni pc, replicati per ogni volta che l'utente fa il logon.

@echo off
set DC=\\hostnameDC
set dati=%DC%\netlogon\dati\log.txt
set prgs=%DC%\netlogon\dati\software.txt
set fooreg=%temp%\foo.reg
set footmp=%temp%\foo.tmp
set foolog=%temp%\foo.log
if exist %fooreg% del %fooreg%
if exist %foolog% del %foolog%
if exist %footmp% del %footmp%
echo -------------------------------------------------- >> %foolog%
net time %DC% | find /I "%DC%" >> %foolog%

date /T >> %foolog%
time /T >> %foolog%
echo --- WNT: Rete --- >> %foolog%
net config workstation | find /I "Nome" >> %foolog%
net config workstation | find /I "Name" >> %foolog%
regedit /E %fooreg% HKEY_CURRENT_USER\Network
type %fooreg% | find /V "REGEDIT4" > %footmp%
type %footmp% | find /V "Network]" > %fooreg%
type %fooreg% | find /V "Provider" > %footmp%
type %footmp% | find /V "dword" > %fooreg%
type %fooreg% | find /V "UserName" > %footmp%
type %footmp% >> %foolog%
del %fooreg%
del %footmp%

rem Interrogazione del software installato. BKA. 21.03.2002.

echo --- WNT: Identificazione --- >> %footmp%
net time %1 | find /I "%DC%" >> %footmp%
net config workstation | find /I "Nome" >> %footmp%
net config workstation | find /I "Name" >> %footmp%
echo --- WNT: Software --- >> %footmp%
regedit /E %fooreg% HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
type %fooreg% | find """DisplayName""" >> %footmp%
del %fooreg%
type %footmp% >> %prgs%
del %footmp%

rem La fine dell'interrogazione

:exit
type %foolog% >> %dati%
del %foolog%

Analizzare i dati

[modifica | modifica wikitesto]

Questo codice è stato scritto da Iron Bishop ed è di pubblico dominio.

Una volta ottenuto il file "software.txt", si ha un file che contiene tante volte l'elenco del software installato nei pc quante sono le volte che l'utente ha effettuato il logon. Per sapere se un software è installato o meno è sufficiente analizzare il file in modo sequenziale, ad esempio con il seguente programma PHP (la cui documentazione è integrata).

<?
/*
  chiediSoftware.php - controlla la lista del software
      installato sulle macchine di un dominio partendo
      da un registro proveniente dal domain controller

  Creato da Flavio "Iron Bishop" Pastore - pubblico dominio

  History:
  * ver 1.9 - 16.05.2006 - Iron Bishop
  * ver 1.1 - 03.05.2006 - Iron Bishop
  * ver 1.0 - 10.03.2006 - Iron Bishop
  * ver 0.1 - 08.03.2006 - Iron Bishop

-----------------------------------------------------------------------------

  Abstract:
  chiediSoftware.php permette di sapere in quanti PC è attualmente installato
  un software; se il software è stato installato e poi rimosso, è come se non
  fosse mai stato installato; la procedura crea un array così composto:

   HOST		nome dell'host (chiave dell'array!)
   DATE		data dell'ultimo logon al dominio
   NAME		nome dell'utente che ha fatto l'ultimo logon
   STATUS	stato del software, TRUE se "installato"

  La procedura può essere usata solo su un software per volta. Possono essere
  specificati dei parametri:

   f		necessario	file di input
   s		necessario	nome del software da cercare
   l		opzionale	output: text / csv

  Senza parametro di output, il software si limita a scrivere su stdout pochi 
  dati riassuntivi relativi al risultato della ricerca. Altrimenti si possono
  specificare i formati:

   text		una riga per ogni host, con data e nome utente ultimo logon;
   csv		una sola riga con informazioni su software, numero di pc dove
                 il software è installato, nome e utente di quei pc;

  Specificando un formato, non vengono scritti i dati riassuntivi.


  Ad esempio:
   php -f chiediSoftware.php s="F-secure" f=software.txt l=csv

-----------------------------------------------------------------------------
*/

// inizializzazione
$FILE      = $_GET["f"];                             // parametro necessario - input
$SOFTWARE  = $_GET["s"];                             // parametro necessario - query
$LISTALL   = $_GET["l"];                             // parametro opzionale - lista
$VER       = "chiediSoftware.php v1.9 - by Iron Bishop";// versione del software
$HOST_TAG  = "(Nome computer completo)(.*)";         // regexp nome computer
$NAME_TAG  = "(Nome utente)(.*)";                    // regexp nome utente
$TIME_TAG  = "([0-9]{1,2})/([0-9]{1,2})/([0-9]{4})"; // regexp data
$find      = array();                                // array principale
$host      = "nome";                                 // indice dell'array
$date      = "";                                     // data
$yes       = 0;                                      // numero host con software installato

$HELP = $VER."\nUtilizzo:\n php -f chiediSoftware.php s=foo f=bar.txt [l=text|csv]\n";

// controllo parametri
if ($SOFTWARE == "") exit("ERRORE: manca un parametro essenziale.\n\n".$HELP);

// apre il file in sola lettura
$handle = fopen($FILE, "r") or exit("ERRORE: file non trovato.\n\n".$HELP);

// interfaccia
if ($LISTALL != "csv") {
  echo $VER."\n\n".
       " File     = ".$FILE."\n".
       " Software = ".$SOFTWARE."\n\n";
}

// legge il file e compila la tabella
while (!feof($handle)) {
   $buffer = fgets($handle, 4096);
   if (ereg($TIME_TAG, $buffer, $regs)) $date = $regs[2]."/".$regs[1]."/".$regs[3];

   if (ereg($HOST_TAG, $buffer, $regs)) {
     $tmp = split("\.", trim($regs[2]));
     $host = $tmp[0];
     $find[$host]["date"] = $date;
     $find[$host]["status"] = FALSE;
   }

   if (ereg($NAME_TAG, $buffer, $regs)) $find[$host]["name"] = trim($regs[2]);
   if (strpos($buffer, $SOFTWARE)) $find[$host]["status"] = TRUE;
}

// chiude il file
fclose($handle);

// conta
foreach ($find as $pc) if ($pc["status"]) $y++ ;
$a = count($find);
$b = (int)(($y*100/$a)+0.5);

if ($LISTALL == "") {
  echo " PC trovati:\t\t\t".$a."\n".
       " Software installato:\t\t".$y."\t(".$b."%)\n".
       " Software non installato:\t".($a-$y)."\t(".(100-$b)."%)\n\n";

} else if ($LISTALL == "text") {
  // scrive la tabella degli host
  ksort($find);
  $hosts = array_keys($find);

  echo "PC\tDATA\tNOME (DITTA)\tSOFTWARE\n";

  foreach ($hosts as $pc) {
      echo $pc."\t".
           $find[$pc]["date"]."\t".
           $find[$pc]["name"]."\t".
           ($find[$pc]["status"]?"installato":"NON INSTALLATO");
      echo "\n";
  } 
} elseif ($LISTALL == "csv") {
  //scrive solo gli hostname che hanno il software installato
  $tmp = "";
  ksort($find);
  $hosts = array_keys($find);

  foreach ($hosts as $pc)
    $tmp.=($find[$pc]["status"]?$pc.":".$find[$pc]["name"]." ":"");

  echo $SOFTWARE.",".$y.",".$tmp;
  echo "\n";
}

?>

Per ottenere una lista del software che è presente sulle macchine del dominio (eliminando software che è stato installato e poi rimosso) è sufficente ripetere l'esecuzione del software tante volte quanti sono i software; non è una soluzione ottimizzata, ma in ogni caso non impiega molto tempo: alcuni test hanno visto la procedura girare 1000 volte su input di 40MB in circa 5 ore. La seguente procedura (in BASH) ne è un esempio.

$ dos2unix software.txt
$ grep ^\"DisplayName software.txt | sort | uniq > nomi.txt
$ echo "#\!/bin/bash" > richieste.sh
$ gawk '{n = substr($0,15) ; print "php -f chiediSoftware.php s=" n " f=software.txt l=csv"}' < nomi.txt >> richieste.sh
$ sh richieste.sh > software_installato.csv

Dopo aver creato il file "nomi.txt" è possibile editarlo per eliminare software di cui non è necessario avere traccia, ad esempio gli aggiornamenti di Windows (in quanto il sistema operativo deve essere mantenuto sempre aggiornato).