关于通过WMI接口获取远程计算机上信息的方法

前几日在帮一位同事解决一个关于WMI远程调用的问题时发现微软MSDN自带的例子尽然无法正确运行,每次在进行信息查询时就出现“拒绝访问”的错误提示,这个例子在微软的MSDN网站上如下:

http://msdn.microsoft.com/en-us/library/aa390422.aspx

如果直接用这个例子都无法完成功能,于是乎应该是微软MSDN例子有误(从经验看MSDN上的错误例子也不在少数啊,包括SDK和WDK中的,俺经常就被误导)。

其中调用出错的语句是下面这句:

// For example, get the name of the operating system
    IEnumWbemClassObject* pEnumerator = NULL;
    hres = pSvc->ExecQuery(
        bstr_t("WQL"),
        bstr_t("Select * from Win32_OperatingSystem"),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
        NULL,
        &pEnumerator);
   
    if (FAILED(hres))
    {
        cout << "Query for operating system name failed."
            << " Error code = 0x"
            << hex << hres << endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return 1;               // Program has failed.
    }
之前的远程连接都是成功的,但是只要一进行信息查询就报错了,在整个过程我进行抓包,筛选了TCP和RPC协议报文,然后和通过Wbemtest远程连接工程抓取的报文进行比对分析发现,有如下两点主要的疑问:

1、调用MSDN上的例子来连接远程主机时尽然连接到另外一台机器上去了

2、查询失败的报文中没有返回错误信息,只是感觉连接突然断了,没有后续报文

通过上网查询发现基本上大家都遇到了类似的问题,很多高手出面,答案也很多,好不容易有人说问题解决了,但是发现尽然没有对此问题的解决之道进行总结,于是乎我为此问题绞尽脑汁啊,想尽办法,苦苦思考一天而没有所获,期间我试着在目标机器上重新配置了wmi服务的权限,包括远程访问权限啊,远程激活权限啊,但是还是继续爆同样的错误。

最最后通过请教发现原来是一些变量参数设置有问题所致,经过如下修改之后终于可以完成远程主机上信息的查询了。

其原因主要在于没有正确的指定当前连接机器的域名,在局域网内,为了便于快速查询,包括加入域操作,一般会使用netbios名来作为查询的,这样就少了繁重的DNS解析的工作量,这就是为什么有些机器关闭了Netbios帮助服务后无法加入域的原因。当然在Kerberos认证的时候肯定是要通过DNS解析的。

查询Netbios名的DOS命令是:nbtstat.

下面是能够成功调用的demo。

 

#include "stdafx.h"

#define _WIN32_DCOM

#include <iostream>

using namespace std;

#include <comdef.h>

#include <Wbemidl.h>

# pragma comment(lib, "wbemuuid.lib")

   

   

    int main(int argc, char **argv)

    {

        HRESULT hres;

   

        // Step 1: --------------------------------------------------

        // Initialize COM. ------------------------------------------

   

        hres =  CoInitializeEx(0, COINIT_MULTITHREADED);

        if (FAILED(hres))

        {

            cout << "Failed to initialize COM library. Error code = 0x"

                << hex << hres << endl;

            return 1;                  // Program has failed.

        }

   

        // Step 2: --------------------------------------------------

        // Set general COM security levels --------------------------

        // Note: If you are using Windows 2000, you need to specify -

        // the default authentication credentials for a user by using

        // a SOLE_AUTHENTICATION_LIST structure in the pAuthList ----

        // parameter of CoInitializeSecurity ------------------------

   

        hres =  CoInitializeSecurity(

            NULL,

            -1,                          // COM authentication

            NULL,                        // Authentication services

            NULL,                        // Reserved

            RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication

            RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation 

            NULL,                        // Authentication info

            EOAC_NONE,                   // Additional capabilities

            NULL                         // Reserved

            );

   

                         

        if (FAILED(hres))

        {

            cout << "Failed to initialize security. Error code = 0x"

                << hex << hres << endl;

            CoUninitialize();

            return 1;                    // Program has failed.

        }

       

        // Step 3: ---------------------------------------------------

        // Obtain the initial locator to WMI -------------------------

   

        IWbemLocator *pLoc = NULL;

   

        hres = CoCreateInstance(

            CLSID_WbemLocator,            

            0,

            CLSCTX_INPROC_SERVER,

            IID_IWbemLocator, (LPVOID *) &pLoc);

    

        if (FAILED(hres))

        {

            cout << "Failed to create IWbemLocator object."

                << " Err code = 0x"

                << hex << hres << endl;

            CoUninitialize();

            return 1;                 // Program has failed.

        }

   

        // Step 4: -----------------------------------------------------

        // Connect to WMI through the IWbemLocator::ConnectServer method

   

        // Get the user name and password for the remote computer

 

        TCHAR pszName[100] = L"UserName";

        TCHAR pszPwd[100]  = L"Password";

 

        // NOTE: The value for pszDom will depend whether you are

        //       using a domain credential or a local machine account.

        //       Specify the NETBIOS name of the domain if the credential

        //       is for a domain user. For local machine account, specify

        //       the NETBIOS name of the remote machine

        TCHAR pszDom[100]  = L"DomainOrRemote"; 

   

 

                   IWbemServices *pSvc = NULL;

 

   

        // Connect to the remote root/cimv2 namespace

        // and obtain pointer pSvc to make IWbemServices calls.

        //---------------------------------------------------------

        // change the computerName and domain

        // strings below to the full computer name and domain

        // of the remote computer

      

        hres = pLoc->ConnectServer(

            _bstr_t(L"COMPUTERNAME//root//cimv2"),

            _bstr_t(pszName),                 // User name

            _bstr_t(pszPwd),                  // User password

            _bstr_t(L"MS_409"),               // Locale            

            NULL,                             // Security flags

            _bstr_t(L"ntlmdomain: DomainOrRemote"),    // Authority       

            0,                                // Context object

            &pSvc                             // IWbemServices proxy

            );

    

        if (FAILED(hres))

        {

            cout << "Could not connect. Error code = 0x"

                 << hex << hres << endl;

            pLoc->Release();    

            CoUninitialize();

            return 1;                // Program has failed.

        }

   

        cout << "Connected to ROOT//CIMV2 WMI namespace" << endl;

   

   

        // Step 5: --------------------------------------------------

        // Set security levels on a WMI connection ------------------

        COAUTHIDENTITY cID;

   

        cID.User           = (USHORT*)&pszName;

        cID.UserLength     = lstrlen(pszName); //bstrUsername.length();

        cID.Password       = (USHORT*)&pszPwd;

        cID.PasswordLength = lstrlen(pszPwd); //bstrPassword.length();

        cID.Domain         = (USHORT*)&pszDom;

        cID.DomainLength   = lstrlen(pszDom); // bstrDomain.length();

        cID.Flags          = SEC_WINNT_AUTH_IDENTITY_UNICODE;

   

        hres = CoSetProxyBlanket(

           pSvc,                        // Indicates the proxy to set

           RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx

           RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx

           NULL,                        // Server principal name

           RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx

           RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx

           &cID,                        // client identity

           EOAC_NONE                    // proxy capabilities

        );

   

        if (FAILED(hres))

        {

            cout << "Could not set proxy blanket. Error code = 0x"

                << hex << hres << endl;

            pSvc->Release();

            pLoc->Release();    

            CoUninitialize();

            return 1;               // Program has failed.

        }

   

        // Step 6: --------------------------------------------------

        // Use the IWbemServices pointer to make requests of WMI ----

   

        // For example, get the name of the operating system

       IEnumWbemClassObject* pEnumerator = NULL;

    hres = pSvc->ExecQuery(

        bstr_t("WQL"),

        bstr_t("Select * from Win32_OperatingSystem"),

        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,

        NULL,

        &pEnumerator);

   

    if (FAILED(hres))

    {

        cout << "Query for operating system name failed."

            << " Error code = 0x"

            << hex << hres << endl;

        pSvc->Release();

        pLoc->Release();

        CoUninitialize();

        return 1;               // Program has failed.

    }

 

 

        //

        // Must set the security on the enumerator interface as well

        // or you will received an access denied error

        //

        hres = CoSetProxyBlanket(

           pEnumerator,                 // Indicates the proxy to set

           RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx

           RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx

           NULL,                        // Server principal name

           RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx

           RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx

           &cID,                        // client identity

           EOAC_NONE                    // proxy capabilities

        );

   

        if (FAILED(hres))

        {

            cout << "Could not set proxy blanket. Error code = 0x"

                << hex << hres << endl;

            pSvc->Release();

            pLoc->Release();    

            CoUninitialize();

            return 1;               // Program has failed.

        }

   

        // When you have finished using the credentials,

        // erase them from memory.

        SecureZeroMemory(pszName, sizeof(pszName));

        SecureZeroMemory(pszPwd, sizeof(pszPwd));

        SecureZeroMemory(pszDom, sizeof(pszDom));

   

   

        // Step 7: -------------------------------------------------

        // Get the data from the query in step 6 -------------------

    

       IWbemClassObject *pclsObj;

    ULONG uReturn = 0;

  

    while (pEnumerator)

    {

        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,

            &pclsObj, &uReturn);

 

        if(0 == uReturn)

        {

            break;

        }

 

        VARIANT vtProp;

 

        // Get the value of the Name property

        hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);

        wcout << " OS Name : " << vtProp.bstrVal << endl;

     

        VariantClear(&vtProp);

    }

 

    // Cleanup

    // ========

   

    pSvc->Release();

    pLoc->Release();

    pEnumerator->Release();

    pclsObj->Release();

    CoUninitialize();

 

 

   

        return 0;   // Program successfully completed.

       

    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值