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.