Running Remote Commands And Actually Getting The Output Using Only WMI

If you’ve worked with WMI for any amount of time, you may have run into the following problem:

“Creating a remote Windows process using the Win32_Process class is relatively easy, but how do I get the console output?”

Have no fear.

Win32_Process to the rescue. Wait… no. ????

The Create method of the Win32_Process class has worked great for many years, but there’s no way to get the console output from the remote process using it. You’ll only receive the PID and some other metadata. Doing a full query on the process you created, returns a lot of information, but alas, still no STDOUT or STDERR streams.

Now you may be thinking…

“I just use PowerShell Remoting or PsExec”

Well… yeah, either of those options are great and I’ve used them many times. But what if you had a specific use case where you couldn’t?

So here’s the challenge:

Execute a remote Windows process, using only WMI and standard PowerShell.

Capture the remote console output from it.

Only WMI traffic is allowed to the target machine.

No WinRM, PsExec, admin shares, etc.

Challenge accepted!

You can see an example of it working in the video below. The script is running on Windows Server 2016 and targeting a Windows 7 non-SP1 machine. It tested successfully both ways.

What’s happening under the hood?

Create a custom WMI class on the remote machine with some properties on it.

Use the Create method of the Win32_Process class to execute my command(s) with PowerShell on the remote machine.

Store the console output in my custom WMI class, while running remotely.

From the source machine, retrieve the property of the WMI class that has the console output.

I’ve come across the issue of not being able to grab STDOUT from Win32_Process for years and always turned to 3rd party tools or PowerShell remoting since I’ve never seen a native WMI solution before this. If you know of one that was already out there, please comment or mention it on Twitter.

Check out the code. Feedback welcome.

The source code is on Github. It’s a proof of concept and needs a lot of refining, error checking and resiliency added. Now, I’m not saying this is super relevant for modern systems management, but I do think it’s a neat technique and opens up some interesting possibilities. Let me know what you think!