I have a Go application that takes in PowerShell commands as input, creates a new ps1 file, writes the commands to the file, then executes the script file.
It would be great if the file were not visible to users.
If there were some way to create the script file as a memory-mapped file and then execute that memory-mapped file, that would be a good solution.
Using CGo, I can call into C or C++ from the Go application. Since PowerShell can work with C# objects, I'm thinking that maybe we can somehow call into C# code (either from C/C++ or Go) and create a C# memory-mapped file object that PowerShell can then use to execute as a script.
Admittedly, I know nothing about how calling managed code from unmanaged code works.
So, is there some way to take this string containing PowerShell commands and execute it as a script without creating an on-disk file?
To make powershell.exe
read script input as standard input, pass -
as a command line argument:
package main
import (
"bytes"
"fmt"
"log"
"os/exec"
"strings"
)
func main() {
cmd := exec.Command("powershell", "-")
cmd.Stdin = strings.NewReader("Write-Output 'Hello, World!'")
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
fmt.Printf("pwsh out: %q\n", out.String())
}
With Go 1.16 you can embed the script in the executable at build time:
package main
import (
"bytes"
_ "embed"
"fmt"
"log"
"os/exec"
"strings"
)
//go:embed script.ps1
var scriptBytes []byte
func main() {
cmd := exec.Command("powershell", "-")
cmd.Stdin = strings.NewReader(string(scriptBytes))
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
fmt.Printf("pwsh out: %q\n", out.String())
}