Don Jones

Tech | Career | Musings

Javier writes:

Suppose I have a Windows service in a productive environment that does some kind of work. It’s secured and everything, and I have a very limited way of interact with it to maybe adjust its configuration or perform a maintenance work on it.

I thought it would be awesome if I could use Powershell to tap into that services and be able to check for internal objects and maybe change some configuration on the fly.

The idea would be to host a Powershell inside the service, easy job, create a runspace and a pipeline in which specific objects are exposed in the form of variables, no problem, and then be able to run Powershell code in that pipeline.

Easy done if the service had a GUI or if it was interactive in some way so it would just ask for an input, and I could push that input into the pipeline and maybe display the info from the returned PSObject. But, no GUI at all and neither I would like for it to have it. I made a proof of concept using a REST kind of interface to pass along the powershell code and execute it in the pipeline, and the look of it was really promising.

Now, since Powershell is built thinking of remoting, I was wondering if there could be some way of creating a remote session to invoke commands but not on the Powershell environment of the computer, but in the pipeline of the Powershell hosted inside my windows service.

There are tons of examples of Powershell self hosting applications but none takes remoting into consideration, from the server perspective. I’m not sure what was the intention in being able to host a powershell engine on a .NET application, but I think it would only be natural if I could initiate a remote connection to that engine, don’t you?

I don’t know if I’m terribly misguided. If that would be the case, what would be in your opinion the best way to use Powershell to interact with a windows service? Something like the way we use powershell to interact and configure Exchange for example.

I hope you’ll ask a question, too! Visit here for info.

Let’s break that down a bit.

Suppose I have a Windows service in a productive environment that does some kind of work. It’s secured and everything, and I have a very limited way of interact with it to maybe adjust its configuration or perform a maintenance work on it.

That’s quite common for services, actually. Most offer fairly limited means of interaction. “Services” like Exchange or SQL Server are vastly more complex. The Exchange team, for example, wrote an entire API so that you could tel their service what to do. The short answer to your question is, unless the service’s author took that time, then you’re stuck.

I thought it would be awesome if I could use Powershell to tap into that services and be able to check for internal objects and maybe change some configuration on the fly.

That would be a malware author’s wet dream, unfortunately. Windows’ internal security design creates a fairly hard boundary between processes. Aside from attaching a low-level debugger to a process (which for many processes, will cause them to self-terminate), you can’t “tap into” someone else’s code. It’d be like “tapping into” your neighbors’ houses to see what’s going on inside. Eventually, you’ll get shot.

The idea would be to host a Powershell inside the service, easy job, create a runspace and a pipeline in which specific objects are exposed in the form of variables, no problem, and then be able to run Powershell code in that pipeline.

You definitely can’t add code to someone else’s process, even using a low-level debugger. Services aren’t often written in .NET, which is what you write in if you need to host a PowerShell instance.

Now, since Powershell is built thinking of remoting, I was wondering if there could be some way of creating a remote session to invoke commands but not on the Powershell environment of the computer, but in the pipeline of the Powershell hosted inside my windows service.

Basically, this is how people build botnets, and the operating system goes to pretty great lengths to make this difficult and impractical.

So unfortunately, in short, the answer here is “no.”

I’m not sure what was the intention in being able to host a powershell engine on a .NET application, but I think it would only be natural if I could initiate a remote connection to that engine, don’t you?

Well, the intention is something like Exchange’s GUI tools, which were written with PowerShell in mind. Underneath the GUI, it’s all just PowerShell, because that GUI “hosts” the PowerShell engine. But there’d be no need to “remotely connect” to the GUI or that hosted engine. You can already remotely connect to PowerShell itself and run whatever commands you want. And I don’t actually think it’d be natural to connect to any ol’ instance of PowerShell hosted inside an application; again, think of the security concerns. In order for this to happen, something on the remote computer would have to “keep track” of every running instance of PowerShell inside any application, so that incoming traffic could be directed to the appropriate one. That something would be WinRM, and it’s just not how it was designed. An application designed for this purpose can register with WinRM, so that incoming Remoting traffic can find its destination. But you have to design the application with that in mind. Most of the time, there’s simply no need.

I don’t know if I’m terribly misguided. If that would be the case, what would be in your opinion the best way to use Powershell to interact with a windows service? Something like the way we use powershell to interact and configure Exchange for example.

The service has to be written to be managed by PowerShell. Usually, that means the service needs to expose some kind of API, usually in .NET but potential in COM, that a PowerShell command can be written to talk to. If a service wasn’t written to be easily managed, then there’s no real way to “fix” that. Simpler services may simply read their configuration from a text file or the Registry, and you can certainly modify those with PowerShell, possibly restarting the service to make it re-read its configuration. Short of that, however, there’s no fixing a service that wasn’t designed to be managed, other than yelling at its developer.

Windows as an OS, and services as a piece of software, are a great deal more complicated than a lot of people realize. There’s a lot happening under the hood, and a lot of rules governing interactions between software, to keep the system both safe and stable.

 

3 thoughts on “AMA: Can PowerShell “Go Inside” a Service?

  1. This isn’t very close, but you could explore the modules (not PS modules) loaded in the process behind the service. Not what you’re after exactly, but interesting to peek inside and see what else the service touches:
    Get-Service vmms
    Get-Process vmms | Select-Object -ExpandProperty Modules | fl *

  2. Javier says:

    Thanks for the answer Don! Mmmh, let’s say the developer of these services is a friend of mine ;). How could I point him in the direction of designing the service with PowerShell in mind? I’ve looked for any available info on WinRM and how to register on it but there’s not much available. Would you recomend me some article or book to begin with?

    Thanks also Ashely for your comment, I’ll take a look on that.

    1. Don Jones says:

      So, the whole point of PowerShell is to wrap around APIs. Ask your friend to create an API. PowerShell an work with anything. REST, COM, DCOM, .NET, whatever. WinRM isn’t necessarily it.

Comments are closed.

%d bloggers like this: