Home > OS >  Node JS how to call a function in a spawned child process (powershell script)?
Node JS how to call a function in a spawned child process (powershell script)?

Time:12-02

is there a way to call a function in a spawned child process, a powershell script, from the parent node js script?

node script:

const cp = require("child_process");
const psData = cp.spawn
("powershell -executionpolicy bypass  ./powershell-script.ps1", [], {
    shell: "powershell.exe",
});

powershell script:

function psDoSomething{
    # do something
}

CodePudding user response:

There's no builtin way for Node to call specific functions in a subprocess. You could pass arguments to your PS script if that would help, or you could spawn/exec another PS script, but Node doesn't know or care about Powershell (or Python, or Shell, or any other language in a spawned/execed script). If you need that functionality, you could try one of the Powershell-related packages on NPM.

Edit: OP suggested in a comment using stdin.write on the child process, and listening to STDIN in the subprocess, which is an interesting idea. I don't use Powershell, but here's how that could work using Bash:

const bashSession = require('child_process').spawn('./foo.sh')
bashSession.stdin.setEncoding('utf-8')
bashSession.stdout.pipe(process.stdout)
bashSession.stdin.write('someFunc\n')
bashSession.stdin.end()
#!/bin/bash

doThing() {
    echo We made it here
}

while read line; do
    if [[ $line == someFunc ]]; then
        doThing
    else
        echo "$line"
    fi
done < "${1:-/dev/stdin}"

Having your subprocess listen to everything on stdin could create problems, but the same concept could be used with a designated file, or with a TCP socket.

CodePudding user response:

If all you're looking to do is to call a function defined inside your PowerShell script, the following should do:

let child = require('child_process').spawn(
  'powershell.exe', 
  [
    '-noprofile', '-executionpolicy', 'bypass', '-c', 
    '. ./powershell-script.ps1; psDoSomething'
  ]
)

// Listen for stdout output and print it to the console.
child.stdout.on('data', function(data) {
  console.log(data.toString());
})
  • The above uses powershell.exe, the Windows PowerShell CLI, with its -c / -Command parameter to process a given snippet of PowerShell code.

  • Since the function to invoke is defined inside the ./powershell-script.ps1 script, that script must be dot-sourced in order to load the function definition into the caller's scope.

  • Thereafter, the function can be invoked.


If you're looking to spawn a PowerShell child process to which you can iteratively feed commands for execution later, on demand, via stdin, you'll need a solution whose fundamentals are outlined in Zac Anger's answer, based on spawning the PowerShell child process as powershell.exe -noprofile -executionpolicy bypass -c -

  • Caveat: Sending a command spanning multiple lines must be terminated with two newlines; see GitHub issue #3223 for details.
  • Related