Running Remote Commands And Actually Getting The Output Using Only WMI

Executing remote commands using nothing but WMI and PowerShell.

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?

In a nutshell…

  • 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!

0 0 votes
Article Rating
Subscribe
Notify of
guest
8 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Valerii

That’s very nice. Did You try to use credentials ?
For example, if computer not in domain ?

Valerii

I improved in a little bit Your script. Now it works with credentials.
But the problem, I can’t execute it on Windows Server 2003

Ederson

Do you mind to share the code?

Ederson

Oh yeah! Thanks for the fast answer, but I mean, I needed the code that works with credentials…
I belive that Valerii have made some adjustments to the code… I tried myself but I am a poor programmer

Scott

Very Good Code/Script, but it does not work on powershell core. On Powershell Core, WMI objects/functions like Get-WMIObject and Set-WMIInstance is missing.

8
0
Would love your thoughts, please comment.x
()
x