Narcissistic, Perfectly Modest

    full-powershell
    TypeScript icon, indicating that this package has built-in type declarations

    1.6.0 • Public • Published

    Full Powershell

    Full Powershell cleanly serialises all 6 message streams at their source so that they can be deserilised into JavaScript, retaining all of their semantics and completely removing the need to write brittle parsing logic.

    Background

    PowerShell has 6 message streams in addition to Stdout and Stderr. Cramming these 6 streams through stdout, on top of direct output, removes the streams semantics. Additionally, parsing this mess is painful - unexpected warning or error messages make your application very brittle.

    How it works

    This library accepts PowerShell commands as strings. It then transparently wraps them in an Invoke-Command that captures and serilises their output. This means that all 6 message streams are captured and sorted at their source. Once sent back to Node.js they can be subscribed to as 6 separate RxJS streams. Or the individual call can be subscribed to, emitting all streams in a clearly defined format. I encourage users to take a look at index.ts and wrapper.ts to see exactly how it works.

    API

    PowerShell class.

    Spawns a PowerShell child process and exposes methods to read/write to/from that process:

    class PowerShell {
        constructor(private options?: PowerShellOptions);
        success$: Subject<any[]>();
        error$: Subject<any[]>();
        warning$: Subject<any[]>();
        verbose$: Subject<any[]>();
        debug$: Subject<any[]>();
        info$: Subject<any[]>();
        call(string: string, format: Format = 'json'): SubjectWithPromise<PowerShellStreams>;
        destroy(): boolean;
    }

    Note: SubjectWithPromise will only emit the first value returned by PowerShell, this could be a warning, error, etc. Use the streams postfixed with $ to handle all output from PowerShell.

    PowerShellStreams object.

    Emittied by the <Observable|Promise> returned from .call().subscribe() and .call().promise(), respectively.

    interface PowerShellStreams {
        success: any[];
        error: any[];
        warning: any[];
        verbose: any[];
        debug: any[];
        info: any[];
    }

    PowerShellOptions object.

    Optional configuration options for the PowerShell class.

    interface PowerShellOptions {
        tmp_dir?: string
        exe_path?: string
        timeout?: number
    }
    • tmp_dir - Change the path for ephemeral '.tmp' files. Must have a trailing slash. (Must be set to /tmp/ when executing on AWS Lambda)

    • exe_path - Explicitly set the path to the PowerShell executable.

    • timeout - Default: 10 minutes. Set number of milliseconds before each call to this shell will timeout. Warning: A timeout will result in the PowerShell child process being terminated and a new process created, any pending calls will be errored and PowerShell context will be lost.

    Semantics

    The subjects provided by the PowerShell class, as well as the singleton observable returned by PowerShell.call all return arrays of either strings or parsed JSON. It's important to note that these arrays reflect the output for each PowerShell command contained in the single string passed to PowerShell.call. So for example, if you were to call PowerShell.call('Get-Date; Get-Date;'), you should expect to receive an Array containing two items in the next emission. However, there are exceptions to this - debug and verbose are newline delimited due to limitations of PowerShell redirection. While they will generally equate to one string per Write-Debug or Write-Verbose, it is up to you to ensure output has not been broken into multiple lines.

    Usage

    Importing:

    ES6

    import { PowerShell } from 'full-powershell';

    CommonJS

    const PowerShell = require('full-powershell');

    Instantiation:

    const shell = new PowerShell();

    Calling PowerShell:

    Pipe result object to ConvertTo-Json before returning:

    shell.call('My-Command');

    Pipe result object to Out-String before returning:

    shell.call('My-Command', 'string');

    Return result object using default string output:

    shell.call('My-Command', null);

    Subscribing to Observables:

    Subscribe directly to a call (observable will complete after first emission):

    shell.call('My-Command')
    .subscribe(
        (res: PowerShellStreams) => {
            /* result handler */
        },
        (err: Error) => {
            /* error handler */
        }
    );

    Subscribe to individual streams (observe all output i.e. all emissions of that type):

    const shell = new PowerShell();
    
    shell.success$
    .subscribe(
        (res: Array<any>) => {
            /* result handler */
        },
        (err: Error) => {
            /* error handler */
        }
    );
    
    shell.error$.subscribe( /* same as success$ */);
    shell.warning$.subscribe( /* same as success$ */);
    shell.verbose$.subscribe( /* same as success$ */);
    shell.debug$.subscribe( /* same as success$ */);
    shell.info$.subscribe( /* same as success$ */);

    Promises:

    The Observable returned by the call method has been extended to expose a function called promise() which returns a promise which will emit the first value returned by the shell.

    shell.call('My-Command')
    .promise()
    .then((res: PowerShellStreams) => {
        /* result handler */
    })

    Example:

    import { PowerShell } from 'full-powershell';
    
    let powershell = new PowerShell();
    
    powershell.success$.subscribe(res => {
        console.log('success:', res)
    });
    
    powershell.error$.subscribe(res => {
        console.log('error:', res)
    });
    
    powershell.warning$.subscribe(res => {
        console.log('warning:', res)
    });
    
    powershell.call('Get-Date', 'json');
    powershell.call('throw "My Error"', 'json');
    
    powershell.call('Get-Date; Write-Warning "My Warning";', 'json')
    .subscribe(
        res => {
            console.log(res.success);
            console.log(res.warning)
        },
        err => {
            console.error(err);
        }
    );

    Install

    npm i full-powershell

    DownloadsWeekly Downloads

    12

    Version

    1.6.0

    License

    MIT

    Unpacked Size

    25.6 kB

    Total Files

    7

    Last publish

    Collaborators

    • daverickdunn