The other day I was prepping for my sessions at the upcoming PowerShell + DevOps Global Summit. As I usually do, when I am building demos that will connect to remote machines I often use the local computer as a placeholder. This should always work right? so imagine my surprise when this command gave me an error:
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
But running Get-CimInstance without the computer name worked just fine. I also had no problems using Get-WmiObject connecting to the local host. Which is good because my first thought was a corrupt CIM repository. But it turned out to be something else that we normally don't think about, because usually it just works.
Since Get-WmiObject worked and Get-CimInstance worked with out a remote connection, I was pretty sure my WMI setup was ok. I also had no issues querying anything else, even with a remote connection back to the local host. That left WSMan as a suspect. When you query WMI using the CIM cmdlets and make a remote connection, even if the "remote" computer is the local host, PowerShell creates a WSMan connection. So my first step was to gather a bit more information.
I opened up Event Viewer and enabled the Analytic log under Applications and Services Logs\Microsoft\Windows\Windows Remote Management. Don't forget to disable it when you are done troubleshooting.
Then I re-ran my command.
Get-CimInstance Win32_ComputerSystem -ComputerName $env:Computername
Now to the logs. I stepped through the events and saw the network setup as well as the authentication process. Eventually I see the beginning of the WMI enumeration.
After scrolling through a few more events I encountered this error:
Interesting. WMI wants to send almost 3MB of data back in response. WSMan doesn't like that as confirmed in the next event.
And eventually I get my invalid XML error. This all makes sense because when you use WSMan, the result is serialized as XML and transmitted back to you. In my scenario, I believe PowerShell received part of the response, but then the process is aborted so the XML is never completed and thus becomes invalid.
To finally verify WSMan was the culprit I tried using the command line winrm utility.
Clearly my WSMan configuration was failing me so I checked my settings in the WSMan PSDrive.
The MaxEnvelopeSizeKB was the likely culprit so I raised it.
Set-Item -Path WSMan:\localhost\maxEnvelopeSizeKB -Value 5000
Now re-running my Get-CimInstance expression worked as expected.
At this point I should have been satisfied, but I wondered why I get was getting so much data for this class. I re-tried my winrm enum command and while it didn't immediately give me an error, it also didn't immediately give me a response. Eventually the command completed and by the time I checked the window again it was full of byte values. Fortunately I was able to scroll up and see that the OEMLogoBitmap property was responsible. Interesting.
I reset my MaxEnvelopeSizeKB back to the default value of 500 and tried a more selective query using Get-CimInstance.
Get-CimInstance Win32_ComputerSystem -ComputerName $env:Computername -Property Name,Model,TotalPhysicalMemory
That worked as expected. But when I tried getting just the OEMLogoBitmap property I got the same error. Resetting WSMan so I could get all the data, I measured the size of the array and found that it was only 43KB. Serialization must add some overhead. In fact I tried simulating the process.
$r = Get-CimInstance win32_computersystem -ComputerName $env:Computername
[xml]$logo = $r.OEMLogoBitmap | convertto-xml
$logo.save("c:\work\logo.xml")
I'm sure there's a bit more than this. Still I ended up with a file that was 1.8MB in size which is a problem when the default limit is 500KB.
So where does this leave me? For now, there's no issue with me leaving my MaxEnvelopeSizeKB at a higher setting. I don't consider any of this a bug. Nor do I put any blame on the vendor who decided to populate the WMI property. That's why it is there. It only causes an issue when querying the class over WSMan. When using a DCOM connection everything just works. I should point out, that even with the lower default, if I were more selective I would have had no problems.
But like many of you I'm probably a bit too lazy. Even though limiting your WMI queries to just the properties you need is definitely a recommended best practice.