Running a Powershell script in Node

I needed a way to call a Powershell script from Node. Node provides child_process module, which provides tools to execute and communicate with external processes.

We're going to use spawn for this. It allows us to pipe the stdout/stderr of a process back to caller. This helps the caller to see what the process is actually doing behind the scenes.

const {spawn} = require("child_process");

/**
 * @param {string} executable
 * @param {string[]} args
 * @param {import('child_process').SpawnOptions} opts
 * @return {Promise<number>} return code
 * */
async function run(executable, args, opts = {}) {
    return new Promise((resolve, reject) => {
        const child = spawn(executable, args, {
            shell: true,
            stdio: ["pipe", process.stdout, process.stderr],
            ...opts,
        });
        child.on("error", reject);
        child.on("exit", (code) => {
            if (code === 0) {
                resolve(code);
            } else {
                const e = new Error('Process exited with error code ' + code);
                e.code = code;
                reject(e);
            }
        });
    });
}

I like writing my own wrapper to promisify spawn. It helps me return the exit code to the caller and I also get a better intellisense while writing scripts.

We can call run inside a try-catch block to capture errors and set a correct exit code.

try {
    const code = await run('powershell', ["-executionpolicy", "unrestricted", "-file", 'script.ps1']);
    process.exit(code);
} catch (e) {
    console.error(e);
    process.exit(e.code || 1);
}
Last updated: