xp_cmdshell (Transact-SQL)
適用於:SQL Server
繁衍 Windows 命令殼層,並傳入字串以供執行。 任何輸出會以文字列的形式傳回。
語法
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
是功能強大的功能,預設為停用。 xp_cmdshell
您可以使用原則式管理或執行 sp_configure
來啟用和停用。 如需詳細資訊,請參閱 Surface area configuration and xp_cmdshell (server configuration option) 。 使用 xp_cmdshell
可觸發安全性稽核工具。
xp_cmdshell
以同步方式運作。 在命令殼層命令完成之前,控件不會傳回給呼叫端。 如果在 xp_cmdshell
批次內執行並傳回錯誤,批次將會失敗。
xp_cmdshell Proxy 帳戶
由不是系統管理員固定伺服器角色成員的使用者呼叫時,xp_cmdshell
會使用儲存在 ##xp_cmdshell_proxy_account## 認證中的帳戶名稱和密碼連線到 Windows。 如果此 Proxy 認證不存在,則 xp_cmdshell
失敗。
您可以執行 sp_xp_cmdshell_proxy_account
來建立 Proxy 帳戶認證。 作為自變數,此預存程式會採用 Windows 使用者名稱和密碼。 例如,下列命令會為具有 Windows 密碼 sdfh%dkc93vcMt0
的 Windows 網域使用者SHIPPING\KobeR
建立 Proxy 認證。
EXEC sp_xp_cmdshell_proxy_account 'SHIPPING\KobeR', 'sdfh%dkc93vcMt0';
如需詳細資訊,請參閱 sp_xp_cmdshell_proxy_account。
權限
因為惡意用戶有時會嘗試使用 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 使用較低許可權帳戶的安全性令牌建立子進程,請遵循下列步驟:
建立和自定義 Windows 本機用戶帳戶或網域帳戶,其中包含您程式所需的最低許可權。
sp_xp_cmdshell_proxy_account
使用系統程序來設定xp_cmdshell
為使用該最低許可權帳戶。注意
您也可以使用 SQL Server Management Studio 來設定此 Proxy 帳戶,方法是在 物件總管 中以滑鼠右鍵按兩下伺服器名稱上的 [屬性],然後查看 [伺服器 Proxy 帳戶] 區段的 [安全性] 索引卷標。
在 Management Studio 中,使用
master
資料庫執行下列 Transact-SQL 語句,讓特定非系統管理員 用戶能夠執行xp_cmdshell
。 指定的用戶必須存在於master
資料庫中。GRANT exec ON xp_cmdshell TO N'<some_user>';
現在,非系統管理員可以使用 啟動操作系統進程 xp_cmdshell
,而這些進程會以您設定的 Proxy 帳戶許可權執行。 具有 CONTROL SERVER 許可權的使用者(系統管理員固定伺服器角色的成員)會繼續接收 由 啟動xp_cmdshell
之子進程之 SQL Server 服務帳戶的許可權。
若要判斷啟動作業系統進程時所使用的 xp_cmdshell
Windows 帳戶,請執行下列語句:
EXEC xp_cmdshell 'whoami.exe';
若要判斷另一個登入的安全性內容,請執行下列 Transact-SQL 程式代碼:
EXEC 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;