xp_cmdshell (Transact-SQL)

繁衍 Windows 命令 Shell 並傳入字串中以供執行。任何輸出都會當作文字資料列來傳回。

主題連結圖示 Transact-SQL 語法慣例

語法

xp_cmdshell { 'command_string' } [ , no_output ]

引數

  • ' command_string '
    這是包含要傳送至作業系統之命令的字串。command_string 是 varchar(8000) 或 nvarchar(4000),沒有預設值。command_string 不能包含多組雙引號。如果檔案路徑或 command_string 參考的程式名稱中有任何空格,則需使用單引號配對。如果使用內嵌空格會出錯,請考慮改用 FAT 8.3 檔案名稱作為因應措施。

  • no_output
    這是選擇性參數,用來指定不應將輸出傳回用戶端。

傳回碼值

0 (成功) 或 1 (失敗)

結果集

執行下列 xp_cmdshell 陳述式會傳回目前目錄的目錄清單。

EXEC xp_cmdshell 'dir *.exe';
GO

資料列會傳回在 nvarchar(255) 資料行中。如果使用了 no_output 選項,則只傳回下行:

The command(s) completed successfully.

備註

xp_cmdshell 繁衍的 Windows 處理序擁有與 SQL Server 服務帳戶相同的安全性權限。

xp_cmdshell 會同步操作。完成 command-shell 命令時,才會將控制權傳回呼叫者。

您可以利用以原則為基礎的管理或執行 sp_configure 來啟用及停用 xp_cmdshell。如需詳細資訊,請參閱<介面區組態>和<xp_cmdshell 伺服器組態選項>。

重要事項重要事項

如果 xp_cmdshell 是在批次內執行,且傳回錯誤,則批次會失敗。這是行為的變更。在舊版 Microsoft SQL Server 中,批次仍可繼續執行。

xp_cmdshell Proxy 帳戶

當它被一個不屬於系統管理員 (sysadmin) 固定伺服器角色的成員呼叫時,xp_cmdshell 會利用儲存在命名為 ##xp_cmdshell_proxy_account## 之認證中的帳戶名稱和密碼來連接到 Windows。如果這個 Proxy 認證不存在,xp_cmdshell 便會失敗。

您可以執行 sp_xp_cmdshell_proxy_account 來建立 Proxy 帳戶認證。作為引數,這個預存程序會取得 Windows 使用者名稱和密碼。例如,下列命令會針對 Windows 網域使用者 SHIPPING\KobeR (這個使用者有 Windows 密碼 sdfh%dkc93vcMt0) 來建立 Proxy 認證。

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

如需詳細資訊,請參閱<sp_xp_cmdshell_proxy_account (Transact-SQL)>。

權限

因為惡意使用者有時會嘗試使用 xp_cmdshell 來提高其權限,所以預設會停用 xp_cmdshell。請使用 sp_configure以原則為基礎的管理來啟用它。如需詳細資訊,請參閱<xp_cmdshell 伺服器組態選項>。

第一次啟用時,xp_cmdshell 需要 CONTROL SERVER 權限來執行,而且 xp_cmdshell 所建立的 Windows 處理序具有與 SQL Server 服務帳戶相同的安全性內容。SQL Server 服務帳戶通常擁有的權限會多於 xp_cmdshell 建立之處理序所執行之工作所需的權限。為了提高安全性,xp_cmdshell 的存取應該限制為高權限使用者。

若要讓非系統管理員使用 xp_cmdshell,並讓 SQL Server 使用較低權限帳戶的安全性 Token 來建立子處理序,請遵循以下步驟:

  1. 使用您的處理序所需的最低權限,建立及自訂 Windows 本機使用者帳戶或是網域帳戶。

  2. 使用 sp_xp_cmdshell_proxy_account 系統程序來設定 xp_cmdshell 使用該最低權限帳戶。

    [!附註]

    您也可以使用 SQL Server Management Studio 設定這個 Proxy 帳戶,其方式是以滑鼠右鍵在 [物件總管] 中按一下伺服器名稱上的 [屬性],然後在 [安全性] 索引標籤上尋找 [伺服器 Proxy 帳戶] 區段。

  3. 在 Management Studio 中,使用 master 資料庫執行 GRANT exec ON xp_cmdshell TO '<somelogin>' 陳述式,提供非系統管理員 (sysadmin) 的特定使用者執行 xp_cmdshell 的能力。指定的登入必須對應到 master 資料庫中的使用者。

現在,非系統管理員可以使用 xp_cmdshell 來啟動作業系統處理序,而這些處理序會使用您所設定之 Proxy 帳戶的權限來執行。具有 CONTROL SERVER 權限的使用者 (系統管理員 (sysadmin) 固定伺服器角色的成員) 將會繼續針對 xp_cmdshell 所啟動的子處理序收到 SQL Server 服務帳戶的權限。

若要在啟動作業系統處理序時判斷 xp_cmdshell 所使用的 Windows 帳戶,請執行下列陳述式:

xp_cmdshell 'whoami.exe'

若要判斷另一個登入的安全性內容,請執行下列程式碼:

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

範例

A. 傳回可執行檔清單

下列範例會顯示執行目錄命令的 xp_cmdshell 擴充預存程序。

EXEC master..xp_cmdshell 'dir *.exe'

B. 未傳回任何輸出

下列範例會利用 xp_cmdshell 執行命令字串,但不將輸出傳回用戶端。

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

C. 使用傳回狀態

在下列範例中,xp_cmdshell 擴充預存程序也建議傳回狀態。傳回碼值儲存在變數 @result 中。

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

D. 將變數內容寫入檔案

下列範例將 @var 變數的內容寫入目前伺服器目錄中一個命名為 var_out.txt 的檔案。

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

E. 將命令結果擷取至檔案

下列範例會將目前目錄的內容寫入目前伺服器目錄中一個名稱為 dir_out.txt 的檔案。

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

請參閱

參考

一般擴充預存程序 (Transact-SQL)

sp_xp_cmdshell_proxy_account (Transact-SQL)

概念

xp_cmdshell 伺服器組態選項

介面區組態