CIMplant Part 3: Good Ol' maxEnvelopeSize to Ruin the Day
This is the last part in the three part series on CIMplant. If you haven't seen the previous two, you can find them here: CIMplant Part 1 and CIMplant Part 2. This last blog post will primarily be an informal look related to an interesting roadblock I ran into while writing CIMplant and my thought process for getting around it.
Max What Now?
I want to take you on a journey through various errors and a simple nuance with CIM/MI through WinRM that drove me crazy for a few days. As such, I'll wait to dive into the definition of the maxEnvelopeSize and associated configurations until later in the post.
So here I am, writing the CIM methods of CIMplant and everything is going great. The WMI methods are finished, I have an OK level of error handling and reasoning why certain errors would be thrown at certain times, and everything works when accessing small files (think a text file with a few lines). Now, of course, I want to start testing with larger files and binary files that may pose issues with conversion and I run into the following error:
First thing that I'm sure would go through anybody's mind would be to Google the HRESULT to see if Microsoft was nice enough to supply me with any helpful insight. Looking at the great hresult.info site here pointed me to the error message "The WS-Management service cannot process the request because the XML is invalid." This is an interesting error since the DebugFilePath was successfully modified and it errored when trying to pull the data back. But the data is valid in the sense that it's only integers and commas, albeit a large amount of them.
If a command is run again that deals with the DebugFilePath property we can see that it errors out when trying to set it, but after some more inspection, the program actually errors when pulling the original DebugFilePath property before setting it.
OK, this is a more insightful error. It looks like the packet size that was being sent over WSMan (~39 mb) was too large and exceeded the default maxEnvelopeSize (500 kb). Section 6.2 (line 1086) of DMTF-DSP0226 gives us some insight into the maxEnvelopeSize SOAP header and what it entails as it's related to sending and receiving data. After a bit more Googling, it appears as though we can modify the maxEnvelopeSize config value to anything we want using PowerShell with the following command:
Set-Item -Path WSMan:\localhost\maxEnvelopeSizeKB -Value [Some multiple of 1024]
Unfortunately, after some trial and error, this value must be set and matched on both the sending and receiving systems otherwise the transfer will fail. This is fairly trivial to do on the remote system via WMI and the Win32_Process class due to that process being executed in an administrative context. The local system is a bit more tricky since the command promt running CIMplant must be running in an elevated context, especially if explicit credentials are given. This is a nuance of local WMI connections where credentials cannot be supplied if targetting a local system and connecting to the WMI database. To combat this, we create a local PowerShell runspace, check if the user is an admin, and then execute the PS command to modify the envelope size. A similar method is used remotely using the Create method of Win32_Process.
Once both the sending and receiving systems have had their maxEnvelopeSize modified, the file transfer can begin as normal. Another thing to note is that when sending large files through CIM/MI the time required greatly increases related to the size. So a file that's several MB in size might take a few minutes to transfer whereas with WMI the transfer is generally much quicker.
And that, folks, is how I spent several hours debugging CIMplant, only to eventually figure out that it was the protocol and not my code causing the issues. Hopefully this post gives a short insight into the maxEnvelopeSize and its involvement with CIM/MI.