Source for file wsus_getinfo.php

Documentation is available at wsus_getinfo.php

  1. #!/usr/bin/php
  2. <?php
  3. /**
  4.  * PHP version 5
  5.  *
  6.  * LICENSE: This program is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU General Public License as published
  8.  * by the Free Software Foundation.
  9.  *
  10.  * @package                     FreeNAC
  11.  * @author                      Hector Ortiz (FreeNAC Core Team)
  12.  * @copyright                   2006 FreeNAC
  13.  * @license                     http://www.gnu.org/copyleft/gpl.html   GNU Public License Version 2
  14.  * @version                     CVS: $Id:$
  15.  * @link                        http://www.freenac.net
  16.  *
  17.  */
  18.  
  19. /**
  20. * Retrieves information from the WSUS database and stored in local mysql
  21. * table.
  22. * Beta test with Wsus V2.???
  23. * Stable release v2.2 testted with Wusus version 3.???
  24. */
  25.  
  26. # Php weirdness: change to script dir, then look for includes
  27. chdir(dirname(__FILE__));
  28. set_include_path("../:./");
  29.  
  30. /**
  31. * Load settings and commong functions
  32. */
  33. require_once "./funcs.inc.php";     
  34.  
  35. $logger->setLogToStdOut();
  36. $output=true;
  37.  
  38. $verbose=FALSE;
  39.  
  40. /**
  41. * Simple parsing of command line parameters
  42. */
  43. for ($i=1;$i<$argc;$i++)
  44. {
  45.    switch($argv[$i])
  46.    {
  47.       case '-v':
  48.          {
  49.             $logger->setDebugLevel(1);
  50.             $verbose TRUE;
  51.          }
  52.          break;
  53.       case '-vv':
  54.          {
  55.             $logger->setDebugLevel(2);
  56.             $verbose TRUE;
  57.          }
  58.          break;
  59.       case '-s':$output FALSE;
  60.          break;
  61.       case '-h':
  62.       default:usage();
  63.          break;
  64.    }
  65. }
  66.  
  67. $timestamp=date('Y-m-d H:i:s');
  68. message("Program run on $timestamp",1);
  69.  
  70. /**
  71. * Prints script's usage
  72. */
  73. function usage()
  74. {
  75.    $logger->logit"Usage: wsus_getinfo [-h][-v[v]][-s]\n");
  76.    $logger->logit"\t-h\tShow this help screen\n");
  77.    $logger->logit"\t-v\tDebug level 1 enabled (output goes to stdout & syslog)\n");
  78.    $logger->logit"\t-vv\tDebug level 1 & 2 enabled (output goes to stdout & syslog)\n");
  79.    $logger->logit"\t-s\tSupress messages to standard output and redirect them to syslog\n");
  80.    exit(1);
  81. }
  82.  
  83. /**
  84. * Connect to the WSUS server
  85. */
  86. function dbwsus_connect()
  87. {
  88.    global $conf,$wsus_dbuser,$wsus_dbpass;
  89.    message("Connect to ".$conf->wsus_dbalias." ".$conf->wsus_db,1);
  90.    $msconnect mssql_connect($conf->wsus_dbalias$wsus_dbuser$wsus_dbpass);
  91.    if ($msconnect 
  92.    {
  93.      message("Cannot connect to WSUS server ".$conf->wsus_dbalias.":" mssql_get_last_message(),0);
  94.      return false;
  95.    }
  96.    $d mssql_select_db($conf->wsus_db$msconnect);
  97.    if ($d)
  98.    {
  99.       message("Couldn't open database ".$conf->wsus_db." ".mssql_get_last_message(),0);
  100.       return false;
  101.    }
  102.    return true;
  103. }
  104.  
  105. /**
  106. * Ensures that $string is mysql safe
  107. */
  108. function validate($string)
  109. {
  110.    rtrim($string,' ');
  111.    if (get_magic_quotes_gpc()) {
  112.       $value=stripslashes($string);
  113.    }
  114.    if (!is_numeric($string)) {
  115.       $stringmysql_real_escape_string($string);
  116.    }
  117.    return $string;
  118. }
  119.  
  120. /**
  121. * Executes query and displays error message if any
  122. */
  123. function execute_query($query)
  124. {
  125.    db_connect();
  126.    $res=mysql_query($query);
  127.    if (!$res)
  128.    
  129.       message("Cannot execute query $query because ".mysql_error(),2);
  130.       return false;
  131.    }
  132.    return $res;
  133. }
  134.  
  135. /**
  136. *  This function converts the datetime retrieved from MSSQL into MySQL datetime format
  137. */
  138. function convert_date($date)
  139. {
  140.    $date_array=getdate(strtotime($date));
  141.    $date=$date_array['year'].'-';
  142.    $date_array['mon'10 $date.='0'.$date_array['mon'].'-' $date.=$date_array['mon'].'-';
  143.    $date_array['mday'10 $date.='0'.$date_array['mday'].' ' $date.=$date_array['mday'].' ';
  144.    $date_array['hours'10 $date.='0'.$date_array['hours'].':' $date.=$date_array['hours'].':';
  145.    $date_array['minutes'10 $date.='0'.$date_array['minutes'].':' $date.=$date_array['minutes'].':';
  146.    $date_array['seconds'10 $date.='0'.$date_array['seconds'$date.=$date_array['seconds'];
  147.    return $date;
  148. }
  149.  
  150. /**
  151. * Dumps the tbComputerTarget table into our computertarget tabl
  152. */
  153. {
  154.    message("Function wsus_dump_computertarget",1);
  155.    db_connect();
  156.    if (dbwsus_connect())
  157.    {
  158.       #This query is for WSUS 2.X
  159.       #$query="select TargetID,IPAddress,FullDomainName,OSMajorVersion,OSMinorVersion,OSBuildNumber,OSServicePackMajorNumber,OSServicePackMinorNumber,OSLocale,ComputerMake,ComputerModel,BiosVersion,BiosName,BiosReleaseDate,ProcessorArchitecture from tbComputerTarget";
  160.       #This query is for WSUS 3.0
  161.       $query="select ct.TargetID, ct.IPAddress, ct.FullDomainName, td.OSMajorVersion, td.OSMinorVersion, td.OSBuildNumber, td.OSServicePackMajorNumber, td.OSServicePackMinorNumber, td.OSLocale, td.ComputerMake, td.ComputerModel, td.BiosVersion, td.BiosName, td.BiosReleaseDate, td.ProcessorArchitecture from tbComputerTarget as ct, tbcomputertargetdetail as td where ct.targetID=td.targetID";
  162.       message("Executing: ".$query,2);
  163.       $res=mssql_fetch_all($query);
  164.       foreach ($res as $row)
  165.       {
  166.      $old_date=$row[BiosReleaseDate];
  167.      $temp=explode('.',$row[FullDomainName]);
  168.          $row[FullDomainName]=$temp[0];
  169.          $row[BiosReleaseDate]=convert_date($row[BiosReleaseDate]);
  170.          message("Converted $old_date into ".$row[BiosReleaseDate]." for ".$row[FullDomainName],1);
  171.          $row[OSLocale]=substr($row[OSLocale],0,2);
  172.          $osid=wsus_get_osid($row[OSMajorVersion],$row[OSMinorVersion],$row[OSBuildNumber],$row[OSServicePackMajorNumber],$row[OSServicePackMinorNumber],$row[ProcessorArchitecture]);
  173.          $query=sprintf("insert into nac_wsuscomputertarget (TargetID, IPAddress, FullDomainName, OSid, OSLocale, ComputerMake, ComputerModel, BiosVersion, BiosName, BiosReleaseDate) values ('%s','%s','%s','%s','%s','%s','%s','%s','%s','%s') on duplicate key update datetime=NOW();"validate($row[TargetID])validate($row[IPAddress])validate($row[FullDomainName])validate($osid)validate($row[OSLocale])validate($row[ComputerMake])validate($row[ComputerModel])validate($row[BiosVersion])validate($row[BiosName])validate($row[BiosReleaseDate]));
  174.          message("Executing: ".$query,2);
  175.          execute_query($query);
  176.       }
  177.       return true;
  178.    }
  179.    else return false;
  180. }
  181.  
  182. /**
  183. * Dumps table tbOSMap into our osmap table
  184. */
  185. function wsus_dump_osmap(
  186. {
  187.    message("Function wsus_dump_osmap",1);
  188.    if (dbwsus_connect())
  189.    {
  190.       $query="select * from tbOSMap";
  191.       message("Executing: ".$query,2);
  192.       $res=mssql_fetch_all($query);
  193.       db_connect();
  194.       $query='delete from nac_wsusosmap'//Delete everything we previosuly had.
  195.       message("Executing: ".$query,2);
  196.       execute_query($query);
  197.       foreach ($res as $row)
  198.       {
  199.          $query=sprintf("insert into nac_wsusosmap values ('%s','%s','%s','%s','%s','%s','%s','%s','%s');"$row[OSid]$row[OSMajorVersion]$row[OSMinorVersion]$row[OSBuildNumber]$row[OSServicePackMajorNumber]$row[OSServicePackMinorNumber]$row[ProcessorArchitecture],validate($row[OSShortName]),validate($row[OSLongName]));
  200.          message("Executing: ".$query,2);
  201.          execute_query($query);
  202.       }
  203.       return true;
  204.    }
  205.    else return false;
  206. }
  207.  
  208. /**
  209. * Get the OSID
  210. */
  211. function wsus_get_osid($majv,$minv,$build,$spmaj,$spmin,$processor)
  212. {
  213.    message("Function wsus_getosid",1);
  214.    db_connect();
  215.    $query="select pid from nac_wsusprocessor where ProcessorArchitecture='$processor';";
  216.    message("Executing: ".$query,2);
  217.    $my_res=execute_query($query);
  218.    if ($my_res)
  219.    {
  220.       $my_result=mysql_fetch_array($my_res,MYSQL_ASSOC);
  221.       if (dbwsus_connect())
  222.       {
  223.          $query=sprintf("select osid from tbosmap where osmajorversion='%s' and osminorversion='%s' and osbuildnumber='%s' and osservicepackmajornumber='%s' and osservicepackminornumber='%s' and processorarchitecture='%s'",$majv,$minv,$build,$spmaj,$spmin,$my_result['pid']);
  224.          message("Executing: ".$query,2);
  225.          $ms_res=mssql_fetch_all($query);
  226.          if ($ms_res)
  227.          {
  228.             foreach($ms_res as $row)
  229.             {
  230.                $result=$row[osid];   
  231.             }         
  232.          
  233.       }
  234.       return $result;
  235.    }
  236.    else return false;
  237. }
  238.  
  239. /**
  240. * Retrieves the installed and needed updates for computer identified by id
  241. */
  242. {
  243.    message("Function wsus_get_updates_per_computer for $id",1);
  244.    if (dbwsus_connect())
  245.    {
  246.       #Query for WSUS 2.X
  247.       #$query="select SummarizationState, UpdateID, LastChangeTime, LastRefreshTime from tbUpdateStatusPerComputer where TargetID='$id' and SummarizationState=4 order by id asc"; #Installed updates
  248.       #Query for WSUS 3.0
  249.       $query="select SummarizationState, LocalUpdateID, LastChangeTime, LastRefreshTime from tbUpdateStatusPerComputer where TargetID='$id' and SummarizationState=4 order by LocalUpdateID asc"#Installed updates
  250.       message("Executing: ".$query,2);
  251.       $installed=mssql_fetch_all($query);
  252.       if ($installed)
  253.       {
  254.          db_connect();
  255.          $query="delete from nac_wsusupdatestatuspercomputer where TargetID='$id' and SummarizationState='4';";
  256.          message("Executing: ".$query,2);
  257.          execute_query($query);
  258.          foreach($installed as $row)
  259.          {
  260.             #Query for WSUS 2.X
  261.             #$query=sprintf("insert into nac_wsusupdatestatuspercomputer values('%s','%s','%s','%s','%s');",validate($row[SummarizationState]),validate(mssql_guid_string($row[UpdateID])),validate($id),validate(convert_date($row[LastChangeTime])),validate(convert_date($row[LastRefreshTime])));
  262.             #Query for WSUS 3.0
  263.             $query=sprintf("insert into nac_wsusupdatestatuspercomputer values('%s','%s','%s','%s','%s');",validate($row[SummarizationState]),validate($row[LocalUpdateID]),validate($id),validate(convert_date($row[LastChangeTime])),validate(convert_date($row[LastRefreshTime])));
  264.             message("Executing: ".$query,2);
  265.             execute_query($query);
  266.          }
  267.       }
  268.       #Query for WSUS 2.x
  269.       #$query="select SummarizationState, UpdateID, LastChangeTime, LastRefreshTime from tbUpdateStatusPerComputer where TargetID='$id' and SummarizationState='6' order by id asc";#Needed updates
  270.       #Query for WSUS 3.0
  271.       $query="select SummarizationState, LocalUpdateID, LastChangeTime, LastRefreshTime from tbUpdateStatusPerComputer where TargetID='$id' and SummarizationState=4 order by LocalUpdateID asc"#Installed updates
  272.       message("Executing: ".$query,2);
  273.       $needed=mssql_fetch_all($query);
  274.       if ($needed)
  275.       {
  276.          db_connect();
  277.          $query="delete from nac_wsusupdatestatuspercomputer where targetID='$id' and SummarizationState='6';";
  278.          message("Executing: ".$query,2);
  279.          execute_query($query);
  280.          $i=0;
  281.          foreach($needed as $row)
  282.          {
  283.             #Query for WSUS 2.X
  284.             #$query=sprintf("insert into nac_wsusupdatestatuspercomputer values('%s','%s','%s','%s','%s');",validate($row[SummarizationState]),validate(mssql_guid_string($row[UpdateID])),validate($id),validate(convert_date($row[LastChangeTime])),validate(convert_date($row[LastRefreshTime])));
  285.             #Query for WSUS 3.0
  286.             $query=sprintf("insert into nac_wsusupdatestatuspercomputer values('%s','%s','%s','%s','%s');",validate($row[SummarizationState]),validate($row[LocalUpdateID]),validate($id),validate(convert_date($row[LastChangeTime])),validate(convert_date($row[LastRefreshTime])));
  287.             message("Executing: ".$query,2);
  288.             execute_query($query);
  289.          }
  290.       }
  291.       #Query for WSUS 3.0
  292.       $query="select LastSyncTime  from tbcomputertarget where TargetID='$id';";
  293.       message("Executing: ".$query,2);
  294.       $result=mssql_fetch_all($query);
  295.       if ($result)
  296.       {
  297.          foreach($result as $row)
  298.          {
  299.             $lastsynctime=validate(convert_date($row[LastSyncTime]));
  300.             $query="update nac_wsuscomputertarget set LastSyncTime='$lastsynctime' where targetid='$id';";
  301.             message("Executing: ".$query,2);
  302.             execute_query($query);  
  303.          }
  304.       }
  305.       return true;
  306.    }
  307.    else return false;
  308. }
  309.  
  310. /**
  311. * This one retrieves the installed and needed updates for every computer
  312. */
  313. {
  314.    message("Function wsus_dump_updates_for_computers",1);
  315.    db_connect();
  316.    $query="select TargetID from nac_wsuscomputertarget;";
  317.    message("Executing: ".$query,2);
  318.    $my_res=execute_query($query);
  319.    if ($my_res)
  320.    {
  321.       while ($row=mysql_fetch_array($my_res,MYSQL_ASSOC))
  322.       {
  323.          wsus_get_updates_per_computer($row['TargetID']);
  324.       }
  325.       return true;
  326.    }
  327.    return false;
  328. }
  329.  
  330. /**
  331. * Connect data from WSUS with the data stored in the systems table
  332. */
  333. function connect_data()
  334. {
  335.    db_connect();
  336.    $query="select id,name from systems";
  337.    message("Executing: ".$query,2);
  338.    $my_res=execute_query($query);
  339.    if ($my_res)
  340.    {
  341.       while ($row=mysql_fetch_array($my_res,MYSQL_ASSOC))
  342.       {
  343.          if ((!empty($row['name']))&&(strcasecmp($row['name'],'unknown')!=0))
  344.          {
  345.             $query="update nac_wsuscomputertarget set sid=".$row['id']." where FullDomainName like '".$row['name']."'";
  346.             message("Executing: ".$query,2);
  347.             execute_query($query);
  348.             if (mysql_affected_rows()==1)
  349.                message("Updated patch information for host {$row['name']}",0);
  350.             else if (mysql_affected_rows()>1)
  351.                message("Possible duplicates in database for host {$row['name']}",0);
  352.          }
  353.          else
  354.             continue;
  355.       }
  356.       return true;
  357.    }
  358.    else
  359.       return false;
  360. }
  361.  
  362. /**
  363. * Get a list of updates available on the server
  364. */
  365. function wsus_dump_updates()
  366. {
  367.    global $wsus_language;
  368.    message("Function wsus_dump_updates",1);
  369.    if (dbwsus_connect(&& $wsus_language)
  370.    {
  371.       $query="select u.localupdateid as LocalID,u.updateid as UpdateID,pre.title as Title,kb.kbarticleid as Article from tbprecomputedlocalizedproperty pre, tbkbarticleforrevision kb, tbupdate u where pre.updateid=u.updateid and pre.revisionid=kb.revisionid and pre.shortlanguage='$wsus_language' order by (kb.revisionid) asc";
  372.       message("Executing: ".$query,2);
  373.       $ms_res=mssql_fetch_all($query);
  374.       if ($ms_res)
  375.       {
  376.          db_connect();
  377.          /*$query='delete from nac_wsusupdate;';
  378.          message("Executing: ".$query,2);
  379.          execute_query($query);*/
  380.          foreach($ms_res as $row)
  381.          {
  382.             $updateid=mssql_guid_string($row[UpdateID]);
  383.             $query=sprintf("insert into nac_wsusupdate values('%s','%s','%s','%s') on duplicate key update UpdateID='%s';",validate($row[LocalID]),validate($updateid),validate($row[Title]),validate($row[Article]),validate($updateid));
  384.             message("Executing: ".$query,2);
  385.             execute_query($query);
  386.          }
  387.          return true;
  388.       }
  389.       else
  390.          return false;
  391.    }
  392.    else return false;
  393. }
  394.  
  395. /**
  396. * Print a message
  397. */
  398. function message($string,$level)
  399. {
  400.    global $output,$logger;
  401.    
  402.    if ($level==0)
  403.    {
  404.       if ($output)
  405.       {
  406.          $logger->setLogToStdOut();
  407.          $logger->logit("$string");
  408.       }
  409.       else
  410.       {
  411.          $logger->setLogToStdOut(false);
  412.          $logger->logit($string);
  413.       }
  414.    }
  415.    if ($level==1)
  416.    {
  417.       if ($logger->getDebugLevel())
  418.       {
  419.          $logger->debug($string,1);
  420.          if ($output)
  421.          {
  422.             $logger->setLogToStdOut();
  423.             $logger->logit("$string");
  424.          }
  425.       }
  426.    }
  427.    if ($level==2)
  428.    {
  429.       if ($logger->getDebugLevel())
  430.       {
  431.          $logger->debug($string,2);
  432.          if ($output)
  433.          {
  434.             $logger->setLogToStdOut();
  435.             $logger->logit("$string");
  436.          }
  437.       }
  438.    }
  439.    return true;
  440. }
  441.  
  442. $wsus_language='en';
  443. $enabled=v_sql_1_select("select value from config where name='wsus_enabled'");
  444. if ($enabled)
  445. {
  446.    message("Dumping remote table tbOSmap into our osmap table.",0);
  447.    if (wsus_dump_osmap())
  448.    {
  449.       message("Dumping patches available on the server",0);
  450.       if (wsus_dump_updates())
  451.       {
  452.          message("Dumping remote table tbComputerTarget into our computertarget table.",0);
  453.          if (wsus_dump_computertarget())
  454.          {
  455.             message("Retrieving patch information for computers.",0);
  456.             if (wsus_dump_updates_for_computers())
  457.             {
  458.                message("Connecting information from WSUS to the systems table.",0);
  459.            if (connect_data())
  460.                {
  461.                   message("Done!",0);
  462.                   logit("WSUS synchronization was successful.");
  463.                   log2db('info',"WSUS synchronization was successful.");
  464.                   exit(0);
  465.                }
  466.                else message("Function connect_data failed.",0);
  467.             }
  468.             else message("Function wsus_dump_updates_for_computers failed.",0);
  469.          }
  470.          else message("Function wsus_dump_computertarget failed.",0);
  471.       }
  472.       else message("Function wsus_dump_updates failed.",0);
  473.    }
  474.    else message("Function wsus_dump_osmap failed.",0);
  475.    logit("WSUS synchronization failed.");
  476.    log2db('err',"WSUS synchronization failed.");
  477.    exit(1);
  478. }
  479. else
  480.    message("This function is not enabled",0);
  481.    exit(1);
  482. }
  483.