xp_cmdshell (Transact-SQL)

Erzeugt eine Windows-Befehlsshell und übergibt eine Zeichenfolge für die Ausführung. Die Ausgabe wird ggf. in Textzeilen zurückgegeben.

Themenlink (Symbol)Transact-SQL-Syntaxkonventionen

Syntax

xp_cmdshell { 'command_string' } [ , no_output ]

Argumente

  • 'command_string'
    Die Zeichenfolge, die einen an das Betriebssystem zu übergebenden Befehl enthält. command_string ist vom Datentyp varchar(8000) oder nvarchar(4000) und hat keinen Standardwert. command_string darf maximal einen Satz doppelter Anführungszeichen enthalten. Wenn Leerzeichen in den Dateipfaden oder Programmnamen enthalten sind, auf die von command_string verwiesen wird, ist ein einzelnes Paar Anführungszeichen erforderlich. Wenn Probleme mit eingebetteten Leerzeichen auftreten, sollten Sie FAT 8.3-Dateinamen verwenden, um dieses Problem zu umgehen.

  • no_output
    Ein optionaler Parameter, der angibt, dass keine Ausgabe an den Client zurückgegeben werden soll.

Rückgabecodewerte

0 (Erfolg) oder 1 (Fehler)

Resultsets

Mit der folgenden xp_cmdshell-Anweisung wird eine Verzeichnisaufstellung des aktuellen Verzeichnisses zurückgegeben.

EXEC xp_cmdshell 'dir *.exe';
GO

Die Zeilen werden in einer Spalte vom Datentyp nvarchar(255) zurückgegeben. Falls die no_output-Option verwendet wird, wird nur Folgendes zurückgegeben:

The command(s) completed successfully.

Hinweise

Der von xp_cmdshell erzeugte Windows-Prozess besitzt dieselben Sicherheitsrechte wie das SQL Server-Dienstkonto.

xp_cmdshell wird synchron ausgeführt. Die Steuerung wird erst dann an den Aufrufer zurückgegeben, wenn der Befehl der Befehlsshell abgeschlossen wurde.

xp_cmdshell kann mithilfe der richtlinienbasierten Verwaltung und durch Ausführen von sp_configure aktiviert und deaktiviert werden. Weitere Informationen finden Sie unter Grundlegendes zur Oberflächenkonfiguration und xp_cmdshell (Option).

Wichtiger HinweisWichtig

Falls xp_cmdshell innerhalb eines Batches ausgeführt wird und einen Fehler zurückgibt, erzeugt der Batch einen Fehler. Dieses Verhalten wurde geändert. In früheren Versionen von Microsoft SQL Server wurde der Batch weiterhin ausgeführt.

xp_cmdshell-Proxykonto

Wenn ein Benutzer, der nicht Mitglied der festen Serverrolle sysadmin ist, xp_cmdshell aufruft, wird eine Verbindung mit Windows mithilfe des Kontonamens und Kennworts hergestellt, die in den Anmeldeinformationen mit dem Namen ##xp_cmdshell_proxy_account## gespeichert sind. Falls diese Proxyanmeldeinformationen nicht vorhanden sind, erzeugt xp_cmdshell einen Fehler.

Die Proxykonto-Anmeldeinformationen können durch Ausführen von sp_xp_cmdshell_proxy_account erstellt werden. Als Argumente besitzt diese gespeicherte Prozedur einen Windows-Benutzernamen und ein Kennwort. Mit dem folgenden Befehl werden z. B. Proxyanmeldeinformationen für den Windows-Domänenbenutzer SHIPPING\KobeR erstellt, der das Windows-Kennwort sdfh%dkc93vcMt0 besitzt.

EXEC sp_xp_cmdshell_proxy_account 'SHIPPING\KobeR','sdfh%dkc93vcMt0'

Weitere Informationen finden Sie unter sp_xp_cmdshell_proxy_account (Transact-SQL).

Berechtigungen

Da böswillige Benutzer manchmal versuchen, mit xp_cmdshell höhere Berechtigungen zu erlangen, ist xp_cmdshell standardmäßig deaktiviert. Verwenden Sie sp_configure oder die richtlinienbasierte Verwaltung, um es zu aktivieren. Weitere Informationen finden Sie unter xp_cmdshell (Option).

Wenn xp_cmdshell erstmalig aktiviert wird, muss die CONTROL SERVER-Berechtigung zur Ausführung verfügbar sein und der von xp_cmdshell erstellte Windows-Prozess muss den gleichen Sicherheitskontext wie das SQL Server-Dienstkonto aufweisen. Das SQL Server-Dienstkonto verfügt oft über mehr Berechtigungen als zur Ausführung des durch xp_cmdshell erstellten Prozesses benötigt werden. Um die Sicherheit zu erhöhen, sollte der Zugriff auf xp_cmdshell Benutzern mit weit reichenden Berechtigungen vorbehalten bleiben.

Führen Sie die folgenden Schritte aus, um Nichtadministratoren die Verwendung von xp_cmdshell zu erlauben und SQL Server die Erstellung untergeordneter Prozesse mit dem Sicherheitstoken eines Kontos mit eingeschränkteren Rechten zu ermöglichen:

  1. Erstellen Sie ein lokales Windows-Benutzerkonto oder ein Domänenkonto mit den geringsten Berechtigungen, die von den Prozessen benötigt werden, und passen Sie es an.

  2. Verwenden Sie die sp_xp_cmdshell_proxy_account-Systemprozedur, um xp_cmdshell für die Verwendung des Kontos mit den geringsten Berechtigungen zu konfigurieren.

    HinweisHinweis

    Sie können dieses Proxykonto auch mit SQL Server Management Studio konfigurieren, indem Sie mit der rechten Maustaste im Objekt-Explorer unter Eigenschaften auf Ihren Servernamen klicken und auf der Registerkarte Sicherheit in den Abschnitt Serverproxykonto wechseln.

  3. Führen Sie in Management Studio unter Verwendung der master-Datenbank die GRANT exec ON xp_cmdshell TO '<somelogin>'-Anweisung aus, um bestimmten Nicht-sysadmin-Benutzern die Ausführung von xp_cmdshell zu ermöglichen. Der angegebene Anmeldename muss einem Benutzer in der master-Datenbank zugeordnet sein.

Jetzt können Nichtadministratoren Betriebssystemprozesse mit xp_cmdshell starten; die Prozesse werden mit den Berechtigungen des von Ihnen konfigurierten Proxykontos ausgeführt. Benutzer mit der CONTROL SERVER-Berechtigung (Mitglieder der festen Serverrolle sysadmin) erhalten weiterhin die Berechtigungen des SQL Server-Dienstkontos für untergeordnete Prozesse, die von xp_cmdshell gestartet werden.

Um das Windows-Konto zu bestimmen, das von xp_cmdshell beim Starten von Betriebssystemprozessen verwendet wird, führen Sie die folgende Anweisung aus:

xp_cmdshell 'whoami.exe'

Um den Sicherheitskontext für einen anderen Anmeldenamen zu bestimmen, führen Sie folgende Anweisung aus:

EXECUTE AS LOGIN = '<other_login>' ;
GO
xp_cmdshell 'whoami.exe' ;
REVERT ; 

Beispiele

A. Zurückgeben einer Liste der ausführbaren Dateien

Im folgenden Beispiel wird mithilfe der erweiterten gespeicherten Prozedur xp_cmdshell der Befehl DIR ausgeführt.

EXEC master..xp_cmdshell 'dir *.exe'

B. Verwenden der NET-Befehle von Windows

Im folgenden Beispiel wird die Verwendung von xp_cmdshell in einer gespeicherten Prozedur veranschaulicht. In diesem Beispiel werden Benutzer mithilfe von net send darüber benachrichtigt, dass eine Instanz von SQL Server bald heruntergefahren wird. Der Server wird mithilfe von net pause angehalten und anschließend mithilfe von net stop heruntergefahren.

CREATE PROC shutdown10
AS
    EXEC xp_cmdshell 'net send /domain:SQL_USERS ''SQL Server 
        shutting down in 10 minutes. No more connections 
        allowed.', no_output
    EXEC xp_cmdshell 'net pause sqlserver'
    WAITFOR DELAY '00:05:00'
    EXEC xp_cmdshell 'net send /domain: SQL_USERS ''SQL Server 
        shutting down in 5 minutes.', no_output
    WAITFOR DELAY '00:04:00'
    EXEC xp_cmdshell 'net send /domain:SQL_USERS ''SQL Server 
        shutting down in 1 minute. Log off now.', no_output
    WAITFOR DELAY '00:01:00'
    EXEC xp_cmdshell 'net stop sqlserver', no_output

C. Unterdrücken der Ausgabe

Im folgenden Beispiel wird mit xp_cmdshell eine Befehlszeichenfolge ausgeführt, ohne dass die Ausgabe an den Client zurückgegeben wird.

USE master;
EXEC xp_cmdshell 'copy c:\SQLbcks\AdvWorks.bck
    \\server2\backups\SQLbcks, NO_OUTPUT';
GO

D. Verwenden des Rückgabestatus

Im folgenden Beispiel wird von der erweiterten gespeicherten Prozedur xp_cmdshell auch der Rückgabestatus vorgeschlagen. Der Rückgabecodewert wird in der Variablen @result gespeichert.

DECLARE @result int
EXEC @result = xp_cmdshell 'dir *.exe'
IF (@result = 0)
   PRINT 'Success'
ELSE
   PRINT 'Failure'

E. Schreiben des Inhalts von Variablen in eine Datei

Im folgenden Beispiel wird der Inhalt der @var-Variablen in die Datei var_out.txt im aktuellen Serververzeichnis geschrieben.

DECLARE @cmd sysname, @var sysname
SET @var = 'Hello world'
SET @cmd = 'echo ' + @var + ' > var_out.txt'
EXEC master..xp_cmdshell @cmd

F. Aufzeichnen des Ergebnisses eines Befehls in einer Datei

Im folgenden Beispiel wird der Inhalt des aktuellen Verzeichnisses in die Datei dir_out.txt im aktuellen Serververzeichnis geschrieben.

DECLARE @cmd sysname, @var sysname
SET @var = 'dir/p'
SET @cmd = @var + ' > dir_out.txt'
EXEC master..xp_cmdshell @cmd