Testando Ping e Status do serviço do SQL SERVER em servidores (local e remoto) com Powershell


 

Pessoal,

Nos meus scripts powershell eu tenho um txt contendo o nome dos servidores que irei coletar os dados. É assim :

Server1
Server2
Server2\Instance1
Server3

Este txt é gravado em um folder.Com base nele que eu coleto todas as informações que eu preciso.

Tá mas se o servidor estiver fora ou o serviço do sql server estiver offline ?

Pra isso eu criei duas funções a get-ping e a get-servicesql que primeiramente testa o ping e depois testa o serviço do sql server.

A get-servicesql é bem legal pois ela divide o nome da instancia do nome do servidor e testa o serviço correspondente.

Por exemplo instancia default o nome do serviço é MSSQLSERVER, para uma nomeada digamos instancia1 é MSSQLSERVER$instancia1.

Intaum o fluxo é este nos meus scripts.

1 – Carrego o nome do servidor
2 – Separo o Nome do servidor do nome da instancia
3 – Pingou o servidor ?
4 – Se pingou vou para 5 senão logo (save-log) e volto pra 1
5 – Testo o servico da instancia
6 – Esta online vou para 7 senão logo (save-log) e volto pra 1
7 – carrego uma variavel com o nome dos servidores ok (server1,server2,server3)

Após isso, faço a coleta de dados com base nesta variavel.

vamos aos scripts ?..Está em inglês (nao reparem ele por sinal), pois estou escrevendo um artigo pra um site gringo.

##########################################################
#Save a log in path
#Funcao pra salvar log
##########################################################
Function Save-Log ([String] $NamePS1,
                  [String] $Server,
                  [String] $Erro,
                  [String] $PathFileError
                 )
{

    #test if path wich will contains the error file exists. if not create

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

    #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"
  "Server : " + $Server, "Date : " + $date ,"Error Message: " + $Erro | Out-file  $NameFileFull -append

}

##########################################################
#Retrive the Server name in Fullservername
#If $Fullservername = "server\instance1" returns server1
#Função para separa o nome do servidor da string "server\instance"
##########################################################

Function get-servername ([string] $FullServerName)
{
   if (!($FullServerName.contains("\")))
   { Return $FullServerName }

   $Position = $FullServerName.indexof("\")

   $ServerName = $FullServerName.substring(0,$Position)
   return $ServerName
}

##########################################################
#Retrive the Instance name in Fullservername
#If $Fullservername = "server\instance1" returns instance1
#Função para separa o nome do instancia da string "server\instance"
##########################################################

Function get-instance ([string] $FullServerName)
{
   if (!($FullServerName.contains("\")))
   { Return "" }

   $Position = $FullServerName.indexof("\")

   $InstanceName = $FullServerName.substring($Position+1)
   return $InstanceName
}

##########################################################
#Function to verify if sql server service is active
# Função para testar o serviço do sql server nos servidores (locais e remotos)
# Veja que para instancia default testo MSSQLSERVER senao testo MSSQLSERVER$NOmedaInstancia
##########################################################
Function get-servicesql ([string] $FullNomeservidor)
{

   $ServerName = ""
   $InstanceName = ""

# Divide the servername and instance name

   $ServerName = get-servername $FullNomeservidor
   $InstanceName = get-instance $FullNomeservidor

# If have a instance name i get MSSQL$Instancename Otherwise MSSQLSERVER (default)

   $ServiceName = "MSSQL$" + $InstanceName

   if ( $InstanceName -eq "" -or $InstanceName -eq $Null)
      {    $ServiceName = "MSSQLSERVER" }

    $Check = get-wmiobject win32_service -computername $ServerName -ErrorAction silentlyContinue |where-object {($_.name -like $ServiceName)}
    if (!$?)
    { 
      $Erro = "Server " + $ServerName + " Instance " + $InstanceName + " not avaliable"

       Save-Log Service $ServerName $Erro "C:\Project\Log"

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

##########################################################
#Ping Server Function
#Função para pingar o servidor
##########################################################
Function get-ping ([String] $FullServerName)
{
    $ServerName = ""
    $ServerName = get-servername $FullServerName
    $Check = get-wmiobject win32_pingstatus -Filter "Address=’$ServerName’" -ErrorAction silentlyContinue | Select-Object statuscode
    if (!$?)
    { 
       $Erro = "Server " + $ServerName + " Not Avaliable in Ping !!!  "
       Save-Log Ping $ServerName $Erro "C:\Project\Log"
    }

    return ($Check.statuscode)
}

#Scripst de Coleta

#First i get the server and database repository name

# Carrego o nome do meu repositorio de dados  (servidor e database)

$Repository = get-content "C:\Project\Configuration\repository.txt"
$Repository = $Repository.split(",")
$ServerRepository = $Repository[0]
$DatabaseRepository = $Repository[1]

#Now i get the Servers and test ping and if the MSSQL Service is ok. If not, its logged in folder C:\Project\Log
# and set the variable to wich server i will not collect the data

#Aqui eu faço os testes e carrego a variavel

$ServersAvaliable = ""
foreach ($svr in get-content "C:\servers\servers.txt" )
{
    #test ping
    if ((get-ping $svr) -eq 0)
    {
        #Test service
        if ((get-ServiceSql $svr) -eq $True)
        {
            $ServersAvaliable = $ServersAvaliable + $svr + ","
        }
        else
        {
            $Erro = "Service in Server " + $svr +" not avaliable in Get-Service !!!"
            Save-Log "CollectInfo" $svr $Erro "C:\Project\Log"
        }
    }
    else
    {
        $Erro = "Server " + $svr + " Not Avaliable in Get-Ping !!!  "
        Save-Log "CollectInfo" $svr $Erro "C:\Project\Log"
    }

}

# take off last comma
# Tiro a ultima virgula pois a string fica (server1,server2,server3,)

$ServersAvaliable = $ServersAvaliable.Substring(0,$ServersAvaliable.Length -1)

#Now, these are the servers that I will check

#Dou o split e mando pra uma array
$ServersAvaliable = $ServersAvaliable.Split(",")

#Agora é so andar nos servidores da array pois são estes que estão online

$Total = $ServersAvaliable.Count – 1
$Count = 0
for(;$Count -le $Total;$Count++)
{
#Anda na variavel com os servidores online
#Coleto os dados
}

Sempre lembrando que não preciso ter o powershell instalado nos servidores, somente no que vai rodar o script, seja ele o minishell do sql server 2008 ou o própio powershell.
Este script serve para todos as versões do sql server, pos não utilizo a SMO nele.

É isso aí..abraços

 

I´ll be back

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