I have a really odd issue with WMI that I'm running into on a few machines on our network.
I have a piece of software (.NET/C#) written that scans an IP range on a local network, and then uses WMI to query certain data about the machines (computer names, .NET framework versions, among other things). One issue I've run into recently is that a small subset of these machines will not respond to WMI connections made via their IP address- they simply throw an "RPC Server is Unavailable" exception as if WMI isn't running to begin with.
This occurs both with the C# application and with a vbscript application that attempts a simple query to return the computer's name:
if wscript.arguments.count >= 1 then
host = wscript.arguments(0)
end if
if host = "" or isnull(host) then host = "."
connectionStr = "winmgmts:{impersonationLevel=impersonate}!\\" & host & "\root\cimv2"
wscript.echo connectionStr
set objWMIService = GetObject(connectionStr)
set objCompName = objWMIService.ExecQuery("Select * from Win32_ComputerSystem")
for each x in objCompName
wscript.echo x.Name
next
This returns the following as results:
C:\>nslookup BROKENCOMPUTER
Address: 192.168.1.123
C:\>cscript testwmi.vbs 192.168.1.123
winmgmts:{impersonationLevel=impersonate}!\\192.168.1.123\root\cimv2
C:\testwmi.vbs(9, 1) Microsoft VBScript runtime error: The remote server machine does not exist or is unavailable: 'GetObject'
C:\>cscript testwmi.vbs BROKENCOMPUTER
winmgmts:{impersonationLevel=impersonate}!\\BROKENCOMPUTER\root\cimv2
BROKENCOMPUTER
I can still open a WMI connection if I refer to the computer by its host/computer name. I can also connect to other servers running on the machine via IP address (such as HTTP or RDP)- a request tp http://192.168.1.123 returns successfully.
To make things even weirder, the behavior isn't even consistent. Sometimes the connection to the IP will work correctly, and it happens in batches. To test this, I set up a script that repeatedly spammed a WMI request every 5 seconds to the computer in question and recorded the result (and trends of results). What I found was that all requests would fail or succeed for about a certain number of requests (180- a 15 minute interval) or a multiple of it. Example:
- Start script
- 35 successful requests in a row
- 180 failed requests in a row
- 180 successful requests
- 360 failed requests
- 180 successful requests
- 180 failed requests
- 900 successful requests
- etc etc
I then ran this script on two machines at the same time. What I found was the behavior between the two was similar (had several-minute-long-intervals of being able to connect and not being able to connect) but did not sync up between the two; there were periods where both could connect, periods where only one (or the other) could connect, and periods where neither could connect.
I know this is an incredibly weird and specifi开发者_高级运维c problem, and I don't really expect anyone to be able to insta-solve it, but I was wondering if anyone had any hints or direction? I've spoken to the network guys here and they're just as puzzled over the issue as I am.
I can add some perspective on this, in addition to the fine answer from MisterZimbu. Assuming Microsoft doesn't remove my comments on this article, see http://msdn.microsoft.com/en-us/library/windows/desktop/aa393720%28v=vs.85%29.aspx. Basically, Microsoft seems to be doing a reverse DNS lookup when IP addresses are passed into WMI. If your DNS isn't squeaky clean, you will get "unpredictable results", which is to say that you will be connecting to machines you didn't expect to connect to.
Adding the period to the IP address forces the reverse (or forward) lookup to fail, and then by some miracle, they actually use the IP address, and not the (potentially incorrect) hostname returned from DNS. It appears that appending a period to the IP address can be used in many contexts (UNC's, browser, etc.), but there are caveats and other failures you might encounter. Note that if you look at your DNS cache (ipconfig /displaydns) you will see the failed lookups when the period is appended, so it doesn't stop the OS from doing the lookup - it just ensures that the stale DNS entries won't be used.
Oddly enough, adding a "." to the end of the IP address when making the query corrects the issue. I assume this forces it to go through DNS resolution or something like that.
So connecting via
winmgmts:{impersonationLevel=impersonate}!\\192.168.1.123.\root\cimv2
seems to work correctly 100% of the time.
Still would be great to know what actually is the underlying cause of the issue though.
精彩评论