Changeset fb8241a in nscp for modules/CheckWMI/CheckWMI.cpp


Ignore:
Timestamp:
03/09/12 00:14:39 (15 months ago)
Author:
Michael Medin <michael@…>
Branches:
master, 0.4.0, 0.4.1, 0.4.2
Children:
c88cf98
Parents:
29655a1
Message:
  • Major improvements to the WMI command line syntax. You can now: list namespaces, list classes, list instances as well as run queries. Means you can use NSClient++ as a almost full featured WMI command line client. For details use: nscp wmi --help
File:
1 edited

Legend:

Unmodified
Added
Removed
  • modules/CheckWMI/CheckWMI.cpp

    r29655a1 rfb8241a  
    127127} 
    128128 
    129  
     129std::wstring build_namespace(std::wstring ns, std::wstring computer) { 
     130  if (ns.empty()) 
     131    ns = _T("root\\cimv2"); 
     132  if (!computer.empty()) 
     133    ns = _T("\\\\") + computer + _T("\\") + ns; 
     134  return ns; 
     135} 
    130136#define MAP_CHAINED_FILTER(value, obj) \ 
    131137      else if (p__.first.length() > 8 && p__.first.substr(1,6) == _T("filter") && p__.first.substr(7,1) == _T("-") && p__.first.substr(8) == value) { \ 
     
    207213  try { 
    208214    WMIQuery wmiQuery; 
     215    ns = build_namespace(ns, target_info.hostname); 
    209216    NSC_DEBUG_MSG_STD(_T("Running query: '") + query + _T("' on: ") + ns + _T(" with ") + target_info.to_wstring()); 
    210     if (!target_info.hostname.empty()) 
    211       ns = _T("\\\\") + target_info.hostname + _T("\\") + ns; 
    212217    rows = wmiQuery.execute(ns, query, target_info.username, target_info.password); 
    213218  } catch (WMIException e) { 
     
    310315  WMIQuery::result_type rows; 
    311316  try { 
    312     if (!target_info.hostname.empty()) 
    313       ns = _T("\\\\") + target_info.hostname + _T("\\") + ns; 
    314  
     317    ns = build_namespace(ns, target_info.hostname); 
    315318    NSC_DEBUG_MSG_STD(_T("Running query: '") + query + _T("' on: ") + ns + _T(" with ") + target_info.to_wstring()); 
    316319    WMIQuery wmiQuery; 
     
    369372} 
    370373 
     374struct pad_handler { 
     375  std::vector<std::wstring::size_type> widths; 
     376  int index; 
     377  pad_handler() : index(0) {} 
     378  void reset_index() { 
     379    index = 0; 
     380  } 
     381  void set_next(std::wstring::size_type size) { 
     382    set(index++, size); 
     383  } 
     384  void set(int col, std::wstring::size_type size) { 
     385    if (col >= widths.size()) 
     386      widths.resize(col+20, 0); 
     387    widths[col] = max(widths[col], size); 
     388  } 
     389  std::wstring pad_next(std::wstring str, wchar_t c = L' ') { 
     390    return pad(index++, str, c); 
     391  } 
     392  std::wstring pad_current(std::wstring str, wchar_t c = L' ') { 
     393    return pad(index, str, c); 
     394  } 
     395  std::wstring pad(int col, std::wstring str, wchar_t c = L' ') const { 
     396    std::wstring::size_type w = 0; 
     397    if (widths.size() > col) 
     398      w = widths[col]; 
     399    if (w > str.size()) 
     400      w -= str.size(); 
     401    else 
     402      w = 0; 
     403    return std::wstring(1, c) + str + std::wstring(w+1, c); 
     404  } 
     405 
     406}; 
     407void print_results(WMIQuery::result_type &rows, int limit, std::wstring & result)  
     408{ 
     409  pad_handler padder; 
     410  NSC_DEBUG_MSG_STD(_T("Query returned: ") + strEx::itos(rows.size()) + _T(" rows.")); 
     411  std::vector<std::wstring::size_type> widths; 
     412  int rownum=0; 
     413  BOOST_FOREACH(const WMIQuery::wmi_row &row, rows) { 
     414    if (rownum++ == 0) { 
     415      padder.reset_index(); 
     416      BOOST_FOREACH(const WMIQuery::wmi_row::list_type::value_type &val, row.results) { 
     417        padder.set_next(val.first.length()); 
     418      } 
     419    } 
     420    if (limit != -1 && rownum > limit) 
     421      break; 
     422    padder.reset_index(); 
     423    BOOST_FOREACH(const WMIQuery::wmi_row::list_type::value_type &val, row.results) { 
     424      padder.set_next(val.second.string.length()); 
     425    } 
     426  } 
     427  rownum=0; 
     428  BOOST_FOREACH(const WMIQuery::wmi_row &row, rows) { 
     429    if (rownum++ == 0) { 
     430      std::wstring row1 = _T("|"); 
     431      std::wstring row2 = _T("|"); 
     432      padder.reset_index(); 
     433      BOOST_FOREACH(const WMIQuery::wmi_row::list_type::value_type &val, row.results) { 
     434        row1 += padder.pad_current(val.first) + _T("|"); 
     435        row2 += padder.pad_next(_T(""), L'-') + _T("|"); 
     436      } 
     437      result += row1 + _T("\n"); 
     438      result += row2 + _T("\n"); 
     439    } 
     440 
     441    if (limit != -1 && rownum > limit) 
     442      break; 
     443    int i=0; 
     444    std::wstring row1 = _T("|"); 
     445    padder.reset_index(); 
     446    BOOST_FOREACH(const WMIQuery::wmi_row::list_type::value_type &val, row.results) { 
     447      row1 += padder.pad_next(val.second.string) + _T("|"); 
     448    } 
     449    result += row1 + _T("\n"); 
     450  } 
     451} 
    371452 
    372453NSCAPI::nagiosReturn CheckWMI::handleCommand(const std::wstring &target, const std::wstring &command, std::list<std::wstring> &arguments, std::wstring &message, std::wstring &perf) { 
     
    378459  return NSCAPI::returnIgnored; 
    379460} 
     461 
     462void list_ns_rec(std::wstring ns, std::wstring user, std::wstring password, std::wstring &result) { 
     463  try { 
     464    WMIQuery wmiQuery; 
     465    WMIQuery::result_type rows = wmiQuery.get_instances(ns, _T("__Namespace"), user, password); 
     466    BOOST_FOREACH(WMIQuery::wmi_row &row, rows) { 
     467      const WMIQuery::WMIResult &res = row.results[std::wstring(_T("Name"))]; 
     468      //const WMIQuery::wmi_row::list_type::value_type v = row.results[_T("Name")]; 
     469      std::wstring name = res.string; 
     470      result += ns + _T("\\") + name + _T("\n"); 
     471      list_ns_rec(ns + _T("\\") + name, user, password, result); 
     472    } 
     473  } catch (WMIException e) { 
     474    NSC_LOG_ERROR_STD(_T("WMIQuery failed: ") + e.getMessage()); 
     475    result += _T("ERROR: ") + e.getMessage(); 
     476  } 
     477} 
     478 
     479 
    380480NSCAPI::nagiosReturn CheckWMI::commandLineExec(const std::wstring &command, std::list<std::wstring> &arguments, std::wstring &result) { 
    381481  try { 
    382     if (command == _T("wmi-query") || command == _T("help") || command == _T("query")) { 
     482    if (command == _T("wmi") || command == _T("help") || command.empty()) { 
    383483 
    384484      namespace po = boost::program_options; 
    385485 
    386       std::wstring query, ns; 
     486      std::wstring query, ns, computer, user, password, list_cls, list_inst; 
    387487      int limit = -1; 
    388488      po::options_description desc("Allowed options"); 
    389489      desc.add_options() 
    390490        ("help,h", "Show help screen") 
    391         ("wmi-query,w", po::wvalue<std::wstring>(&query), "Query to execute") 
     491        ("select,s", po::wvalue<std::wstring>(&query), "Execute a query") 
     492        ("list-classes", po::wvalue<std::wstring>(&list_cls)->implicit_value(_T("")), "list all classes of a given type") 
     493        ("list-instances", po::wvalue<std::wstring>(&list_inst)->implicit_value(_T("")), "list all instances of a given type") 
     494        ("list-ns", "list all name spaces") 
     495        ("list-all-ns", "list all name spaces recursivly") 
    392496        ("limit,l", po::value<int>(&limit), "Limit number of rows") 
    393497        ("namespace,n", po::wvalue<std::wstring>(&ns)->default_value(_T("root\\cimv2")), "Namespace") 
     498        ("computer,c", po::wvalue<std::wstring>(&computer), "A remote computer to connect to ") 
     499        ("user,u", po::wvalue<std::wstring>(&user), "The user for the remote computer") 
     500        ("password,p", po::wvalue<std::wstring>(&password), "The password for the remote computer") 
    394501        ; 
    395502 
     
    397504 
    398505      if (command == _T("help")) { 
     506        std::stringstream ss; 
     507        ss << "wmi Command line syntax:" << std::endl; 
     508        ss << desc; 
     509        result = utf8::cvt<std::wstring>(ss.str()); 
     510        return NSCAPI::isSuccess; 
     511      } 
     512 
     513      std::vector<std::wstring> args(arguments.begin(), arguments.end()); 
     514      po::wparsed_options parsed = po::basic_command_line_parser<wchar_t>(args).options(desc).run(); 
     515      po::store(parsed, vm); 
     516      po::notify(vm); 
     517 
     518      if (vm.count("help") || (vm.count("select") == 0 && vm.count("list-classes") == 0 && vm.count("list-instances") == 0 && vm.count("list-ns") == 0 && vm.count("list-all-ns") == 0)) { 
    399519        std::stringstream ss; 
    400520        ss << "CheckWMI Command line syntax:" << std::endl; 
     
    404524      } 
    405525 
    406       std::vector<std::wstring> args(arguments.begin(), arguments.end()); 
    407       po::wparsed_options parsed = po::basic_command_line_parser<wchar_t>(args).options(desc).run(); 
    408       po::store(parsed, vm); 
    409       po::notify(vm); 
    410  
    411       if (vm.count("help") || query.empty()) { 
    412         std::stringstream ss; 
    413         ss << "CheckWMI Command line syntax:" << std::endl; 
    414         ss << desc; 
    415         result = utf8::cvt<std::wstring>(ss.str()); 
    416         return NSCAPI::isSuccess; 
    417       } 
     526      ns = build_namespace(ns, computer); 
    418527 
    419528      WMIQuery::result_type rows; 
    420       try { 
    421         WMIQuery wmiQuery; 
    422         NSC_DEBUG_MSG_STD(_T("Running query: '") + query + _T("' on: ") + ns); 
    423         rows = wmiQuery.execute(ns, query); 
    424       } catch (WMIException e) { 
    425         NSC_LOG_ERROR_STD(_T("WMIQuery failed: ") + e.getMessage()); 
    426         result += _T("ERROR: ") + e.getMessage(); 
    427         return NSCAPI::hasFailed; 
    428       } 
    429       if (rows.empty()) { 
    430         result += _T("No result"); 
    431         return NSCAPI::isSuccess; 
    432       } else { 
    433         NSC_DEBUG_MSG_STD(_T("Query returned: ") + strEx::itos(rows.size()) + _T(" rows.")); 
    434         std::vector<std::wstring::size_type> widths; 
    435         int rownum=0; 
    436         for (WMIQuery::result_type::const_iterator citRow = rows.begin(); citRow != rows.end(); ++citRow) { 
    437           if (limit != -1 && rownum++ > limit) 
    438             break; 
    439           const WMIQuery::wmi_row vals = *citRow; 
    440           if (citRow == rows.begin()) { 
    441             for (WMIQuery::wmi_row::list_type::const_iterator citCol = vals.results.begin(); citCol != vals.results.end(); ++citCol) { 
    442               widths.push_back( (*citCol).first.length()+1 ); 
    443             } 
    444           } 
    445           int i=0; 
    446           for (WMIQuery::wmi_row::list_type::const_iterator citCol = vals.results.begin(); citCol != vals.results.end(); ++citCol, i++) { 
    447             widths[i] = max(widths[i], (*citCol).second.string.length()+1); 
    448           } 
    449         } 
    450         std::wstring row2 = _T("|"); 
    451         rownum=0; 
    452         for (WMIQuery::result_type::iterator citRow = rows.begin(); citRow != rows.end(); ++citRow) { 
    453           if (limit != -1 && rownum++ > limit) 
    454             break; 
    455           const WMIQuery::wmi_row vals = *citRow; 
    456           if (citRow == rows.begin()) { 
    457             int i=0; 
    458             std::wstring row1 = _T("|"); 
    459             for (WMIQuery::wmi_row::list_type::const_iterator citCol = vals.results.begin(); citCol != vals.results.end(); ++citCol, i++) { 
    460               std::wstring::size_type w = widths[i]-(*citCol).first.length(); 
    461               if (w<0) w=0; 
    462               row1 += std::wstring(w, ' ') + (*citCol).first + _T(" |"); 
    463               row2 += std::wstring(widths[i], '-') + _T("-+"); 
    464  
    465             } 
    466             result += row2; 
    467             result += row1; 
    468             result += row2; 
    469           } 
    470           int i=0; 
    471           std::wstring row = _T("|"); 
    472           for (WMIQuery::wmi_row::list_type::const_iterator citCol = vals.results.begin(); citCol != vals.results.end(); ++citCol, i++) { 
    473             std::wstring::size_type w = widths[i]-(*citCol).second.string.length(); 
    474             if (w<0) w=0; 
    475             row += std::wstring(w, ' ') + (*citCol).second.string + _T(" |"); 
    476           } 
    477           result += row; 
    478         } 
    479         result += row2; 
     529      if (vm.count("select")) { 
     530        try { 
     531          WMIQuery wmiQuery; 
     532          NSC_DEBUG_MSG_STD(_T("Running query: '") + query + _T("' on: ") + ns); 
     533          rows = wmiQuery.execute(ns, query, user, password); 
     534        } catch (WMIException e) { 
     535          NSC_LOG_ERROR_STD(_T("WMIQuery failed: ") + e.getMessage()); 
     536          result += _T("ERROR: ") + e.getMessage(); 
     537          return NSCAPI::hasFailed; 
     538        } 
     539        if (rows.empty()) { 
     540          result += _T("No result"); 
     541          return NSCAPI::isSuccess; 
     542        } else { 
     543          print_results(rows, limit, result); 
     544        } 
     545      } else if (vm.count("list-classes")) { 
     546        try { 
     547          WMIQuery wmiQuery; 
     548          rows = wmiQuery.get_classes(ns, list_cls, user, password); 
     549          print_results(rows, limit, result); 
     550        } catch (WMIException e) { 
     551          NSC_LOG_ERROR_STD(_T("WMIQuery failed: ") + e.getMessage()); 
     552          result += _T("ERROR: ") + e.getMessage(); 
     553          return NSCAPI::hasFailed; 
     554        } 
     555      } else if (vm.count("list-instances")) { 
     556        try { 
     557          WMIQuery wmiQuery; 
     558          rows = wmiQuery.get_instances(ns, list_inst, user, password); 
     559          print_results(rows, limit, result); 
     560        } catch (WMIException e) { 
     561          NSC_LOG_ERROR_STD(_T("WMIQuery failed: ") + e.getMessage()); 
     562          result += _T("ERROR: ") + e.getMessage(); 
     563          return NSCAPI::hasFailed; 
     564        } 
     565      } else if (vm.count("list-ns")) { 
     566        try { 
     567          WMIQuery wmiQuery; 
     568          rows = wmiQuery.get_instances(ns, _T("__Namespace"), user, password); 
     569          print_results(rows, limit, result); 
     570        } catch (WMIException e) { 
     571          NSC_LOG_ERROR_STD(_T("WMIQuery failed: ") + e.getMessage()); 
     572          result += _T("ERROR: ") + e.getMessage(); 
     573          return NSCAPI::hasFailed; 
     574        } 
     575      } else if (vm.count("list-all-ns")) { 
     576        try { 
     577          list_ns_rec(ns, user, password, result); 
     578        } catch (WMIException e) { 
     579          NSC_LOG_ERROR_STD(_T("WMIQuery failed: ") + e.getMessage()); 
     580          result += _T("ERROR: ") + e.getMessage(); 
     581          return NSCAPI::hasFailed; 
     582        } 
    480583      } 
    481584    } 
Note: See TracChangeset for help on using the changeset viewer.