index.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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. const execFile = promisify(childProcess.execFile);
  7. export const powerShellPath = () => `${process.env.SYSTEMROOT || process.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
  8. // Cache for PowerShell accessibility check
  9. let canAccessCache;
  10. export const canAccessPowerShell = async () => {
  11. canAccessCache ??= (async () => {
  12. try {
  13. await fs.access(powerShellPath(), fsConstants.X_OK);
  14. return true;
  15. } catch {
  16. return false;
  17. }
  18. })();
  19. return canAccessCache;
  20. };
  21. const argumentsPrefix = [
  22. '-NoProfile',
  23. '-NonInteractive',
  24. '-ExecutionPolicy',
  25. 'Bypass',
  26. '-EncodedCommand',
  27. ];
  28. const encodeCommand = command => Buffer.from(command, 'utf16le').toString('base64');
  29. const escapeArgument = value => `'${String(value).replaceAll('\'', '\'\'')}'`;
  30. const createArguments = command => [...argumentsPrefix, encodeCommand(command)];
  31. export const executePowerShell = async (command, options = {}) => {
  32. const {
  33. powerShellPath: psPath,
  34. ...execFileOptions
  35. } = options;
  36. return execFile(
  37. psPath ?? powerShellPath(),
  38. createArguments(command),
  39. {
  40. encoding: 'utf8',
  41. ...execFileOptions,
  42. },
  43. );
  44. };
  45. executePowerShell.argumentsPrefix = argumentsPrefix;
  46. executePowerShell.encodeCommand = encodeCommand;
  47. executePowerShell.escapeArgument = escapeArgument;
  48. executePowerShell.createArguments = createArguments;
  49. export const executePowerShellSync = (command, options = {}) => {
  50. const {
  51. powerShellPath: psPath,
  52. ...execFileOptions
  53. } = options;
  54. return childProcess.execFileSync(
  55. psPath ?? powerShellPath(),
  56. createArguments(command),
  57. {
  58. encoding: 'utf8',
  59. ...execFileOptions,
  60. },
  61. );
  62. };