none
It takes 2 minutes until WMI connect returns "RPC server is unavailable"

    Question

  • Hi developers,

    I wrote an C# application for remote WMI query. The code works well but it might be terrible slow and returns RPC server is unavailable.

    My test environment:
    1. There are 2 PC, PC1 and PC2, PC1 is NOT setup with a local WMI account; PC2 issues WMI query to PC1.
    2. PC1 is wireless and in 60% signal, PC2 is cabled. They are all in workgroup.

    I start 4 thread for WMI connect concurrently to SecurityCenter, DEFAULT:StdRegProv, SecurityCenter2 and CIMV2. As expected, they failed to connect but it blocks for nearly 2 minutes until the 4 thread returns failure.

    8/21/2008 5:21:47 INFO Begin to get info for IP: 192.168.1.104
    8/21/2008 5:22:29 ERROR Target: SecurityCenter; Replied client, IP: 192.168.1.104; User: wmi; Pwd: User@123!; Err: The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
    8/21/2008 5:22:50 ERROR Target: DEFAULT:StdRegProv; Replied client, IP: 192.168.1.104; User: wmi; Pwd: User@123!; Err: The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
    8/21/2008 5:23:11 ERROR Target: SecurityCenter2; Replied client, IP: 192.168.1.104; User: wmi; Pwd: User@123!; Err: The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
    8/21/2008 5:23:32 ERROR Target: CIMV2; Replied client, IP: 192.168.1.104; User: wmi; Pwd: User@123!; Err: The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)

    I want to reduct the block time because it delay the overall system refresh on others. I do not want to use up too much system resource by issuing more WMI query to other computer concurrently because of limited concurrent TCP connection on XP SP2 and latter.

    I had already used 15 seconds time-out in ConnectionOptions. My code is as below. It seems no use to reduct the blocking time.

                ConnectionOptions options = new ConnectionOptions();
                options.Impersonation = ImpersonationLevel.Impersonate;
                options.Authentication = AuthenticationLevel.PacketPrivacy;
                options.EnablePrivileges = true;
                options.Timeout = new TimeSpan(0, 0, 15); ;

    I also tried a 15 seconds time-out in EnumerationOptions in ManagementObjectSearcher's construct, the code is as below. No use.

                    EnumerationOptions eo = new EnumerationOptions(
                        null, new TimeSpan(0, 0, 15),
                        1, true, true, true,
                        true, false, true, true);

                    ManagementObjectSearcher searcher =
                        new ManagementObjectSearcher(connectScope, query, eo);

    I also tried to set bool returnImmediatley in EnumerationOptions to be false. Still, no use, the connect still blocks for long.

    It does not always block for so long time. Sometimes, it returned failure precisely 15 seconds (my pre-set time-out).

    How to reduct the blocking? Any hint is appreciated.

    My ipconfig /all in target (PC1 with wireless) is as

    Windows IP Configuration

       Host Name . . . . . . . . . . . . : lab01-nb01
       Primary Dns Suffix  . . . . . . . :
       Node Type . . . . . . . . . . . . : Hybrid
       IP Routing Enabled. . . . . . . . : No
       WINS Proxy Enabled. . . . . . . . : No

    Wireless LAN adapter Wireless Network Connection:

       Connection-specific DNS Suffix  . :
       Description . . . . . . . . . . . : Intel(R) PRO/Wireless 3945ABG Network Connection
       Physical Address. . . . . . . . . : 00-13-02-00-C5-19
       DHCP Enabled. . . . . . . . . . . : Yes
       Autoconfiguration Enabled . . . . : Yes
       Link-local IPv6 Address . . . . . : fe80::4c97:82d4:79fe:ebc1%9(Preferred)
       IPv4 Address. . . . . . . . . . . : 192.168.1.104(Preferred)
       Subnet Mask . . . . . . . . . . . : 255.255.255.0
       Lease Obtained. . . . . . . . . . : Monday, August 25, 2008 12:42:41 AM
       Lease Expires . . . . . . . . . . : Thursday, August 28, 2008 4:40:51 PM
       Default Gateway . . . . . . . . . : 192.168.1.100
       DHCP Server . . . . . . . . . . . : 192.168.1.100
       DHCPv6 IAID . . . . . . . . . . . : 150999810
       DNS Servers . . . . . . . . . . . : 192.168.1.100
       NetBIOS over Tcpip. . . . . . . . : Enabled


    The WMI query thread is like below
            static bool WMIQuery(string sIP, string sUser, string sPwd)
            {
                Console.WriteLine("Parameter in LocalWMI, IP: {0}; User: {1}; Pwd: {2}",
                    sIP, sUser, sPwd);

                string HostName = "";
                string OSInfo = "";
                string Mac = "";
                UInt16 OSInfoMajorVer = 0;
                UInt16 OSInfoMinorVer = 0;
                bool bBattery = false;
                string UUID = "";

                DateTime dt = DateTime.Now;
                bool bRet = false;

                ConnectionOptions options = new ConnectionOptions();
                options.Impersonation = ImpersonationLevel.Impersonate;
                options.Authentication = AuthenticationLevel.PacketPrivacy;
                options.EnablePrivileges = true;
                options.Timeout = new TimeSpan(0, 0, 15); ;

                options.Username = sIP + "\\" + sUser;
                options.Password = sPwd;

                try
                {
                    //ManagementScope connectScope = new ManagementScope(@"\root\CIMV2", options);
                    EnumerationOptions eo = new EnumerationOptions(
                        null, new TimeSpan(0, 0, 15),
                        1, true, false, false,
                        true, false, false, true);

                    ManagementScope connectScope = new ManagementScope(@"\\" + sIP + @"\root\CIMV2",
                        options);

                    connectScope.Connect();

                    Console.WriteLine("After Connect(): {0} seconds",
                        (DateTime.Now - dt).Seconds);

                    ObjectQuery query = new ObjectQuery(
                        "SELECT * FROM Win32_OperatingSystem");
                    ManagementObjectSearcher searcher =
                        new ManagementObjectSearcher(connectScope, query, eo);

                    foreach (ManagementObject managementObject in searcher.Get())
                    {
                        OSInfo = (string)managementObject["Caption"];
                        OSInfoMajorVer = (UInt16)managementObject["ServicePackMajorVersion"];
                        OSInfoMinorVer = (UInt16)managementObject["ServicePackMinorVersion"];
                    }

                    Console.WriteLine("After Query Win32_OperatingSystem: {0} seconds",
                        (DateTime.Now - dt).Seconds);

                    ObjectQuery query1 = new ObjectQuery(
                        "SELECT * FROM Win32_ComputerSystem");
                    ManagementObjectSearcher searcher1 =
                        new ManagementObjectSearcher(connectScope, query1, eo);

                    foreach (ManagementObject managementObject in searcher1.Get())
                    {
                        HostName = (string)managementObject["Caption"];
                    }

                    Console.WriteLine("After Query Win32_ComputerSystem: {0} seconds",
                        (DateTime.Now - dt).Seconds);

                    ObjectQuery query2 = new ObjectQuery(
                        "SELECT * FROM Win32_Battery");
                    ManagementObjectSearcher searcher2 =
                        new ManagementObjectSearcher(connectScope, query2, eo);

                    foreach (ManagementObject managementObject in searcher2.Get())
                    {
                        bBattery = true;
                        break;
                    }

                    Console.WriteLine("After Query Win32_Battery: {0} seconds",
                        (DateTime.Now - dt).Seconds);

                    ObjectQuery query3 = new ObjectQuery(
                        "SELECT IPAddress, MACAddress FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled = true");
                    ManagementObjectSearcher searcher3 =
                        new ManagementObjectSearcher(connectScope, query3, eo);

                    string ipConfig = "";
                    foreach (ManagementObject managementObject in searcher3.Get())
                    {
                        Array arrIP = (Array)managementObject["IPAddress"];
                        string MAC = (string)managementObject["MACAddress"];
                        if (arrIP == null || string.IsNullOrEmpty(MAC) || arrIP.Length == 0)
                            continue;

                        foreach (string ip in arrIP)
                        {
                            string MACIP = string.Empty;
                            if (string.IsNullOrEmpty(ip))
                                continue;
                            MACIP = MAC + "(" + ip + ");";
                            ipConfig += MACIP;

                            if (string.Compare(ip, sIP) == 0)
                            {
                                Mac = MAC;
                            }
                        }
                    }

                    Console.WriteLine("After Query Win32_NetworkAdapterConfiguration: {0} seconds",
                        (DateTime.Now - dt).Seconds);

                    ObjectQuery query4 = new ObjectQuery(
                         "SELECT * FROM Win32_ComputerSystemProduct");
                    ManagementObjectSearcher searcher4 =
                        new ManagementObjectSearcher(connectScope, query4, eo);

                    foreach (ManagementObject managementObject in searcher4.Get())
                    {
                        UUID = (string)managementObject["UUID"];
                        break;
                    }
                    bRet = true;
                }
                catch (ManagementException)
                {
                    bRet = false;
                }
                catch (UnauthorizedAccessException e1)
                {
                    bRet = false;
                }
                catch (COMException e2)
                {
                    bRet = false;
                }

                Console.WriteLine("Finished with {0}; {1} seconds",
                    bRet.ToString(), (DateTime.Now - dt).Seconds);

                Console.WriteLine("HostName: {0}; Mac: {1}; OSInfo: {2}; Bettary: {3}; UUID: {4}",
                    HostName, Mac, OSInfo, bBattery.ToString(), UUID);

                return bRet;
            }
    Dev007
    Wednesday, August 27, 2008 3:35 AM

Answers

All replies