4

I like to embed some powershell scripts in one Go binary. How can I embed them and execute the commands from GO. Currently I got it by running an external script:

out,err := exec.Command("Powershell", "-file" , "C:\\test\\go\\my.ps1").Output()
if err != nil {
     log.Fatal(err)

}

fmt.Printf("Data from powershell script is: %s", out)

my.ps1 content:

[System.Security.Principal.WindowsIdentity]::GetCurrent().Name

I got a few more powershell scripts, I like to add the powershell scripts into my go binary file. Have tryed a few things I did find on the internet but failed.

1
  • You can embed files in a Go binary, but to expose these to the host OS you'd need to copy the embedded assets back out to the filesystem (e.g. /tmp) - then you could initiate your exec.Command. Commented Nov 30, 2021 at 13:20

2 Answers 2

2

Embed your asset:

import (
    _ "embed"
)

//go:embed my.ps1
var shellBody []byte

and then when you need the host OS to access this, surface it via a temp file:

tmp, err := ioutil.TempFile("/tmp", "powershell.*.ps1")
if err != nil {
    log.Fatal(err)
}
defer os.Remove(tmp.Name()) // clean-up when done


f, err := os.OpenFile(tmp.Name(), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
    log.Fatal(err)
}

_, err = f.Write(shellBody)
if err != nil {
    log.Fatal(err)
}

err = f.Close()
if err != nil {
    log.Fatal(err)
}

then you can invoke Powershell:

out, err := exec.Command("Powershell", "-file" , tmp.Name()).Output()
if err != nil {
    log.Fatal(err)
}
Sign up to request clarification or add additional context in comments.

2 Comments

Is there no way to pass the embedded filename to the command (Powershell in this case) without doing the whole process of creating and writing to a temporary file?
Unfortunately no. The. Embedded files are in the go binary. To surface them, one has to proactively extract them via go code.
1

You can use go1.16 and embed, you should create a separated folder to save the embed file definitions, then use another function to return the string or byte[] file reference.

package main

import (
    "embed"
    "text/template"
)

var (
    // file.txt resides in a separated folder
    //go:embed file.txt
    myfile string
)

func main() {
    fmt.Printf("File %q\n", myfile)
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.