xp_cmdshell (Transact-SQL)
繁衍 Windows 命令 Shell 並傳入字串中以供執行。任何輸出都會當作文字資料列來傳回。
語法
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 是在批次內執行,且傳回錯誤,則批次會失敗。這是行為的變更。在舊版 MicrosoftSQL 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 來建立子處理序,請遵循以下步驟:
使用您的處理序所需的最低權限,建立及自訂 Windows 本機使用者帳戶或是網域帳戶。
使用 sp_xp_cmdshell_proxy_account 系統程序來設定 xp_cmdshell 使用該最低權限帳戶。
[!附註]
您也可以使用 SQL Server Management Studio 設定這個 Proxy 帳戶,其方式是以滑鼠右鍵在 [物件總管] 中按一下伺服器名稱上的 [屬性],然後在 [安全性] 索引標籤上尋找 [伺服器 Proxy 帳戶] 區段。
在 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. 使用 Windows net 命令
下列範例會顯示如何在預存程序中使用 xp_cmdshell。這個範例利用 net send 來通知使用者即將關閉 SQL Server 的執行個體,利用 net pause 來暫停伺服器,然後利用 net stop 來關閉伺服器。
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. 未傳回輸出
下列範例會利用 xp_cmdshell 執行命令字串,但不將輸出傳回用戶端。
USE master;
EXEC xp_cmdshell 'copy c:\SQLbcks\AdvWorks.bck
\\server2\backups\SQLbcks, NO_OUTPUT';
GO
D. 使用傳回狀態
在下列範例中,xp_cmdshell 擴充預存程序也建議傳回狀態。傳回碼值儲存在變數 @result 中。
DECLARE @result int
EXEC @result = xp_cmdshell 'dir *.exe'
IF (@result = 0)
PRINT 'Success'
ELSE
PRINT 'Failure'
E. 將變數內容寫入檔案
下列範例將 @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
F. 將命令結果擷取至檔案
下列範例會將目前目錄的內容寫入目前伺服器目錄中一個名稱為 dir_out.txt 的檔案。
DECLARE @cmd sysname, @var sysname
SET @var = 'dir/p'
SET @cmd = @var + ' > dir_out.txt'
EXEC master..xp_cmdshell @cmd
變更記錄
更新的內容 |
---|
已強化「權限」一節。 |