xp_cmdshell (Transact-SQL)

Gera um shell de comando do Windows e passa em uma cadeia de caracteres para execução. Qualquer saída é retornada como linhas de texto.

Ícone de vínculo de tópicoConvenções de sintaxe Transact-SQL

Sintaxe

xp_cmdshell { 'command_string' } [ , no_output ]

Argumentos

  • 'command_string'
    É a cadeia de caracteres que contém um comando a ser passado para o sistema operacional. command_string é varchar(8000) ou nvarchar(4000), sem padrão. command_string não pode conter mais de um conjunto de aspas duplas. Um único par de aspas será necessário se houver qualquer espaço nos caminhos de arquivo ou nomes de programa referenciados em command_string. Se você tiver dificuldade com espaços incorporados, considere o uso de nomes de arquivo FAT 8.3 como uma solução alternativa.

  • no_output
    É um parâmetro opcional, especificando que nenhuma saída deve ser retornada ao cliente.

Valores de código de retorno

0 (êxito) ou 1 (falha)

Conjuntos de resultados

A execução da seguinte instrução xp_cmdshell retorna uma lista de diretório do diretório atual.

EXEC xp_cmdshell 'dir *.exe';
GO

As linhas são retornadas em uma coluna nvarchar(255). Se a opção no_output for usada, somente o seguinte será retornado:

The command(s) completed successfully.

Comentários

O processo de Windows gerado por xp_cmdshell tem os mesmos direitos de segurança que a conta de serviço do SQL Server.

xp_cmdshell opera de forma síncrona. O controle não é voltado ao chamador até que o comando do shell de comandos seja concluído.

xp_cmdshell pode ser habilitado e desabilitado com o uso do Gerenciamento com base em Políticas ou pela execução de sp_configure. Para obter mais informações, consulte Compreendendo a Configuração da Área da Superfície e Opção xp_cmdshell.

Observação importanteImportante

Se xp_cmdshell for executado dentro de um lote e retornar um erro, o lote falhará. É uma alteração de comportamento. Nas versões anteriores do Microsoft SQL Server, o lote continuaria a ser executado.

Conta proxy xp_cmdshell

Quando é chamado por um usuário que não é um membro da função de servidor fixa sysadmin, xp_cmdshell se conecta ao Windows usando o nome da conta e a senha armazenadas na credencial chamada ##xp_cmdshell_proxy_account##. Se essa credencial de proxy não existir, xp_cmdshell falhará.

A credencial de conta proxy pode ser criada executando sp_xp_cmdshell_proxy_account. Como argumentos, esse procedimento armazenado possui um nome de usuário e uma senha do Windows. Por exemplo, o comando a seguir cria uma credencial de proxy para o usuário de domínio do Windows SHIPPING\KobeR que possui a senha do Windows sdfh%dkc93vcMt0.

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

Para obter mais informações, consulte sp_xp_cmdshell_proxy_account (Transact-SQL).

Permissões

Como usuários mal-intencionados às vezes tentam elevar seus privilégios usando xp_cmdshell, xp_cmdshell é desabilitado por padrão. Use sp_configure ou o Gerenciamento Baseado em Diretivas para habilitá-lo. Para obter mais informações, consulte Opção xp_cmdshell.

Quando habilitado pela primeira vez, xp_cmdshell exige a permissão CONTROL SERVER ser executado, e o processo do Windows criado por xp_cmdshell tem o mesmo contexto de segurança que a conta de serviço do SQL Server. A conta de serviço do SQL Server tem frequentemente mais permissões do que o necessário para o trabalho executado pelo processo criado por xp_cmdshell. Para aprimorar a segurança, o acesso a xp_cmdshell deverá ser restrito a usuários altamente privilegiados.

Para permitir que não administradores usem o xp_cmdshell, e permitir que o SQL Server crie processos filho com o token de segurança de uma conta com privilégios mínimos, siga estas etapas:

  1. Crie e personalize uma conta de usuário local do Windows ou uma conta de domínio com os privilégios mínimos que seus processos requerem.

  2. Use o procedimento de sistema sp_xp_cmdshell_proxy_account para configurar o xp_cmdshell para usar aquela conta com privilégios mínimos.

    ObservaçãoObservação

    Você também poderá configurar essa conta proxy usando o SQL Server Management Studio. Para isso, clique com o botão direito do mouse em Propriedades, no nome do servidor no Pesquisador de Objetos, e procure na guia Segurança pela seção Conta proxy do servidor.

  3. No Management Studio, usando o banco de dados mestre, execute a instrução GRANT exec ON xp_cmdshell TO '<somelogin>' para conceder a usuários específicos não sysadmin a capacidade de executar o xp_cmdshell. O logon especificado deve ser mapeado para um usuário no banco de dados mestre.

Agora os usuários que não são administradores podem iniciar processos do sistema operacional com o xp_cmdshell, e esses processos são executados com as permissões da conta proxy que você configurou. Os usuários com permissão CONTROL SERVER (membros da função de servidor fixa sysadmin) continuarão recebendo as permissões da conta de serviço do SQL Server para processos filho iniciados pelo xp_cmdshell.

Para determinar a conta do Windows que é usada pelo xp_cmdshell ao iniciar processos do sistema operacional, execute a seguinte instrução:

xp_cmdshell 'whoami.exe'

Para determinar o contexto de segurança para outro logon, execute o seguinte:

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

Exemplos

A. Retornando uma lista de arquivos executáveis

O exemplo a seguir mostra o procedimento armazenado estendido xp_cmdshell executando um comando de diretório.

EXEC master..xp_cmdshell 'dir *.exe'

B. Usando comandos net do Windows

O exemplo a seguir mostra o uso de xp_cmdshell em um procedimento armazenado. Este exemplo notifica os usuários, usando net send, de que uma instância do SQL Server está prestes a ser desligada, pausa o servidor usando net pause e desliga o servidor usando 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. Não retornando nenhuma saída

O exemplo a seguir usa xp_cmdshell para executar uma cadeia de caracteres de comando sem retornar a saída ao cliente.

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

D. Usando o status de retorno

No exemplo a seguir, o procedimento armazenado estendido xp_cmdshell também sugere o status de retorno. O valor de código de retorno é armazenado na variável @result.

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

E. Escrevendo conteúdos de variável em um arquivo

O exemplo a seguir escreve o conteúdo da variável @var em um arquivo chamado var_out.txt no diretório de servidor atual.

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

F. Capturando o resultado de um comando em um arquivo

O exemplo a seguir escreve o conteúdo do diretório atual em um arquivo chamado dir_out.txt no diretório de servidor atual.

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