Ad Widget

Collapse

Host inventory as it should be (cpuz integration)

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • mmarkwitzz
    Senior Member
    • Jan 2011
    • 106

    #1

    Host inventory as it should be (cpuz integration)

    This script is based on zabbix 2.0 automatic host inventory and on CPU-Z hardware information application

    The template included uses active checks. Your zabbix agent must be configured for active checks otherwise the server won't receive any data.

    Many thanks to CPUID for creating and keeping cpuz as freeware

    Description

    The intended usage of this solution is to tune-up the zabbix host inventory capabilities and turn it into something useful. By default zabbix only allows text fields that can only hold a small amount of information and are damn hard to read.

    This solutions uses a host script and some hacks in the frontend phps to allow for tables to be displayed. It also makes use of both WMI and cpuz to extract the most relevant information from the host. The following fields are automatically filled by the template:

    Name: fqdn name of the host
    OS: full name, version, edition of the os and bitness
    Hardware (full details): motherboard and bios info, processors info, ram memory info, disks info, volumes info, virtualization roles (h-v supported for now)
    Software (full details): installed software (add/remove list), installed roles/services (2008), installed components (2000/2003), active directory roles
    Host networks: network adapters info, routing table, persistent routes



    This is an example of the type of host information I get now:





    Usage

    Download the archive, extract the XML template, import it into the frontend and link the hosts to it. Make sure all hosts are configured with "automatic" host inventory. Download both the x86 and x64 versions of the cpuz application (the zips without installation) from their website and rename the executables to cpuz32.exe and cpuz64.exe.

    Copy the vbs scripts and the two cpu-z executables to your zabbix agent folder and configure the following line in your zabbix_agentd.conf file, replacing the path in the UserParameter with your zabbix agent installation path, restart the agent.

    Code:
    #inventory 
    UserParameter = inventory[*],cscript "C:\Program Files\Zabbix agent\zabbix_inv_inventory.vbs" //Nologo "$1" "$2" "$3"
    SSH to your zabbix server and make the following changes to these files:
    • Edit /var/www/html/include/classes/class.ctag.php
    • Search for addItem function
    • Comment the line $value = $this->encode(..)

    • Edit the /var/www/html/include/forms.inc.php
    • Search for insert_host_inventory_form function
    • Copy the line $frmHostP->addRow(...) and comment the original
    • Delete the 'pre' argument from the copied line (delete the comma also)


    Optionally, add the following URL to each host in maps: http://zabbix.company.com/hostinventories.php?hostid={HOST.ID} replacing the zabbix.company.com placeholder with your actuall zabbix server address.

    Gotchas

    The first php file edit is to disable html parsing. This enables the browser to interpret html code literally so we can show tables in the host inventory screen. This is a dirty hack that is applied globally.

    If you have some php skills you can easily modify the CForms classes to disable html parsing only for the hosts inventory screen.

    The second php edit is to disable the <pre> tag which turns everything between them into plain text. This enables the browser to interpret html code literally so we can show tables in the host inventory screen.

    On the first poll, the INV Software and INV Hardware items may receive empty strings. This is normal (details below). To have instant data, just restart the agent again after 2 minutes.

    The tables appear empty when using the "black and blue" theme. This is due to my awesome css skills and hopefully a temporary issue. Switch to the default theme and all will be well.

    If you have any issues importing this template, please upgrade to zabbix 2.0.1 and php 5.3 or higher.

    Update 1

    Added windows 2000/2003 installed components to software inventory. Make sure you reimport the template.



    Moved software and hardware querying out of process because querying the system could often take longer than 30 seconds, causing the agent to kill the script and return nothing. When zabbix agent receives a request to poll the INV OOP item it starts the zabbix_inv_inventory.vbs script that proceeds to do the following:

    Launches zabbix_vbs_logger.vbs with some parameters that tells it to re-execute zabbix_inv_inventory.vbs, attach to the output stream and save everything in the zabbix_inv_inventory.log file.
    The logger is launched using wmiprvse.exe, escaping the job object of the zabbix agent. This means that when the initial zabbix_inv_inventory.vbs terminates, the logger survives (it would normally be terminated as part of the job object), queries the system for software and hardware information and saves them to a file.

    When zabbix agent receives a request to poll the INV Hardware or INV Software items, it attempts to read the saved file and return the read data. If the saved file does not exist yet, no data is sent. But from the second poll forwards, the file exists and the contents are sent.

    This means you always have a maximum of 12 hours delay between the actual querying of the system and the zabbix server getting the data. This may sound bad but it's the only way I can guarantee that the script is not killed because of timeout. If the delay is too big for your taste just edit the interval for the following INV Software, INV Hardware and INV OOP items.

    Update 2

    CSS Styles are now returned only once, in the INV CSS table styles item which maps to the Secondary POC notes inventory field. Previously css styles were returned in each of the items/fields together with the actual table html data. It seems that the inventory fields have some length restrictions and this should make the strings shorter.

    Don't forget to reimport the template. Do restart your zabbix agent twice (with 2 minutes delay in between) to make sure the server gets the latest data immediately.
    Attached Files
    Last edited by mmarkwitzz; 05-07-2012, 14:26.
  • HullZabbix
    Senior Member
    • Feb 2011
    • 104

    #2
    Great idea using cpuz. I wish I thought of this before writing customised vbs scripts!

    I made a post in this thread with my way of doing it:


    The only advantage my way has, is that the host inventory overview screen is quite clear.



    Though I did need to edit the inventory php to customise the columns. (got rid of mac address etc.)

    I'm curious as to how it will look with your method.

    I did write several vbs scripts to get specific info if anyone is interested

    BIOS:
    Code:
    On Error Resume Next
    
    strComputer = "."
    Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
    Set colBIOSItems = objWMIService.ExecQuery("Select * from Win32_BIOS")
    
    For Each objItem in colBIOSItems
    	stringBIOS = objItem.Manufacturer & vbcrlf & "Name: " & objItem.Name & vbcrlf
    	Next
    	
    Wscript.Echo stringBIOS
    CPU:
    Code:
    On Error Resume Next
    
    strComputer = "."
    Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
    Set colCPUItems = objWMIService.ExecQuery("Select * from Win32_Processor")
    
    For Each objItem in colCPUItems
    	StringCPU = objItem.Name & vbcrlf & "Socket Designation: " & objItem.SocketDesignation & vbcrlf & "Current Clock Speed: " & objItem.CurrentClockSpeed & vbcrlf & "L2 Cache Size: " & objItem.L2CacheSize & vbcrlf & "Ext Clock: " & objItem.ExtClock & vbcrlf
    	Next
    	
    Wscript.Echo stringCPU
    GFX:
    Code:
    On Error Resume Next
    
    strComputer = "."
    Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
    Set colGFXItems = objWMIService.ExecQuery("Select * from Win32_VideoController")
    
    For Each objItem in colGFXItems
    	stringGFX = objItem.Description & vbcrlf & "Adapter RAM: " & (objItem.AdapterRAM / 1048576) & "MB" & vbcrlf & "Driver Date: " & objItem.DriverDate & vbcrlf & "Driver Version: " & objItem.DriverVersion & vbcrlf & "Video Mode Description: " & objItem.VideoModeDescription & vbcrlf
    	Next
    	
    Wscript.Echo stringGFX
    HD:
    Code:
    On Error Resume Next
    
    strComputer = "."
    Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
    Set colHDItems = objWMIService.ExecQuery("Select * from Win32_DiskDrive")
    
    numberOfDisks = -1
    For Each objItem in ColHDItems
    	numberOfDisks = numberOfDisks + 1
    	Next
    Dim myArray()
    reDim myArray(numberOfDisks)
    j = 0
    
    For Each objItem in colHDItems
    	myArray(j) = "HD" & j & "" & vbcrlf & objItem.Model & vbcrlf & "Size: " & FormatNumber((objItem.Size/1000000000), 0) & "GB" & vbcrlf & "Interface: " & objItem.InterfaceType & vbcrlf & "Media Type: " & objItem.MediaType & vbcrlf & "Partitions: " & objItem.Partitions & vbcrlf
    	j = j + 1
    	Next
    	
    Wscript.Echo Join(myArray,vbcrfl)
    MB:
    Code:
    On Error Resume Next
    
    strComputer = "."
    Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
    Set colMBItems = objWMIService.ExecQuery("Select * from Win32_BaseBoard")
    
    For Each objItem in colMBItems
    	stringMB = objItem.Manufacturer & vbcrlf & "Model: " & objItem.Model & vbcrlf & "Part Number: " & objItem.PartNumber & vbcrlf & "Product: " & objItem.Product & vbcrlf & "Serial Number: " & objItem.SerialNumber & vbcrlf & "Version: " & objItem.Version & vbcrlf
    	Next
    	
    Wscript.Echo stringMB
    OS:
    Code:
    On Error Resume Next
    
    strComputer = "."
    Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
    Set colOSItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
    
    Set WshShell = WScript.CreateObject("WScript.Shell")
    Architecture = WshShell.RegRead("HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\PROCESSOR_ARCHITECTURE")
    
    If Architecture = "AMD64" Then
       OSArchitecture = "64-bit"
    ElseIf Architecture = "x86" Then
       OSArchitecture =  "32-bit"
    End If
    
    For Each objItem in colOSItems
    	stringOS = objItem.Caption & " " & objItem.Version & " " & OSArchitecture
    	Next	
    
    Wscript.Echo stringOS
    RAM:
    Code:
    On Error Resume Next
    
    strComputer = "."
    Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
    set colMEMItems = objWMIService.ExecQuery("Select * from Win32_PhysicalMemory")
    Set colMEMAItems = objWMIService.ExecQuery("Select * from Win32_PhysicalMemoryArray")
    
    memType = array("Unknown","Other","DRAM","Synchronous DRAM","Cache DRAM","EDO","EDRAM","VRAM","SRAM","RAM","ROM","Flash","EEPROM","FEPROM","EPROM","CDRAM","3DRAM","SDRAM","SGRAM","RDRAM","DDR","DDR-2")
    memForm = array("Unknown","Other","SIP","DIP","ZIP","SOJ","Proprietary","SIMM","DIMM","TSOP","PGA","RIMM","SODIMM","SRIMM","SMD","SSMP","QFP","TQFP","SOIC","LCC","PLCC","BGA", "FPBGA","LGA")
    
    strMemory = ""
    i = 1
    For Each objItem In colMEMItems
    	if strMemory <> "" then strMemory = strMemory & vbcrlf
    	strMemory = strMemory &  "Bank" & i & " : " & (objItem.Capacity / 1048576) & "MB"
    	i = i + 1
    	memoryForm = memForm(objItem.FormFactor)
    	memoryType = memType(objItem.MemoryType)
    	memorySpeed = objItem.Speed
    	memoryTotal = memoryTotal + (objItem.Capacity / 1048576)
    	Next
    	installedModules = i - 1
    
    For Each objItem in colMEMAItems
    	totalSlots = objItem.MemoryDevices
    	stringMEM = memoryTotal & "MB " & memoryType & " " & memorySpeed & "MHz" & vbcrlf & "Form: " & memoryForm & vbcrlf & "Total Slots: " & totalSlots & vbcrlf & "Free Slots: " & (totalSlots - installedModules) & vbcrlf & strMemory & vbcrlf
    	Next
    
    Wscript.Echo stringMEM
    And finally a short script which is used for "hardware" the screenshot, this picks info I need and groups it so it's easily read.

    ShortHWFull:
    Code:
    On Error Resume Next
    
    strComputer = "."
    Set objWMIService = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
    Set colCPUItems = objWMIService.ExecQuery("Select * from Win32_Processor")
    set colMEMItems = objWMIService.ExecQuery("Select * from Win32_PhysicalMemory")
    Set colMEMAItems = objWMIService.ExecQuery("Select * from Win32_PhysicalMemoryArray")
    Set colHDItems = objWMIService.ExecQuery("Select * from Win32_DiskDrive")
    Set colGFXItems = objWMIService.ExecQuery("Select * from Win32_VideoController")
    Set colMBItems = objWMIService.ExecQuery("Select * from Win32_BaseBoard")
    Set colBIOSItems = objWMIService.ExecQuery("Select * from Win32_BIOS")
    
    
    For Each objItem in colCPUItems
    	StringCPU = "|| CPU: "& objItem.Name
    	Next
    	
    memType = array("Unknown","Other","DRAM","Synchronous DRAM","Cache DRAM","EDO","EDRAM","VRAM","SRAM","RAM","ROM","Flash","EEPROM","FEPROM","EPROM","CDRAM","3DRAM","SDRAM","SGRAM","RDRAM","DDR","DDR-2")
    memForm = array("Unknown","Other","SIP","DIP","ZIP","SOJ","Proprietary","SIMM","DIMM","TSOP","PGA","RIMM","SODIMM","SRIMM","SMD","SSMP","QFP","TQFP","SOIC","LCC","PLCC","BGA", "FPBGA","LGA")
    
    For Each objItem In colMEMItems
    	memoryType = memType(objItem.MemoryType)
    	memoryTotal = memoryTotal + (objItem.Capacity / 1048576)
    	Next
    
    For Each objItem in colMEMAItems
    	totalSlots = objItem.MemoryDevices
    	stringMEM = "|| RAM: " & memoryTotal & "MB " & memoryType
    	Next
    
    numberOfDisks = -1
    For Each objItem in ColHDItems
    	numberOfDisks = numberOfDisks + 1
    	Next
    Dim myArray()
    reDim myArray(numberOfDisks)
    j = 0
    
    For Each objItem in colHDItems
    	myArray(j) = "|| HD" & j & ": " & objItem.Model & " " & FormatNumber((objItem.Size/1000000000), 0) & "GB" & " " & objItem.InterfaceType & " "
    	j = j + 1
    	Next
    	
    For Each objItem in colGFXItems
    	stringGFX = "|| GFX: " & objItem.Description
    	Next
    	
    For Each objItem in colMBItems
    	stringMB = "|| MB: " & objItem.Manufacturer & " " & objItem.Product
    	Next
    
    For Each objItem in colBIOSItems
    	stringBIOS = "|| BIOS: " & objItem.Manufacturer & " " & objItem.Name
    	Next
    
    Wscript.Echo stringOS & vbcrlf & stringCPU & vbcrlf & stringMEM & vbcrlf & Join(myArray,vbcrfl) & vbcrlf & stringGFX & vbcrlf & stringMB & vbcrlf & stringBIOS

    Comment

    • mmarkwitzz
      Senior Member
      • Jan 2011
      • 106

      #3
      @AxidaZabbix

      I was going to use WMI initially, just like you did, but after getting no info on my MB I remembered that CPUz showed all info including the chipset and the RAM type/speed. So I decided to take the shortcut and use cpuz instead.

      I will check if WMI offers any additional info which cpuz does not using your scripts. Hope you are ok with that

      Comment

      • HullZabbix
        Senior Member
        • Feb 2011
        • 104

        #4
        Originally posted by mmarkwitzz
        @AxidaZabbix

        I will check if WMI offers any additional info which cpuz does not using your scripts. Hope you are ok with that
        Absolutely ok, I posted so people could use them

        Good luck

        Comment

        • tchjts1
          Senior Member
          • May 2008
          • 1605

          #5
          mmarkwitzz - That is a really useful mod.

          I tried applying this to 2.0 stable release. Under Inventory --> Host, I have the tables, but they are empty. Under Latest Data for the host, however, I see the tables with data populated in them.

          Any thoughts on why the data is not making it to the Inventory section?

          Comment

          • HullZabbix
            Senior Member
            • Feb 2011
            • 104

            #6
            Have you set the host to automatic inventory?

            Also, have you checked your item is set to populate the specific section of the inventory? As in this screenshot:

            Last edited by HullZabbix; 26-06-2012, 17:32.

            Comment

            • mmarkwitzz
              Senior Member
              • Jan 2011
              • 106

              #7
              Originally posted by tchjts1
              mmarkwitzz - That is a really useful mod.

              I tried applying this to 2.0 stable release. Under Inventory --> Host, I have the tables, but they are empty. Under Latest Data for the host, however, I see the tables with data populated in them.

              Any thoughts on why the data is not making it to the Inventory section?
              You should not have empty tables. The data is either complete or not there at all. The only reason I can think of for this happening is that the returned string exceeds the allowed length of the database table, and is cut short.
              This or some other rendering problem.

              Go in Configuration->Hosts->YourHost->Host Inventory for your test host and look at the actual values for the fields. If there is html code in there, try putting it in a html file and see how it looks.

              You could also try looking at the html page source for Inventory->Host and check the code with "inspect element" function from chrome.

              Comment

              • tchjts1
                Senior Member
                • May 2008
                • 1605

                #8
                Originally posted by AxidaZabbix
                Have you set the host to automatic inventory?

                Also, have you checked your item is set to populate the specific section of the inventory? As in this screenshot:

                Yes, those are set accordingly. The "Populates host inventory field" was already set when importing mmarkwitzz template.

                Comment

                • tchjts1
                  Senior Member
                  • May 2008
                  • 1605

                  #9
                  Originally posted by mmarkwitzz
                  You should not have empty tables. The data is either complete or not there at all. The only reason I can think of for this happening is that the returned string exceeds the allowed length of the database table, and is cut short.
                  This or some other rendering problem.

                  Go in Configuration->Hosts->YourHost->Host Inventory for your test host and look at the actual values for the fields. If there is html code in there, try putting it in a html file and see how it looks.

                  You could also try looking at the html page source for Inventory->Host and check the code with "inspect element" function from chrome.
                  The data actually loks great under "Latest Data" as well as being used in "Screens". It is just under Inventory --> Host where the tables are empty. Here is a partial screenshot from a screen I created. FWIW, this is being applied to 2.0.1rc1
                  Attached Files

                  Comment

                  • mmarkwitzz
                    Senior Member
                    • Jan 2011
                    • 106

                    #10
                    Can you post a screenshot from the Inventory->Hosts screen? And also the string values from the fields in Configuration->Hosts->YourHOst->Host inventory?


                    The fields in latest data/screens look ok because there is no length restriction on the item value. The data is intact.

                    The item data is then copied to the inventory fields which have length restrictions (some of them anyway). For example the "Software A" field can only be 50 chars or so in length. My guess is that one of the fields it too long and is cut short. And what happens to html code when cut short is unpredictable.

                    Post the data I asked for and I'll try my best to help you.

                    Comment

                    • tchjts1
                      Senior Member
                      • May 2008
                      • 1605

                      #11
                      Originally posted by mmarkwitzz
                      Can you post a screenshot from the Inventory->Hosts screen? And also the string values from the fields in Configuration->Hosts->YourHOst->Host inventory?


                      The fields in latest data/screens look ok because there is no length restriction on the item value. The data is intact.

                      The item data is then copied to the inventory fields which have length restrictions (some of them anyway). For example the "Software A" field can only be 50 chars or so in length. My guess is that one of the fields it too long and is cut short. And what happens to html code when cut short is unpredictable.

                      Post the data I asked for and I'll try my best to help you.
                      Screenshots are below. As an aside, there was no mention of what to do with the cpuz.ini file, so I simply placed it as-is in the zabbix folder where the executables reside.

                      Also maybe worth noting are the code changes that were made:

                      class.ctag.php
                      Code:
                      public function addItem($value) {
                                      // the string contents of an HTML tag should be properly encoded
                                      if (is_string($value)) {
                                      //      $value = $this->encode($value, $this->getEncStrategy());
                                      }
                      forms.inc.php
                      Code:
                       function insert_host_inventory_form(){
                                      $frmHostP = new CFormTable(_('Host Inventory'));
                      
                                      $table_titles = getHostInventories();
                                      $table_titles = zbx_toHash($table_titles, 'db_field');
                                      $sql_fields = implode(', ', array_keys($table_titles));
                      
                                      $sql = 'SELECT '.$sql_fields.' FROM host_inventory WHERE hostid='.$_REQUEST['hostid'];
                                      $result = DBselect($sql);
                      
                                      $row = DBfetch($result);
                                      foreach($row as $key => $value){
                                              if(!zbx_empty($value)){
                                      //              $frmHostP->addRow($table_titles[$key]['title'], new CSpan(zbx_str2links($value), 'pre'));
                                                      $frmHostP->addRow($table_titles[$key]['title'], new CSpan(zbx_str2links($value)));
                                              }
                      Attached Files

                      Comment

                      • mmarkwitzz
                        Senior Member
                        • Jan 2011
                        • 106

                        #12
                        OK, thank you for the info.
                        The cpuz.ini file is not even needed. The changes in the php files are ok, otherwise you would not get correct display in latest data.

                        I stand by my original through that it's a html rendering problem. This may sound silly but did you try selecting for text inside the tables? maybe it's the same color as the background.

                        Notice that in the screenshot you provided there is no hardware table. You should have the following fields (on the left): Name, OS, Hardware (full details), software (full details), host networks.
                        This tells me that the error happens when zabbix tries to copy the value of the INV Hardware item to the Hardware (full details) field of the host inventory. Then, when it tries to render the contents, the browser sees some broken html and tries to manage, rendering it wrong.

                        I need you to go to the Configuration->Hosts->lab...->Host Inventory and get me the value for hardware (full details) as in the screenshot. Also, do you have any other host that you can test with?

                        Comment

                        • mmarkwitzz
                          Senior Member
                          • Jan 2011
                          • 106

                          #13
                          @tchjts1

                          Try the updated template and script. I now return CSS styles in a sepparate item, instead of together with each of them. Details in the first post.

                          This will cause tables in "latest data" to be displayed without proper formatting.

                          Comment

                          • tchjts1
                            Senior Member
                            • May 2008
                            • 1605

                            #14
                            You were right about the text being the same color as the background - this happens when using the "black and blue" theme. I switched my theme back to "Original Blue" and was able to see the text as below.

                            As far as the hardware field not being populated, screenshot is attached. The configuration is as directed in your post... it simply is not pulling that data into the inventory. I will check your next post regarding CSS styles and see how that goes. I will also try and dig up another test host.

                            I appreciate your time and help... this is a worthwhile modification and will come in quite handy.

                            Jeff
                            Attached Files

                            Comment

                            • mmarkwitzz
                              Senior Member
                              • Jan 2011
                              • 106

                              #15
                              So my css skills finally came back to kick me in the ass Glad we managed to sort this out finally.

                              About the hardware field not populating.. First try to restart zabbix agent, maybe the data was processed but not sent to the server. Second, open the zabbix_inv_inventory.log on your host and look for any errors. My bet is that the script encounters an error during hardware quering.

                              I did test the script on 5 machines with different configurations but it's not perfect. Give me the error details and i'll try to improve it.

                              Alex

                              Comment

                              Working...