powershell-utils 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts ADDED
@@ -0,0 +1,122 @@
1
+ import type {ExecFileOptions} from 'node:child_process';
2
+
3
+ export type ExecutePowerShellOptions = ExecFileOptions & {
4
+ /**
5
+ Path to PowerShell executable.
6
+
7
+ @default powerShellPath()
8
+ */
9
+ readonly powerShellPath?: string;
10
+ };
11
+
12
+ export type ExecutePowerShellResult = {
13
+ readonly stdout: string;
14
+ readonly stderr: string;
15
+ };
16
+
17
+ /**
18
+ Get the PowerShell executable path on Windows.
19
+
20
+ @returns The path to the PowerShell executable.
21
+
22
+ @example
23
+ ```
24
+ import {powerShellPath} from 'powershell-utils';
25
+
26
+ const psPath = powerShellPath();
27
+ //=> 'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe'
28
+ ```
29
+ */
30
+ export function powerShellPath(): string;
31
+
32
+ /**
33
+ Check if PowerShell is accessible on Windows.
34
+
35
+ This checks if the PowerShell executable exists and has execute permissions. Useful for detecting restricted environments where PowerShell may be disabled by administrators.
36
+
37
+ @returns A promise that resolves to true if PowerShell is accessible, false otherwise.
38
+
39
+ @example
40
+ ```
41
+ import {canAccessPowerShell} from 'powershell-utils';
42
+
43
+ if (await canAccessPowerShell()) {
44
+ console.log('PowerShell is available');
45
+ } else {
46
+ console.log('PowerShell is not accessible');
47
+ }
48
+ ```
49
+ */
50
+ export function canAccessPowerShell(): Promise<boolean>;
51
+
52
+ /**
53
+ Execute a PowerShell command.
54
+
55
+ @param command - The PowerShell command to execute.
56
+ @returns A promise that resolves to the command output.
57
+
58
+ @example
59
+ ```
60
+ import {executePowerShell} from 'powershell-utils';
61
+
62
+ const {stdout} = await executePowerShell('Get-Process');
63
+ console.log(stdout);
64
+ ```
65
+ */
66
+ export function executePowerShell(
67
+ command: string,
68
+ options?: ExecutePowerShellOptions
69
+ ): Promise<ExecutePowerShellResult>;
70
+
71
+ export namespace executePowerShell {
72
+ /**
73
+ Standard PowerShell arguments that prefix the encoded command.
74
+
75
+ Use these when manually building PowerShell execution arguments for `spawn()`, `execFile()`, etc.
76
+
77
+ @example
78
+ ```
79
+ import {executePowerShell} from 'powershell-utils';
80
+
81
+ const arguments_ = [...executePowerShell.argumentsPrefix, encodedCommand];
82
+ childProcess.spawn(powerShellPath(), arguments_);
83
+ ```
84
+ */
85
+ export const argumentsPrefix: readonly string[];
86
+
87
+ /**
88
+ Encode a PowerShell command as Base64 UTF-16LE.
89
+
90
+ This encoding prevents shell escaping issues and ensures complex commands with special characters are executed reliably.
91
+
92
+ @param command - The PowerShell command to encode.
93
+ @returns Base64-encoded command.
94
+
95
+ @example
96
+ ```
97
+ import {executePowerShell} from 'powershell-utils';
98
+
99
+ const encoded = executePowerShell.encodeCommand('Get-Process');
100
+ ```
101
+ */
102
+ export function encodeCommand(command: string): string;
103
+
104
+ /**
105
+ Escape a string argument for use in PowerShell single-quoted strings.
106
+
107
+ @param value - The value to escape.
108
+ @returns Escaped and quoted string ready for PowerShell.
109
+
110
+ @example
111
+ ```
112
+ import {executePowerShell} from 'powershell-utils';
113
+
114
+ const escaped = executePowerShell.escapeArgument("it's a test");
115
+ //=> "'it''s a test'"
116
+
117
+ // Use in command building
118
+ const command = `Start-Process ${executePowerShell.escapeArgument(appName)}`;
119
+ ```
120
+ */
121
+ export function escapeArgument(value: unknown): string;
122
+ }
package/index.js ADDED
@@ -0,0 +1,58 @@
1
+ import process from 'node:process';
2
+ import {Buffer} from 'node:buffer';
3
+ import {promisify} from 'node:util';
4
+ import childProcess from 'node:child_process';
5
+ import fs, {constants as fsConstants} from 'node:fs/promises';
6
+
7
+ const execFile = promisify(childProcess.execFile);
8
+
9
+ export const powerShellPath = () => `${process.env.SYSTEMROOT || process.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
10
+
11
+ // Cache for PowerShell accessibility check
12
+ let canAccessCache;
13
+
14
+ export const canAccessPowerShell = async () => {
15
+ canAccessCache ??= (async () => {
16
+ try {
17
+ await fs.access(powerShellPath(), fsConstants.X_OK);
18
+ return true;
19
+ } catch {
20
+ return false;
21
+ }
22
+ })();
23
+
24
+ return canAccessCache;
25
+ };
26
+
27
+ export const executePowerShell = async (command, options = {}) => {
28
+ const {
29
+ powerShellPath: psPath,
30
+ ...execFileOptions
31
+ } = options;
32
+
33
+ const encodedCommand = executePowerShell.encodeCommand(command);
34
+
35
+ return execFile(
36
+ psPath ?? powerShellPath(),
37
+ [
38
+ ...executePowerShell.argumentsPrefix,
39
+ encodedCommand,
40
+ ],
41
+ {
42
+ encoding: 'utf8',
43
+ ...execFileOptions,
44
+ },
45
+ );
46
+ };
47
+
48
+ executePowerShell.argumentsPrefix = [
49
+ '-NoProfile',
50
+ '-NonInteractive',
51
+ '-ExecutionPolicy',
52
+ 'Bypass',
53
+ '-EncodedCommand',
54
+ ];
55
+
56
+ executePowerShell.encodeCommand = command => Buffer.from(command, 'utf16le').toString('base64');
57
+
58
+ executePowerShell.escapeArgument = value => `'${String(value).replaceAll('\'', '\'\'')}'`;
package/license ADDED
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "powershell-utils",
3
+ "version": "0.1.0",
4
+ "description": "Utilities for executing PowerShell commands",
5
+ "license": "MIT",
6
+ "repository": "sindresorhus/powershell-utils",
7
+ "funding": "https://github.com/sponsors/sindresorhus",
8
+ "author": {
9
+ "name": "Sindre Sorhus",
10
+ "email": "sindresorhus@gmail.com",
11
+ "url": "https://sindresorhus.com"
12
+ },
13
+ "type": "module",
14
+ "exports": {
15
+ "types": "./index.d.ts",
16
+ "default": "./index.js"
17
+ },
18
+ "sideEffects": false,
19
+ "engines": {
20
+ "node": ">=20"
21
+ },
22
+ "scripts": {
23
+ "test": "xo && ava && tsc index.d.ts --skipLibCheck"
24
+ },
25
+ "files": [
26
+ "index.js",
27
+ "index.d.ts"
28
+ ],
29
+ "keywords": [
30
+ "powershell",
31
+ "windows",
32
+ "execute",
33
+ "command",
34
+ "shell",
35
+ "console",
36
+ "terminal",
37
+ "cli",
38
+ "spawn",
39
+ "exec",
40
+ "utilities"
41
+ ],
42
+ "devDependencies": {
43
+ "ava": "^6.4.1",
44
+ "typescript": "^5.9.3",
45
+ "xo": "^0.59.0"
46
+ }
47
+ }
package/readme.md ADDED
@@ -0,0 +1,153 @@
1
+ # powershell-utils
2
+
3
+ > Utilities for executing PowerShell commands
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ npm install powershell-utils
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```js
14
+ import {executePowerShell, powerShellPath} from 'powershell-utils';
15
+
16
+ // Execute a PowerShell command
17
+ const {stdout} = await executePowerShell('Get-Process');
18
+ console.log(stdout);
19
+
20
+ // Get PowerShell path
21
+ console.log(powerShellPath());
22
+ //=> 'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe'
23
+ ```
24
+
25
+ ## API
26
+
27
+ ### powerShellPath()
28
+
29
+ Returns: `string`
30
+
31
+ Get the PowerShell executable path on Windows.
32
+
33
+ ```js
34
+ import {powerShellPath} from 'powershell-utils';
35
+
36
+ const psPath = powerShellPath();
37
+ //=> 'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe'
38
+ ```
39
+
40
+ ### canAccessPowerShell()
41
+
42
+ Returns: `Promise<boolean>`
43
+
44
+ Check if PowerShell is accessible on Windows.
45
+
46
+ This checks if the PowerShell executable exists and has execute permissions. Useful for detecting restricted environments where PowerShell may be disabled by administrators.
47
+
48
+ ```js
49
+ import {canAccessPowerShell} from 'powershell-utils';
50
+
51
+ if (await canAccessPowerShell()) {
52
+ console.log('PowerShell is available');
53
+ } else {
54
+ console.log('PowerShell is not accessible');
55
+ }
56
+ ```
57
+
58
+ ### executePowerShell(command, options?)
59
+
60
+ Returns: `Promise<{stdout: string, stderr: string}>`
61
+
62
+ Execute a PowerShell command.
63
+
64
+ ```js
65
+ import {executePowerShell} from 'powershell-utils';
66
+
67
+ // Execute a PowerShell command
68
+ const {stdout} = await executePowerShell('Get-Process');
69
+ console.log(stdout);
70
+ ```
71
+
72
+ #### command
73
+
74
+ Type: `string`
75
+
76
+ The PowerShell command to execute.
77
+
78
+ #### options
79
+
80
+ Type: `object`
81
+
82
+ The below option and also all options in Node.js [`child_process.execFile()`](https://nodejs.org/api/child_process.html#child_processexecfilefile-args-options-callback) are supported.
83
+
84
+ ##### powerShellPath
85
+
86
+ Type: `string`\
87
+ Default: `powerShellPath()`
88
+
89
+ Path to PowerShell executable. Useful when calling from WSL or when PowerShell is in a non-standard location.
90
+
91
+ ##### encoding
92
+
93
+ Type: `string`\
94
+ Default: `'utf8'`
95
+
96
+ Character encoding for stdout and stderr.
97
+
98
+ ### executePowerShell.argumentsPrefix
99
+
100
+ Type: `string[]`
101
+
102
+ Standard PowerShell arguments that prefix the encoded command.
103
+
104
+ Use these when manually building PowerShell execution arguments for `spawn()`, `execFile()`, etc.
105
+
106
+ ```js
107
+ import {executePowerShell} from 'powershell-utils';
108
+
109
+ const arguments_ = [...executePowerShell.argumentsPrefix, encodedCommand];
110
+ childProcess.spawn(powerShellPath(), arguments_);
111
+ ```
112
+
113
+ ### executePowerShell.encodeCommand(command)
114
+
115
+ Returns: `string`
116
+
117
+ Encode a PowerShell command as Base64 UTF-16LE.
118
+
119
+ This encoding prevents shell escaping issues and ensures complex commands with special characters are executed reliably.
120
+
121
+ #### command
122
+
123
+ Type: `string`
124
+
125
+ The PowerShell command to encode.
126
+
127
+ ```js
128
+ import {executePowerShell} from 'powershell-utils';
129
+
130
+ const encoded = executePowerShell.encodeCommand('Get-Process');
131
+ ```
132
+
133
+ ### executePowerShell.escapeArgument(value)
134
+
135
+ Returns: `string`
136
+
137
+ Escape a string argument for use in PowerShell single-quoted strings.
138
+
139
+ #### value
140
+
141
+ Type: `unknown`
142
+
143
+ The value to escape.
144
+
145
+ ```js
146
+ import {executePowerShell} from 'powershell-utils';
147
+
148
+ const escaped = executePowerShell.escapeArgument("it's a test");
149
+ //=> "'it''s a test'"
150
+
151
+ // Use in command building
152
+ const command = `Start-Process ${executePowerShell.escapeArgument(appName)}`;
153
+ ```