PowerShell e o dia a dia do DBA – Testando Linked Servers – UMA ABORDAGEM PROFISSIONAL II – Gravando no EventLog e Enviando Emails


 

Pessoal,

Vamos dar mais uma melhorada  no script de verificação de Linked Servers ?. Estas funções que estou fazendo e os tratamentos de erros servem para todos os scripts, eu estou usando este como Base.

Vamos fazer o seguinte Agora, vamos gravar no eventlog da maquina central caso de algum problema com o script, porque ?..Em emails com Buck Woody ele me sugeriu gravar no eventlog para se caso alguma ferramenta estiver montorando pode pegar. E envia por email pro administrador para ele saber que o script pode ter funcionado ou não.

A função é essa

Aonde eu passo o Source, o erro e o tipo. O source eu criei na chamada dela como DBACheckList..ou seja, pra estes eventos teremos sempre este source. O tipo é 1 erro, 2 warning, 3 information, 4 sucessaudit, 5 Failuereaudit..Ele sempre gravará no apllication

Vamos Fazer  um Teste ?..copie este codigo e coloque no PS….depois olhe no eventviwer da sua maquina

Function write-eventlog ([string] $Ssource, [string] $Evento, [int] $Tipo)
#$tipo = 1 Error, 2 Warning, 3 Informatoin, 4 SuccessAudit, 5 FailureAudit
{
$event=new-object System.Diagnostics.EventLog("Application")
$event.Source=$Ssource

switch ($tipo) {
1   { $Infevt=[System.Diagnostics.EventLogEntryType]::Error }
2   { $Infevt=[System.Diagnostics.EventLogEntryType]::Warning }
3   { $Infevt=[System.Diagnostics.EventLogEntryType]::Information }
4   { $Infevt=[System.Diagnostics.EventLogEntryType]::SuccessAudit }
5   { $Infevt=[System.Diagnostics.EventLogEntryType]::FailureAudit }
}

$event.WriteEntry($evento,$Infevt,70)
}

write-eventlog "TesteDoWriteLog" "Gerei um Evento de Erro" 1

write-eventlog "TesteDoWriteLog" "Gerei um Evento de Warning"  2

write-eventlog "TesteDoWriteLog" "Gerei um Evento de Information "  3

Aqui eu faço o seguinte, alguns erros continuam o script, outros param..é porisso que segmento desta maneira. Os emails a mesma  coisa, caso haja algum de warning ou erro eu envio só pra saber que houve alguma coisa e  se quiser checar o log é só ir ver. Isso pode ser alterado e gravar sómente quando vcs acharem necessário e enviar o email idem.

Vou estar colocando os 2 arquivos completos agora..Tanto o de funções como o testlinkedservererro . O de email eu peguei da net,  sou a favor da produtividade..nao vou reinventar a roda.

# PowerShell 1.0 script to send email through SMTP
# by Jakob Bindslet (jakob@bindslet.dk), 21. december 2007
# Current Script version 1.1
#
#NAME
#    Send-SMTPmail
#
#SYNOPSIS
#    Sends an email by use of an SMTP server
#
#SYNTAX
#    Send-SMTPmail -to -from -subject -body
#    [-smtpserver ] [-port ] [-attachment ] [-html]
#    [-cc ] [-bcc ] [-alert] [-timeout ]
#
#PARAMETERS
#    No specific order of the parameters are required:
#        -to
#        -from
#        -subject
#        -body
#    Optional arguments are:
#    -smtpserver
#        Address of the smtp server to be used. This is only optional if a
#        default    smtpserver has been specified
#    -port
#        port number of the smtp server, used only if it differs from the
#        standard port 25.
#    -attachment
#        Complete path to file to attach, ie. "c:\boot.ini"
#    -cc
#        Recipient(s) to be included as "carbon copy" on the email.
#    -bcc
#        Recipient(s) to be included as "blind carbon copy" on the email.
#    -timeout
#        Sets the timeout in miliseconds, for the send mail operation.
#        This includes the time it take to upload any attachments, so
#        be careful of setting this too low if using attached file.
#    -alert
#        The email will be treatet as an alert (the standard sharepoint
#        alert icon will be used in outlook).
#    -html
#        Indicates that the email will be in HTML format. The HTML
#        content itself should be specified in the -body parameter.
#
#NOTES
#
# ————————– EXAMPLE 1 ————————–

function Send-SMTPmail($to, $from, $subject, $body, $attachment, $cc, $bcc, $port, $timeout, $smtpserver, [switch] $html, [switch] $alert) {
    if ($smtpserver -eq $null) {$smtpserver = "smtp.astsconsulting.com.br.com"}
    $mailer = new-object Net.Mail.SMTPclient($smtpserver)
    if ($port -ne $null) {$mailer.port = $port}
    if ($timeout -ne $null) {$mailer.timeout = $timeout}
    $msg = new-object Net.Mail.MailMessage($from,$to,$subject,$body)
    if ($html) {$msg.IsBodyHTML = $true}
    if ($cc -ne $null) {$msg.cc.add($cc)}
    if ($bcc -ne $null) {$msg.bcc.add($bcc)}
    if ($alert) {$msg.Headers.Add("message-id", "<3bd50098e401463aa228377848493927-1>")}
    if ($attachment -ne $null) {
        $attachment = new-object Net.Mail.Attachment($attachment)
        $msg.attachments.add($attachment)
    }

$myCred = new-object System.net.networkCredential
$myCred.userName = "laerte@seila.com.br"
$myCred.password = "laerte9962"
$mailer.credentials = $myCred

    $mailer.send($msg)
}

Function write-eventlog ([string] $Ssource, [string] $Evento, [int] $Tipo)
#$tipo = 1 Error, 2 Warning, 3 Informatoin, 4 SuccessAudit, 5 FailureAudit
{
$event=new-object System.Diagnostics.EventLog("Application")
$event.Source=$Ssource

switch ($tipo) {
1   { $Infevt=[System.Diagnostics.EventLogEntryType]::Error }
2   { $Infevt=[System.Diagnostics.EventLogEntryType]::Warning }
3   { $Infevt=[System.Diagnostics.EventLogEntryType]::Information }
4   { $Infevt=[System.Diagnostics.EventLogEntryType]::SuccessAudit }
5   { $Infevt=[System.Diagnostics.EventLogEntryType]::FailureAudit }
}

$event.WriteEntry($evento,$Infevt,70)
}

#this function save a log

Function Salva-Log ([String] $NamePS1,
                  [String] $Server,
                  [String] $Error,
                  [String] $PathFileError
                 )
{

  #Testa se o path que vai ter o arquivo de erro existe..senão cria…pode se tirar esta checagem com o #
  #test if path wich will contains the error file exists. if not create

  if (!(Test-Path -path $PathFileError))
  {
    New-Item $PathFileError
  }

  #Assume o arquivo de log como sendo o nome do ps1 + data + .log
  #Put the name of error file like  $Nameps1.log
  $NameFileFull = $PathFileError + "\" + $NamePS1 + (get-date -format "yyyyMMddhhmmss") + ".log"

  if (Test-Path -path $NameFileFull)
  {
    del $NameFileFull -ErrorAction "silentlycontinue"
  }

  $date =  get-date -format "yyyy-MM-dd hh:mm:ss"
  "Servidor : " + $Server, "Data : " + $date ,"Mensagem de Erro : " + $Error | Out-file  $NameFileFull -append

}

##########################################################
#Função para retirar somente o nome do servidor
##########################################################

Function get-servidor ([string] $NomeServidor)
{
   if (!($nomeservidor.contains("\")))
   { Return $NomeServidor }

   $posicao = $nomeservidor.indexof("\")

   $NomeServidor = $NomeServidor.substring(0,$posicao)
   return $NomeServidor
}

##########################################################
#Função para retirar somente o nome da instancia
##########################################################

Function get-Instancia ([string] $NomeServidor)
{
   if (!($nomeservidor.contains("\")))
   { Return $NomeServidor }

   $posicao = $nomeservidor.indexof("\")

   $NomeServidor = $NomeServidor.substring($posicao+1)
   return $NomeServidor
}

##########################################################
#Função para verificar se o serviço do sql server está ativo
##########################################################
Function get-servicosql ([string] $FullNomeservidor)
{

   $NomeServidor = ""
   $NomeInstancia = ""

# divido o nome da instancia do servidor se tiver

   $NomeServidor = get-servidor $FullNomeservidor
   $NomeInstancia = get-instancia $FullNomeservidor

   $NomeServico = "MSSQL$" + $NomeInstancia

# se tiver instancia pego MSSQL$NomeInstancia senao pego MSSQL*

   if ( $NomeInstancia -eq "" -or $NomeInstancia -eq $Null)
      {    $nomeServico = "MSSQL*" }

    $Check = get-wmiobject win32_service -computername $Nomeservidor -ErrorAction silentlyContinue |where-object {($_.name -like $nomeServico)}
    if (!$?)
    {  
      $Erro = "Ocorreu um erro tentando checar o serviço do sql em " + $NomeServidor + " Instancia " + $NomeInstancia

       write-eventlog DBACheckLIst $Erro 2
       Salva-Log TestLinkedServerError $NomeServidor $Erro "C:\dadosps"
       send-SMTPmail -to "laertejuniordba@hotmail.com" -from "laerte@seila.com.br"  -subject "OCorreu um Warning – ChekList Matinal" -smtpserver "smtp.seila.com.br"  -body "Instancia com serviço sql server parado !!! " + $erro

    }
    Return ($Check.state -eq "Running")
}

##########################################################
#Função para Pingar o Servidor
##########################################################
Function get-ping ([String] $FullNomeservidor)
{
    $NomeServidor = ""
    $NomeServidor = get-servidor $FullNomeservidor
    $Check = get-wmiobject win32_pingstatus -Filter "Address=’$NomeServidor’" -ErrorAction silentlyContinue | Select-Object statuscode
    if (!$?)
    {  
       $Erro = "Ocorreu um erro tentando Pingar em " + $NomeServidor + "  !!!  "
       Salva-Log TestLinkedServerError $NomeServidor $Erro "C:\dadosps"
       write-eventlog DBACheckLIst $erro 2
       send-SMTPmail -to "laertejuniordba@hotmail.com" -from "laerte@seila.com.br"  -subject "OCorreu um Warning – ChekList Matinal" -smtpserver "smtp.seila.com.br"  -body "Servidor Não Responde ao Ping!!! " + $erro
    }

    return ($Check.statuscode)
}

 

O testeLinkedServer

Param (    [string] $ServidorCentral,
           [String] $DatabaseCentral,
           [String] $FullPathFileTXTServers
      )

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

#estao comentados para testes, pois passeramos estes parametros na chamada do ps1

#$ServidorCentral = "SERVER1\MSSQLSERVER_1"
#$DatabaseCentral = "DBA"
#$FullPathFileTXTServers = "C:\dadosps\servidores.txt"

#Aqui eu carrego o arquivo de funçoes
. c:\Palestras\Interoperabilidade\CheckList\funcoes.ps1

##########################################################
#Testa se os parametros vieram com informação
##########################################################

if ($ServidorCentral -eq "" -or $ServidorCentral -eq $Null)
{
      $Erro = "Informe o Servidor Central !!!"
      write-eventlog DBACheckLIst $Erro 1
       send-SMTPmail -to "laertejuniordba@hotmail.com" -from "laerte@seila.com.br"  -subject "OCorreu um ERRO – ChekList Matinal" -smtpserver "smtp.seila.com.br"  -body $erro
      exit
}

if ($DatabaseCentral -eq "" -or $DatabaseCentral -eq $Null)
{
      $Erro = "Informe o Databse Central !!!"
      write-eventlog DBACheckLIst $Erro 1
       send-SMTPmail -to "laertejuniordba@hotmail.com" -from "laerte@seila.com.br"  -subject "OCorreu um ERRO – ChekList Matinal" -smtpserver "smtp.seila.com.br"  -body $erro
      exit
}

if ($FullPathFileTXTServers -eq "" -or $FullPathFileTXTServers -eq $Null)
{
      $Erro = "Informe o Caminho/Arquivo dos Servidores !!!"
      write-eventlog DBACheckLIst $Erro 1
       send-SMTPmail -to "laertejuniordba@hotmail.com" -from "laerte@seila.com.br"  -subject "OCorreu um ERRO – ChekList Matinal" -smtpserver "smtp.seila.com.br"  -body $erro
      exit
}

##########################################################
#Carrega os servidores
##########################################################
$Servidores = get-content $FullPathFileTXTServers -ErrorAction "silentlycontinue"
if (!$?)
   {  
      $Erro = "Verifique o Path/arquivo de configuração dos servidores !!!  – " + $FullPathFileTXTServers
      write-eventlog DBACheckLIst $Erro 1
      send-SMTPmail -to "laertejuniordba@hotmail.com" -from "laerte@seila.com.br"  -subject "OCorreu um ERRO – ChekList Matinal" -smtpserver "smtp.seila.com.br"  -body $erro
      exit
   }

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

$sql = "truncate table diario.tb_LinkeDServersErro"
Invoke-Sqlcmd -ServerInstance $ServidorCentral -Database $DatabaseCentral -Query $sql -ErrorAction "silentlyContinue"
if (!$?)
   {  
      $Erro = "Verifique Se o Servidor Central/Database/Tabela existem  !!! "
      write-eventlog DBACheckLIst $Erro 1
      Salva-Log TestLinkedServerError Erro $Erro "C:\dadosps"
      send-SMTPmail -to "laertejuniordba@hotmail.com" -from "laerte@seila.com.br"  -subject "OCorreu um ERRO – ChekList Matinal" -smtpserver "smtp.seila.com.br"  -body $erro
      exit;
   }

foreach ($svr in $servidores)
{

#Faço o teste de Ping se deu pau eu logo no arquivo de log

   if ((get-ping $svr) -eq 0)
   {

# só faço o teste de linked servers para os servers que estiverem com o serviço ativo   se estiver parado eu logo

       if ((get-servicosql $svr) -eq $True)
       {

#tudo certo..testo os linked servers
    $Serv =New-Object "Microsoft.SqlServer.Management.Smo.Server" "$svr"
    $data = $Serv.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
                 $Erro = $erro + " Não conseguir testar o linked server " + $NomeLinkedServer + " em " + $svr
                 write-eventlog DBACheckLIst $Erro  1
                 continue;
             }
             $NomeLInkedServer = $_.name
             $_.testconnection()
             }

        }
        else
        {
           $Erro = "Serviço do sql " + $svr + " Parado !!! "
           write-eventlog DBACheckLIst $Erro 3
           Salva-Log TestLinkedServerError Erro $Erro "C:\dadosps"
        }
    }
    else
    {
       $Erro = "Servidor não respondendo ao ping " + $svr
       write-eventlog DBACheckLIst $Erro 3
       Salva-Log TestLinkedServerError Erro $Erro "C:\dadosps"
    }

}

 

FALOWWWWWWW

About Laerte Junior

Laerte Junior Laerte Junior is a SQL Server specialist and an active member of WW SQL Server and the Windows PowerShell community. He also is a huge Star Wars fan (yes, he has the Darth Vader´s Helmet with the voice changer). He has a passion for DC comics and living the simple life. "May The Force be with all of us"
This entry was posted in Powershell. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s