PowerShell e o dia a dia do DBA SQL SERVER

(checando a conectividade de linked servers)

 

Bom pessoal,

Neste artigo estaremos vendo um recurso que foi incorporado ao SQL SERVER 2008 o Powershell e que nos ajudará numa tarefa diária que alguns de nós temos : Checar a conectividade os linked servers de todos os servidores

Vou fazer um breve introdução ao PS (Powershell – a partir de agora o estarei chamando assim) e colocarei alguns links que acho interessante para quem assim como eu está iniciando nesta tecnologia.

O PS é um poderosíssimo Shell que nos permite a criação de scripts (uma “linguagem” de criação de scripts) sendo totalmente baseado em .NET Framework que é a base do SO windows. A facilidade que temos no gerenciamento do SO tanto em maquinas remotas como local  é completamente simples e amigável.

Ele é desenhado para ser usado especialmente por Administradores de Redes/Sistemas/Ambientes e agora (eu digo agora pois ficou mais simples trabalhar com o PS do SQL SERVER, mas poderíamos muito bem trabalhar com o PS e a SMO antes do SQL Server 2008) vem incorporado no SQL SERVER 2008 aumentando assim também para Administradores de Banco de Dados SQL SERVER.

A diferença básico do PS do SQL SERVER (sqlps.exe) para o PS digamos normal é que no PSSQL é iniciada uma sessão PS com os cmdlets e provedor do SQL SERVER POWERSHELL já carregados e registrados.

O PSSQL (SQL SERVER POWERSHELL)  possui nomenclaturas padronizadas para os comandos(cmdltes) e é a junção de um verbo (write,new,out..)  mais um nome (host,content...) e sendo ou não seguido de parâmetros (commom parameters).

A grande sacada de se trabalhar com o PS no SQL SERVER é saber usar a SMO e XML. Meus scripts de checagem são 99% baseados na SMO.

Exemplo :

Get-content

Write-host

Bom gente, pra quem quiser saber mais sobre o PS segue alguns links que me ajudaram e me ajudam diariamente.

http://blogs.microsoft.co.il/blogs/ScriptFanatic

http://www.andersonpatricio.org

http://blogs.technet.com/dbordini

http://www.computerperformance.co.uk/powershell/powershell_intro.htm

http://technet.microsoft.com/en-us/library/bb978526.aspx

 

 

 

Vamos ao nosso intuito que é a checagem dos linked serves em vários servidores.

Inicialmente criaremos uma pasta chamada c:\dadosps e nela colocaremos um .txt contendo o nome dos nossos servidores. Caso use uma ou várias instâncias nomeadas as coloque também.

 
 
Definiremos um Servidor e Database Centrais, que receberão os dados. Vamos usar o Servidor1\MSSQLSERVER_1 e o Database DBA. Também criaremos um schema chamado DIARIO para receber a tabela e facilitar a atribuição de permissões além de segmentar.

Criando o Schema

USE [DBA]

GO

 

/****** Object:  Schema [Diario]    Script Date: 11/10/2008 18:04:53 ******/

CREATE SCHEMA [Diario] AUTHORIZATION [dbo]

GO

 

 

Criando a Tabela que receberá os dados (os linkedservers que deram erro).

USE [DBA]

GO

 

/****** Object:  Table [Diario].[tb_LinkeDServersErro]    Script Date: 11/10/2008 18:04:33 ******/

SET ANSI_NULLS ON

GO

 

SET QUOTED_IDENTIFIER ON

GO

 

SET ANSI_PADDING ON

GO

 

CREATE TABLE [Diario].[tb_LinkedServersErro](

      [Servidor] [varchar](50) NULL,

      [Data] [datetime] NULL,

      [NomeLinkedServer] [varchar](100) NULL,

      [MsgErro] [varchar](500) NULL

) ON [PRIMARY]

 

GO

 

SET ANSI_PADDING OFF

GO

 

Pronto ja temos o que precisamos para começar a trabalhar. Vou colocar primeiramente um script simples da checagem, depois passaremos para um complexo com tratamento de erros, gravação do log num arquivo e erro no EventViewer, verificação de ping dos servidores e se o serviço do SQL (por instancia cadastrada no TXT) está online e envio de email.

Script 1

 

[reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | out-null

$datas = get-date -format "yyyy-MM-dd hh:mm:ss"

##########################################################
#Atribui o Dabatase e Server central que receberão os dados
##########################################################

$ServidorCentral = "Server1\MSSQLSERVER_1"
$DatabaseCentral = "DBA"


$sql = "truncate table diario.tb_LinkeDServersErro"
Invoke-Sqlcmd -ServerInstance $ServidorCentral -Database $DatabaseCentral -Query $sql

 

foreach ($svr in get-content "C:\dadosps\servidores.txt" )
{
   trap [Exception] {
                 $erro =  $_.Exception.Message
                 write-host $_.Exception.number
                 continue;
             }


 $Servidor=New-Object "Microsoft.SqlServer.Management.Smo.Server" "$svr"
 $data = $Servidor.linkedservers| where-object {$_.State -eq "Existing"} | foreach {
       
             trap [Exception] {
                 $erro =  $_.Exception.Message
                 $sql1 = "set dateformat dmy insert into diario.tb_LinkedServersErro(servidor,data,NomeLinkedServer,msgerro) values ('$svr','$datas','$NomeLinkedServer','$erro')"
                 Invoke-Sqlcmd -ServerInstance $ServidorCentral -Database $DatabaseCentral -Query $sql1
                 continue;
             }
        
             $NomeLInkedServer = $_.name
             $_.testconnection()

        }

}

 

 

 
 
Como o método testconnection não me retorna valores temos que trabalhar com o erro que é gerado caso algum linkedserver esteja sem conectividade ou com problemas.

Vamos entender este script ?

Codigo PS

O que faz ?

[reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") | out-null

Carrega a SMO

$datas = get-date -format "yyyy-MM-dd hh:mm:ss"

 

Formato a data e hora para inserir na tabela

$ServidorCentral = "SERVER1\MSSQLSERVER_1"

$DatabaseCentral = "DBA"

Atribuo o servidor central e o database central nas variáveis $servidorcentral e $databasecentral

$sql = "truncate table diario.tb_LinkeDServersErro"

Invoke-Sqlcmd -ServerInstance $ServidorCentral -Database $DatabaseCentral -Query $sql

Trunco a tabela que recebera os dados. Utilizo cmdllet Invoke-Sqlcmd para executar esta variável. Para saber mais sobre ele http://msdn.microsoft.com/pt-br/library/cc281720.aspx

 

foreach ($svr in get-content "C:\dadosps\servidores.txt" )

 

Aqui eu carrego a variável $svr contendo o nome do servidor no txt que criamos. Um a um é executado conforme o foreach ou seja ele anda em todos os  servidores

$Servidor=New-Object "Microsoft.SqlServer.Management.Smo.Server" "$svr"

Aqui eu instancio a SMO.Server no servidor corrente da variável $svr

$data = $Servidor.linkedservers| where-object {$_.State -eq "Existing"} | foreach {

Aqui eu ando na coleção linkedservers da SMO.Server, procurando por linked servers ativos. É iniciado um foreach para cada linked Server encontrado.

trap [Exception] {

                 $erro =  $_.Exception.Message

                 $sql1 = "set dateformat dmy insert into diario.tb_LinkedServersErro(servidor,data,NomeLinkedServer,msgerro) values ('$svr','$datas','$NomeLinkedServer','$erro')"

                 Invoke-Sqlcmd -ServerInstance $ServidorCentral -Database $DatabaseCentral -Query $sql1

                 continue;

             }

  $NomeLInkedServer = $_.name

             $_.testconnection()

 

        }

Aqui eu trabalho com a exception ou seja o erro. O método testconnection da SMO não retorna valores e sim erro quando existe algum problema com o mesmo.

Nas linhas abaixo eu pego o nome do linked Server e texto sua conexão. Caso haja algum problema entrará na exception e eu insiro na tabela o nome do servidor, a data, o nome do linked  Server e a mensagem de erro e mando continuar pois quero testar o resto

        

Prontinho, desta maneira temos a posição dos linked servers de todos os servidores.

Vamos rodar este script ?

 Primeiramente vamos startar o PSSQL. Botão direito em cima de qualquer objeto do servidor no SSMS e escolha Start Powershell

 

Após isso copiar o script (copy-paste) e colar na janela do PSSQL..e irá rodar o script

Podemos também gravar ele num arquivo .PS1. Abra o notepad, cole o script lá e salve-o na pasta c:\dadosps como TestLSError.PS1 (lembre-se de no notepad quando for gravar colocar no “Salvar como tipo” como todos.

 

Agora vamos automatizar o processo num job ?

·         Após o arquivo TestLSError.PS1 devidamente criado na pasta c:\dadosps Crie um novo job e no step no Type coloque Powershell e na janela de comando a chamada do arquivo PS1.

\dadosps\TestLSError.ps1

 

 

Prontinhu..agora só Schedular e chegando de manhã já temos a posição atualizada dos linked servers.

Como eu disse anteriormente, este script teoricamente não está pronto para ser usado em produção. Teríamos que tratar os erros tipo algum servidor do TXT estar fora de propósito, o serviço do SQL Server estar offline também por algum motivo programado ou até não, mas teríamos que fazer estes testes.No meu blog além dos meus avanços com PS e o SQL SERVER tenho exemplo de uma abordagem profissional deste mesmo script (com verificação de ping, status de serviço, gravação em log e eventviewer) e outros que estou usando no dia a dia.

http://laertejuniordba.spaces.live.com/

 

Um Grande Abraço a todos

 

Links Relacionados

 

·         http://www.laertejuniordba.spaces.live.com/

·         http://blogs.msdn.com/dtjones/default.aspx

·         http://blogs.msdn.com/powershell/

·         http://www.microsoft.com/windowsserver2003/technologies/management/powershell/default.mspx

 

Conclusão

Como vimos o Powershell é uma potente ferramenta que temos para gerenciamento de múltiplos ambientes. Em junção com a SMO e XML se torna uma das mais poderosas neste quisito.

Laerte Poltronieri Junior
PowerShell no Dia a Dia do DBA 
http://laertejuniordba.spaces.live.com