xp_cmdshell (Transact-SQL)

適用対象:SQL Server

Windows のコマンド シェルを起動し、実行用の文字列に渡します。 出力は、テキストの行として返されます。

Transact-SQL 構文表記規則

構文

xp_cmdshell { 'command_string' } [ , NO_OUTPUT ]

引数

'command_string'

オペレーティング システムに渡されるコマンドを含む文字列。 command_stringvarchar(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.

Remarks

によってxp_cmdshell生成される Windows プロセスには、SQL Server サービス アカウントと同じセキュリティ権限があります。

注意事項

xp_cmdshell は強力な機能であり、既定では無効になっています。 xp_cmdshell を有効または無効にするには、ポリシー ベースの管理を使用するか、 を実行します sp_configure。 詳細については、「 Surface area configuration and xp_cmdshell (サーバー構成オプション)」を参照してください。 を使用すると xp_cmdshell 、セキュリティ監査ツールをトリガーできます。

xp_cmdshell は同期的に動作します。 command-shell コマンドが完了するまで、コントロールは呼び出し元に返されません。 がバッチ内で実行され、エラーが返された場合 xp_cmdshell 、バッチは失敗します。

xp_cmdshell プロキシ アカウント

sysadmin 固定サーバー ロールのメンバーではないユーザーによって呼び出されると、 xp_cmdshell##xp_cmdshell_proxy_account## という名前の資格情報に格納されているアカウント名とパスワードを使用して Windows に接続します。 このプロキシ資格情報が存在しない場合、 xp_cmdshell は失敗します。

プロキシ アカウントの資格情報は、 を sp_xp_cmdshell_proxy_account実行して作成できます。 このストアド プロシージャは、Windows のユーザー名とパスワードを引数にとります。 たとえば、次のコマンドは、Windows パスワード sdfh%dkc93vcMt0を持つ Windows ドメイン ユーザーSHIPPING\KobeRのプロキシ資格情報を作成します。

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

詳細については、「 sp_xp_cmdshell_proxy_account (Transact-SQL)」を参照してください。

アクセス許可

悪意のあるユーザーが を使用xp_cmdshellxp_cmdshellして特権の昇格を試みる場合があるため、既定では無効になっています。 またはポリシー ベースの管理を使用sp_configureして有効にします。 詳細については、「 xp_cmdshell サーバー構成オプション」を参照してください。

最初に有効にすると、 xp_cmdshell によって作成された xp_cmdshell Windows プロセスは、SQL Server サービス アカウントと同じセキュリティ コンテキストを持つ CONTROL SERVER アクセス許可を実行する必要があります。 多くの場合、SQL Server サービス アカウントには、 によってxp_cmdshell作成されたプロセスによって実行される作業に必要なアクセス許可よりも多くのアクセス許可があります。 セキュリティを強化するには、 へのアクセスを xp_cmdshell 高い特権を持つユーザーに制限する必要があります。

管理者以外のユーザーが を使用xp_cmdshellし、SQL Serverが特権の低いアカウントのセキュリティ トークンを使用して子プロセスを作成できるようにするには、次の手順に従います。

  1. プロセスに必要な最小限の特権を持つ Windows ローカル ユーザー アカウントまたはドメイン アカウントを作成してカスタマイズします。

  2. システム 手順を sp_xp_cmdshell_proxy_account 使用して、その最小特権アカウントを使用するようにを構成 xp_cmdshell します。

    注意

    オブジェクト エクスプローラーでサーバー名の [プロパティ] を右クリックし、[サーバー プロキシ アカウント] セクションの [セキュリティ] タブを調べることで、SQL Server Management Studioを使用してこのプロキシ アカウントを構成することもできます。

  3. Management Studio でデータベースを master 使用して、次の Transact-SQL ステートメントを実行して、特定の sysadmin 以外のユーザーに を実行 xp_cmdshellできるようにします。 指定したユーザーがデータベースに存在している master 必要があります。

     GRANT exec ON xp_cmdshell TO N'<some_user>';
    

管理者以外のユーザーは、 を使用してオペレーティング システム プロセスを xp_cmdshell 起動できるようになり、それらのプロセスは、構成したプロキシ アカウントのアクセス許可で実行されます。 CONTROL SERVER アクセス許可 (sysadmin 固定サーバー ロールのメンバー) を持つユーザーは、 によって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;

関連項目