Installation und Einrichtung
Voraussetzungen
- PowerShell 7.0+
# Überprüfung der PowerShell-Version $PSVersionTable.PSVersion # Installation von PowerShell 7 (falls erforderlich) # Download von https://github.com/PowerShell/PowerShell - Zugriffsrechte
- Für Ports < 1024 sind Administratorrechte erforderlich.
- Berechtigungen zur Ausführung von PowerShell-Skripten.
- Konfiguration der Ausführungsrichtlinie (Execution Policy)
# Überprüfung der aktuellen Richtlinie Get-ExecutionPolicy # Festlegen der Richtlinie, um die Ausführung von Skripten zu erlauben Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Erstmalige Einrichtung
- Navigation zum Serververzeichnis
# Wechsel in das Stammverzeichnis des Moduls cd C:\powershell\modules\mcp-powershell-server # Wechsel zu den Servern cd src\servers - Überprüfung der Dateien
powershell # Stellen Sie sicher, dass alle notwendigen Dateien vorhanden sind Get-ChildItem *.ps1 | Select-Object Name
Wahl des Betriebsmodus: HTTP vs. STDIO
Bevor wir ins Detail gehen, ist es wichtig zu verstehen, welcher der beiden Betriebsmodi des Servers für Sie geeignet ist. Die Wahl hängt davon ab, wie und von wo Sie Befehle senden möchten.
- HTTP-Modus (
mcp-powershell-http.ps1): Funktioniert wie ein Webservice. Er nimmt Befehle über das Netzwerk (HTTP) entgegen und kann von anderen Computern oder aus Webanwendungen heraus aufgerufen werden. Dies ist eine universelle Methode für Netzwerkintegrationen. - STDIO-Modus (
mcp-powershell-stdio.ps1): Funktioniert wie eine Konsolenanwendung, die von einem anderen Prozess gesteuert wird. Er empfängt Befehle über den Standard-Eingabestrom (Standard Input) und gibt das Ergebnis über den Standard-Ausgabestrom (Standard Output) zurück. Diese Methode ist ideal für die lokale Integration, zum Beispiel mitgemini-cli.
Wann sollte der HTTP-Modus verwendet werden?
Wählen Sie HTTP, wenn Sie Netzwerkzugriff benötigen:
- Fernverwaltung: Die Client-Anwendung (z. B. ein Python-Skript) befindet sich auf einem anderen Computer.
- Web-Integration: Sie möchten PowerShell aus einem Web-Panel aufrufen, indem Sie Anfragen mit JavaScript senden.
- Microservice-Architektur: Verschiedene Dienste in Ihrem Netzwerk müssen Befehle austauschen.
- Einfaches Testen: Sie möchten Befehle mit Werkzeugen wie
curloder Postman senden.
Schlüsselszenario: Client und Server befinden sich in einem Netzwerk und kommunizieren über Standard-Webprotokolle.
Wann sollte der STDIO-Modus verwendet werden?
Wählen Sie STDIO für eine lokale und sicherere Integration:
- Integration mit Gemini CLI: Dies ist das Haupt- und häufigste Szenario.
gemini-clistartetmcp-powershell-stdio.ps1als untergeordneten Prozess und kommuniziert direkt mit ihm. - Lokale Wrapper-Skripte: Ihre Anwendung in einer anderen Sprache (z. B. Node.js) startet den PowerShell-Server als untergeordneten Prozess und verwaltet ihn.
- Erhöhte Sicherheit: Dieser Modus öffnet keine Netzwerkports, was eine ganze Klasse von Netzwerkbedrohungen ausschließt.
Schlüsselszenario: Client und Server laufen auf derselben Maschine, und der Client verwaltet den Lebenszyklus des Servers selbst.
Nachdem Sie sich für einen Modus entschieden haben, gehen Sie zum entsprechenden Abschnitt unten, um detaillierte Anweisungen zum Starten und Verwenden zu erhalten.
STDIO-Modus
Der STDIO-Modus ist für die Integration mit MCP-Clients wie gemini-cli vorgesehen.
Starten des STDIO-Servers
# Direkter Start des Servers (aus dem Ordner src/servers)
.\mcp-powershell-stdio.ps1
# Oder aus dem Projektstammverzeichnis
.\src\servers\mcp-powershell-stdio.ps1
Merkmale des STDIO-Modus
- Protokoll: JSON-RPC über Standard-Ein-/Ausgabeströme
- Protokollierung: In die Datei
%TEMP%\mcp-powershell-server.log - Zeichenkodierung: UTF-8 für die korrekte Verarbeitung von Sonderzeichen
- Kompatibilität: Funktioniert mit allen MCP-Clients
Testen des STDIO-Modus
# Starten des Testservers zur Überprüfung (aus dem Ordner src/servers)
.\test-mcp.ps1
# Oder aus dem Projektstammverzeichnis
.\src\servers\test-mcp.ps1
Beispiel für manuelle Tests:
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05"}}
{"jsonrpc":"2.0","id":2,"method":"tools/list"}
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"run-script","arguments":{"script":"Get-Date"}}}
HTTP-Modus
Der HTTP-Modus ist für Web-Integrationen und REST-APIs vorgesehen.
Starten des HTTP-Servers
# Grundlegender Start (localhost:8090) aus dem Ordner src/servers
.\mcp-powershell-http.ps1
# Start auf einem anderen Port
.\mcp-powershell-http.ps1 -Port 9090
# Start auf allen Netzwerkschnittstellen
.\mcp-powershell-http.ps1 -ServerHost "0.0.0.0" -Port 8080
# Start mit einer Konfigurationsdatei
.\mcp-powershell-http.ps1 -ConfigFile "config.json"
# Oder aus dem Projektstammverzeichnis
.\src\servers\mcp-powershell-http.ps1 -Port 8090
HTTP-API-Endpunkte
Alle Anfragen werden als POST an die Stamm-URL des Servers gesendet.
URL: http://localhost:8090/
Methode: POST
Content-Type: application/json
Testen des HTTP-Modus
# Test mit Invoke-RestMethod
$body = @{
jsonrpc = "2.0"
id = 1
method = "tools/list"
} | ConvertTo-Json
Invoke-RestMethod -Uri "http://localhost:8090/" -Method POST -Body $body -ContentType "application/json"
# Test mit curl
curl -X POST http://localhost:8090/ \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Integration mit Gemini CLI
Automatische Einrichtung
# Start mit automatischer Einrichtung für Gemini CLI
.\start-mcp-with-gemini.ps1 -ApiKey "ihr-gemini-api-schluessel"
# Mit zusätzlichen Parametern
.\start-mcp-with-gemini.ps1 -ApiKey "ihr-schluessel" -ServerPort 9090 -Wait 15
Manuelle Einrichtung
- Erstellen der MCP-Konfiguration
# Erstellen des Konfigurationsverzeichnisses $configDir = "$env:USERPROFILE\.config\gemini" New-Item -Path $configDir -ItemType Directory -Force # Erstellen der MCP-Konfigurationsdatei $config = @{ mcpServers = @{ powershell = @{ command = "pwsh" args = @("-File", "C:\pfad\zu\mcp-powershell-stdio.ps1") env = @{} } } } | ConvertTo-Json -Depth 5 $config | Set-Content "$configDir\mcp_servers.json" -Encoding UTF8 - Verwendung mit gemini-cli
# Interaktiver Modus gemini --mcp-config "pfad/zu/mcp_servers.json" -i # Einzelne Anfrage gemini --mcp-config "pfad/zu/mcp_servers.json" -m gemini-2.5-pro -p "Führe den Befehl Get-Process | Select-Object -First 5 aus"
Anwendungsbeispiele
Grundlegende PowerShell-Befehle
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "run-script",
"arguments": {
"script": "Get-ComputerInfo | Select-Object WindowsProductName, TotalPhysicalMemory"
}
}
}
Arbeiten mit Dateien
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "run-script",
"arguments": {
"script": "Get-ChildItem C:\\ -Directory | Select-Object Name, CreationTime | Format-Table",
"workingDirectory": "C:\\",
"timeoutSeconds": 30
}
}
}
Skripte mit Parametern
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "run-script",
"arguments": {
"script": "param($ProcessName) Get-Process -Name $ProcessName -ErrorAction SilentlyContinue",
"parameters": {
"ProcessName": "notepad"
}
}
}
}
Systemüberwachung
{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "run-script",
"arguments": {
"script": "$cpu = Get-Counter '\\Processor(_Total)\\% Processor Time' | Select-Object -ExpandProperty CounterSamples | Select-Object -ExpandProperty CookedValue; $memory = Get-Counter '\\Memory\\Available MBytes' | Select-Object -ExpandProperty CounterSamples | Select-Object -ExpandProperty CookedValue; Write-Output \"CPU: $([math]::Round($cpu, 2))%, Available Memory: $memory MB\""
}
}
}
Konfiguration
Die Datei config.json
{
"Port": 8090,
"Host": "localhost",
"MaxConcurrentRequests": 10,
"TimeoutSeconds": 300,
"LogLevel": "INFO",
"AllowedPaths": [
"C:\\Scripts\\",
"C:\\Tools\\",
"C:\\Temp\\"
],
"Security": {
"EnableScriptValidation": true,
"BlockDangerousCommands": true,
"RestrictedCommands": [
"Remove-Item",
"Format-Volume",
"Stop-Computer",
"Restart-Computer",
"New-ItemProperty -Path 'HKLM:*'",
"Remove-ItemProperty -Path 'HKLM:*'"
],
"AllowedModules": [
"Microsoft.PowerShell.*",
"PackageManagement",
"PowerShellGet"
]
},
"Logging": {
"LogFile": "%TEMP%\\mcp-powershell-server.log",
"MaxLogSize": "10MB",
"LogRotation": true
}
}
Umgebungsvariablen
# Konfiguration über Umgebungsvariablen
$env:MCP_PS_PORT = "8090"
$env:MCP_PS_HOST = "localhost"
$env:MCP_PS_TIMEOUT = "300"
$env:MCP_PS_LOG_LEVEL = "INFO"
Sicherheit
Sicherheitsempfehlungen
- Befehlseinschränkung
json "RestrictedCommands": [ "Remove-Item", "Format-Volume", "Stop-Computer", "Restart-Computer", "Invoke-Expression", "iex", "& *" ] - Pfadeinschränkung
json "AllowedPaths": [ "C:\\Scripts\\", "C:\\Tools\\", "C:\\Temp\\" ] - Netzwerkeinschränkungen
powershell # Zugriff nur auf den lokalen Host beschränken .\start-mcp-server.ps1 -ServerHost "127.0.0.1" - Timeouts
json "TimeoutSeconds": 60 // Ausführungszeit begrenzen
Überwachung und Protokollierung
# Protokolle in Echtzeit überwachen
Get-Content "$env:TEMP\mcp-powershell-server.log" -Wait -Tail 10
# Ausgeführte Befehle analysieren
Select-String -Path "$env:TEMP\mcp-powershell-server.log" -Pattern "Führe PowerShell-Skript aus"
Erweiterung der Funktionalität
Hinzufügen neuer MCP-Werkzeuge
- Struktur des Werkzeugs
# Fügen Sie in der Funktion Invoke-MCPMethod einen neuen case hinzu "mein-benutzerdefiniertes-werkzeug" { # Parameter validieren if (-not $arguments.ContainsKey("erforderlicher_param")) { return New-MCPResponse -Id $Id -Error @{ code = -32602 message = "Fehlender erforderlicher Parameter 'erforderlicher_param'" } }# Ausführungslogik $result = Invoke-MeineEigeneFunktion -Param $arguments.erforderlicher_param # Ergebnis zurückgeben return New-MCPResponse -Id $Id -Result @{ content = @( @{ type = "text" text = "Ergebnis: $result" } ) }} - Registrierung in
tools/listpowershell # Fügen Sie die Beschreibung des Werkzeugs zur Methode tools/list hinzu @{ name = "mein-benutzerdefiniertes-werkzeug" description = "Beschreibung meines Werkzeugs" inputSchema = @{ type = "object" properties = @{ erforderlicher_param = @{ type = "string" description = "Ein erforderlicher Parameter" } } required = @("erforderlicher_param") } }
Beispiel für ein benutzerdefiniertes Werkzeug
# Hinzufügen eines Werkzeugs zur Abfrage der Registrierung
"registry-query" {
if (-not $arguments.ContainsKey("path")) {
return New-MCPResponse -Id $Id -Error @{
code = -32602
message = "Fehlender erforderlicher Parameter 'path'"
}
}
try {
$regPath = $arguments.path
$regKey = Get-ItemProperty -Path $regPath -ErrorAction Stop
$result = $regKey | Format-List | Out-String
return New-MCPResponse -Id $Id -Result @{
content = @(
@{
type = "text"
text = "Registrierungswerte unter ${regPath}:`n$result"
}
)
}
}
catch {
return New-MCPResponse -Id $Id -Error @{
code = -32603
message = "Registrierungsabfrage fehlgeschlagen: $($_.Exception.Message)"
}
}
}
Fehlerbehebung
Diagnosebefehle
# PowerShell-Version überprüfen
$PSVersionTable.PSVersion
# Portverfügbarkeit prüfen
Test-NetConnection -ComputerName localhost -Port 8090
# Protokolle überprüfen
Get-Content "$env:TEMP\mcp-powershell-server.log" -Tail 50
# PowerShell-Prozesse überprüfen
Get-Process -Name pwsh*
Häufige Probleme
- „Port wird bereits verwendet“
# Prozess finden, der den Port verwendet Get-NetTCPConnection -LocalPort 8090 | Get-Process # Oder einen anderen Port verwenden .\start-mcp-server.ps1 -Port 9090 - „Zugriff verweigert“
powershell # Mit Administratorrechten für Ports < 1024 starten Start-Process pwsh -Verb RunAs -ArgumentList "-File", "start-mcp-server.ps1" - „Probleme mit der Zeichenkodierung“
# Konsolenkodierung überprüfen [Console]::OutputEncoding [Console]::InputEncoding # UTF-8 erzwingen [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 [Console]::InputEncoding = [System.Text.Encoding]::UTF8 - „Skript wird nicht ausgeführt“
# Ausführungsrichtlinie überprüfen Get-ExecutionPolicy -List # Vorübergehend erlauben powershell.exe -ExecutionPolicy Bypass -File "script.ps1"
Debugging
# Detaillierte Protokollierung aktivieren
$DebugPreference = "Continue"
# Skriptausführung verfolgen
Set-PSDebug -Trace 1
# Verfolgung deaktivieren
Set-PSDebug -Off
API-Referenz
MCP-Methoden
initialize
Initialisiert den MCP-Server.
Anfrage (Request):
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05"
}
}
Antwort (Response):
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2024-11-05",
"capabilities": {
"tools": {
"listChanged": true
}
},
"serverInfo": {
"name": "PowerShell Script Runner",
"version": "1.0.0",
"description": "Führt PowerShell-Skripte über MCP aus"
}
}
}
tools/list
Ruft die Liste der verfügbaren Werkzeuge ab.
Anfrage (Request):
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list"
}
Antwort (Response):
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"tools": [
{
"name": "run-script",
"description": "Führt ein PowerShell-Skript mit angegebenen Parametern aus",
"inputSchema": {
"type": "object",
"properties": {
"script": {
"type": "string",
"description": "Auszuführender PowerShell-Code"
},
"parameters": {
"type": "object",
"description": "Parameter für das Skript (optional)"
},
"workingDirectory": {
"type": "string",
"description": "Arbeitsverzeichnis für die Ausführung"
},
"timeoutSeconds": {
"type": "integer",
"description": "Ausführungs-Timeout in Sekunden",
"default": 300,
"minimum": 1,
"maximum": 3600
}
},
"required": ["script"]
}
}
]
}
}
tools/call
Führt ein Werkzeug aus.
Anfrage (Request):
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "run-script",
"arguments": {
"script": "Get-Date",
"timeoutSeconds": 30
}
}
}
Antwort (Response):
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"content": [
{
"type": "text",
"text": "Befehlsausgabe:\n```\nDienstag, 25. September 2025 14:30:45\n```"
}
],
"isError": false,
"_meta": {
"executionTime": "2025-09-25 14:30:45",
"success": true,
"errorCount": 0,
"warningCount": 0
}
}
}
Fehlercodes
| Code | Beschreibung |
|---|---|
| -32700 | Parse error – Fehler beim Parsen von JSON |
| -32600 | Invalid Request – Ungültige Anfrage |
| -32601 | Method not found – Methode nicht gefunden |
| -32602 | Invalid params – Ungültige Parameter |
| -32603 | Internal error – Interner Serverfehler |
Protokollierungsstufen
| Stufe | Beschreibung |
|---|---|
| DEBUG | Detaillierte Debuginformationen |
| INFO | Allgemeine Betriebsinformationen |
| WARNING | Warnungen vor potenziellen Problemen |
| ERROR | Fehler, die Aufmerksamkeit erfordern |
Fazit
Der MCP PowerShell Server bietet eine leistungsstarke und sichere Möglichkeit, PowerShell über das standardisierte MCP-Protokoll in KI-Assistenten und andere Anwendungen zu integrieren. Befolgen Sie die Sicherheitsempfehlungen und verwenden Sie die Protokollierung, um den Betrieb des Servers zu überwachen.