/**
* PowerShell 命令执行工具
*/
import { exec } from 'child_process';
import { promisify } from 'util';
const execAsync = promisify(exec);
export class PowerShellTools {
getToolDefinitions() {
return [
{
name: 'run_powershell',
description: '执行 PowerShell 命令或脚本',
inputSchema: {
type: 'object',
properties: {
command: { type: 'string', description: 'PowerShell 命令或脚本' },
timeout: { type: 'number', description: '超时时间(毫秒,可选)' },
},
required: ['command'],
},
},
{
name: 'run_cmd',
description: '执行 CMD 命令',
inputSchema: {
type: 'object',
properties: {
command: { type: 'string', description: 'CMD 命令' },
timeout: { type: 'number', description: '超时时间(毫秒,可选)' },
},
required: ['command'],
},
},
{
name: 'get_system_info',
description: '获取系统信息',
inputSchema: {
type: 'object',
properties: {},
},
},
{
name: 'get_disk_info',
description: '获取磁盘信息',
inputSchema: {
type: 'object',
properties: {},
},
},
{
name: 'get_network_info',
description: '获取网络信息',
inputSchema: {
type: 'object',
properties: {},
},
},
];
}
canHandle(toolName) {
const tools = ['run_powershell', 'run_cmd', 'get_system_info',
'get_disk_info', 'get_network_info'];
return tools.includes(toolName);
}
async executeTool(name, args) {
switch (name) {
case 'run_powershell':
return await this.runPowerShell(args.command, args.timeout);
case 'run_cmd':
return await this.runCmd(args.command, args.timeout);
case 'get_system_info':
return await this.getSystemInfo();
case 'get_disk_info':
return await this.getDiskInfo();
case 'get_network_info':
return await this.getNetworkInfo();
default:
throw new Error(`未知工具: ${name}`);
}
}
async runPowerShell(command, timeout = 30000) {
try {
const { stdout, stderr } = await execAsync(
`powershell -Command "${command.replace(/"/g, '\\"')}"`,
{
shell: 'powershell.exe',
timeout,
maxBuffer: 1024 * 1024 * 10, // 10MB
}
);
return {
success: true,
output: stdout.trim(),
error: stderr.trim(),
command
};
} catch (error) {
return { success: false, error: error.message, command };
}
}
async runCmd(command, timeout = 30000) {
try {
const { stdout, stderr } = await execAsync(command, {
shell: 'cmd.exe',
timeout,
maxBuffer: 1024 * 1024 * 10,
});
return {
success: true,
output: stdout.trim(),
error: stderr.trim(),
command
};
} catch (error) {
return { success: false, error: error.message, command };
}
}
async getSystemInfo() {
try {
const command = `
$os = Get-CimInstance Win32_OperatingSystem
$cs = Get-CimInstance Win32_ComputerSystem
$cpu = Get-CimInstance Win32_Processor
@{
ComputerName = $cs.Name
OS = $os.Caption
Version = $os.Version
Architecture = $os.OSArchitecture
Manufacturer = $cs.Manufacturer
Model = $cs.Model
TotalMemoryGB = [math]::Round($cs.TotalPhysicalMemory / 1GB, 2)
CPU = $cpu.Name
CPUCores = $cpu.NumberOfCores
CPULogical = $cpu.NumberOfLogicalProcessors
} | ConvertTo-Json
`;
const { stdout } = await execAsync(`powershell -Command "${command.replace(/"/g, '\\"')}"`, {
shell: 'powershell.exe'
});
const info = JSON.parse(stdout);
return { success: true, info };
} catch (error) {
return { success: false, error: error.message };
}
}
async getDiskInfo() {
try {
const command = `
Get-PSDrive -PSProvider FileSystem | Where-Object { $_.Used -ne $null } | ForEach-Object {
@{
Drive = $_.Name
TotalGB = [math]::Round($_.Used / 1GB + $_.Free / 1GB, 2)
UsedGB = [math]::Round($_.Used / 1GB, 2)
FreeGB = [math]::Round($_.Free / 1GB, 2)
PercentUsed = [math]::Round(($_.Used / ($_.Used + $_.Free)) * 100, 2)
}
} | ConvertTo-Json
`;
const { stdout } = await execAsync(`powershell -Command "${command.replace(/"/g, '\\"')}"`, {
shell: 'powershell.exe'
});
let disks = JSON.parse(stdout);
if (!Array.isArray(disks)) {
disks = [disks];
}
return { success: true, disks };
} catch (error) {
return { success: false, error: error.message };
}
}
async getNetworkInfo() {
try {
const command = `
Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.InterfaceAlias -notlike '*Loopback*' } | ForEach-Object {
@{
Interface = $_.InterfaceAlias
IPAddress = $_.IPAddress
PrefixLength = $_.PrefixLength
}
} | ConvertTo-Json
`;
const { stdout } = await execAsync(`powershell -Command "${command.replace(/"/g, '\\"')}"`, {
shell: 'powershell.exe'
});
let interfaces = [];
try {
interfaces = JSON.parse(stdout);
if (!Array.isArray(interfaces)) {
interfaces = [interfaces];
}
} catch {
interfaces = [];
}
return { success: true, interfaces };
} catch (error) {
return { success: false, error: error.message };
}
}
}