Running PowerShell cmdlets and functions?


#1

Hello all.

Is it possible to run PowerShell cmdlets and functions from rust-lang application?

Thanks in advance. :slight_smile:


#2

In as much as it’s possible from any language that can start external processes. You just invoke the PowerShell executable with an appropriate command line argument.

I found a StackOverflow question on how to do it from a batch file. Combine that with the documentation on process::Command and you should be good to go.


#3

While you can invoke the executable, there is no interactivity with it and you need to keep invoking the executable again and again which is inefficient. NET System.Management.Automation library has the kind of functionality I was looking for. Meaning, open a PowerShell session and interact with it.

I was looking for a cross-platform solution where I can run PowerShell on Windows and a shell like bash on Linux. And I was hoping there would be a way to accomplish this in Rust, rather than sticking with .NET and Mono.


#4

That appears to be a managed class that also isn’t exposed via COM. Insofar as I know, there is no way of directly calling that from Rust, C or any other native language. At least, not without embedding .NET in the Rust program, but I have no idea how you’d go about that.

If I had to do this, and just invoking the executable definitely wasn’t an option, I’d create a server program in C# with some kind of RPC interface; the Rust end would start the server, connect to it, then use that to execute commands.

As for cross platform, I can’t imagine how you would write a program that works across psh and bash without having to special-case for each. They’re different in so many important respects!


#5

Besides a server, you could also create a library in C++/CLI with C interface, which could be used by Rust’s FFI. Both are a bit of a long shots though, a lot of trouble and not so much gain.

Personally I’d recommend using Cygwin or MSYS or suchlike on windows instead, that would provide basically the same interface as shell on unix.


#6

You can just launch one powershell instance and pass it the arguments, “-Command -” to be able to use it interactively through its standard input.

let mut process = Command::new("powershell")
                      .args(&["-Command", "-"]).ok().expect("launch failure");
let stdin = process.stdin.as_mut().expect("pipe failure");
stdin.write_line("start-process calc");
stdin.write_line("exit");
//process.wait();

#7

Huh, that’s interesting! Thanks.