0.2.0 • Published 3 years ago
@josephuspaye/powershell v0.2.0
powershell
Run PowerShell commands from Node.js and get the results as text, JSON, CSV, or HTML.
This project is part of #CreateWeekly, my attempt to create something new publicly every week in 2020.
Installation
npm install @josephuspaye/powershell --save
Usage
For the following examples, let's assume there's a folder called fixtures/
in the current working directory with the following entries:
folder/
file-a.txt
file-b.md
Run a command and get output as plain text
const { command } = require('@josephuspaye/powershell');
async function main() {
try {
const { result } = await command('ls fixtures');
console.log(result);
} catch (error) {
console.error('unable to run powershell command', error);
}
}
main();
Directory: C:\code\JosephusPaye\powershell\tests\fixtures
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 10/12/2020 8:15 PM folder
-a---- 10/12/2020 8:15 PM 7 file-a.txt
-a---- 10/12/2020 8:15 PM 9 file-b.md
Run a command and get output as JSON
const { command } = require('@josephuspaye/powershell');
async function main() {
try {
const { result } = await command(
'ls fixtures | Select-Object Name,DirectoryName',
{
convertTo: 'json',
}
);
console.log(JSON.stringify(result, null, ' '));
} catch (error) {
console.error('unable to run powershell command', error);
}
}
main();
[
{
"Name": "folder",
"DirectoryName": null
},
{
"Name": "file-a.txt",
"DirectoryName": "C:\\code\\JosephusPaye\\powershell\\tests\\fixtures"
},
{
"Name": "file-b.md",
"DirectoryName": "C:\\code\\JosephusPaye\\powershell\\tests\\fixtures"
}
]
Run a series of commands from a script file
This is useful when you have a large number of commands that would exceed the maximum command argument size.
const { commandsAsScript } = require('@josephuspaye/powershell');
async function main() {
try {
const command = `Get-Item fixtures/file-a.txt | Select-Object Name,DirectoryName | ConvertTo-Json;`;
const commands = [command, command, command, command].join('\r\n');
const { stdout } = await commandsAsScript(commands);
console.log(stdout);
} catch (error) {
console.error('unable to run powershell commands as script', error);
}
}
main();
{
"Name": "file-a.txt",
"DirectoryName": "C:\\code\\JosephusPaye\\powershell\\tests\\fixtures"
}
{
"Name": "file-a.txt",
"DirectoryName": "C:\\code\\JosephusPaye\\powershell\\tests\\fixtures"
}
{
"Name": "file-a.txt",
"DirectoryName": "C:\\code\\JosephusPaye\\powershell\\tests\\fixtures"
}
{
"Name": "file-a.txt",
"DirectoryName": "C:\\code\\JosephusPaye\\powershell\\tests\\fixtures"
}
API
interface PowershellOptions {
/**
* The format to convert the command's output to. If this is specified, the command should
* not end with a semi-colon, as it is piped into another command for conversion.
*/
convertTo?: 'json' | 'csv' | 'html';
/**
* Ensure that the JSON result returned is an array. Will wrap non-arrays in an array.
*/
ensureJsonArray?: boolean;
/**
* Get access to the underlying child process. The function provided will be
* called with the child process as soon as it is created and launched.
*/
useChildProcess?(child: ChildProcess): void;
}
interface CommandOutput {
/**
* The command's stdout, trimmed
*/
stdout: string;
/**
* The command's stderr, trimmed
*/
stderr: string;
/**
* The command's exit code
*/
exitCode: number | null;
}
type CommandOutputWithResult<T> = CommandOutput & {
/**
* The command's result. For commands requesting JSON, this is stdout parsed as JSON.
*/
result: T;
};
/**
* Run the given PowerShell command, and optionally convert the results to JSON, CSV, or HTML.
*/
function command<T = any>(
command: string,
options?: PowershellOptions
): Promise<CommandOutputWithResult<T>>;
/**
* Run the given PowerShell commands from a script file and get the output as a string
*/
function commandsAsScript(
commands: string,
useChildProcess?: PowershellOptions['useChildProcess']
): Promise<CommandOutput>;