domingo, 29 de abril de 2012

Desfragmentando automaticamente o HD de um servidor Siebel

Bem, se você chegou até aqui é porque passou do título do artigo e não pensou "caramba, eu gerencio um servidor Siebel em um sistema operacional com sistema de arquivos decente, eu não preciso saber disto".

Ainda por aqui? Bem, então é porque provavelmente tem um servidor Siebel instalado em alguma versão do Microsoft Windows Server e com unidades de disco em estado deprimente de fragmentação porque ninguém se lembra de fazer isto, principalmente se o servidor em questão é utilizado para desenvolvimento ou QA.

Já faz algum tempo que eu resolvi (meio que por falta de opção, para dizer a verdade) fazer automações com Windows Powershell e descobri como automatizar a desfragmentação de um servidor Siebel sem nenhuma intervenção manual.

Para fazer isto, eu usei o programa defrag.exe que está disponível por padrão na instalação do Windows e algum código em Powershell 2 para parar os serviços do Siebel e reiniciá-los quando defrag.exe acabar seu trabalho. De quebra, o script ainda gera um arquivo de registro rudimentar para revisão.

Segue o código abaixo para fazer isto:

set-strictmode -version 2.0

# a ordem aqui é importante: parar o IIS, parar o serviço do servidor Siebel e
# parar o serviço do SiebelG Gateway
$services = @('W3SVC','siebsrvr_SIEBEL_foobar','gtwyns')
$timeToWait = 180
$now = get-date
$logFile = 'results-' + $now.Day.ToString() + $now.Month.ToString() + $now.Year.ToString() + '.txt'

'[' + $now.ToString() + '] Starting management of disks' | Out-File $logFile

try {

    foreach ($serviceName in $services) {

        "Stopping $serviceName service" | Out-File -Append $logFile
       
        $service = Stop-Service $serviceName -PassThru -Force
       
        if ( $service -ne $null ) {
           
            if ( $service.Status -ne 'Stopped' ) {
           
                throw "Could not stop $serviceName. Aborting..."
           
            } else {
           
                "$serviceName was stopped successfully" | Out-File -Append $logFile
           
            }
           
        }
       
    }
   
    "Defragmenting drives" | Out-File -Append $logFile
    "Defragmenting drive C:" | Out-File -Append $logFile
    defrag c: -v 2>&1 | Out-File -Append $logFile
    "Defragmenting drive D:" | Out-File -Append $logFile
    defrag d: -v 2>&1 | Out-File -Append $logFile
   
    [array]::Reverse($services)
   
    foreach ($serviceName in $services) {

        "Starting $serviceName service" | Out-File -Append $logFile
       
        $service = Start-Service $serviceName -PassThru
       
        if ( $service -ne $null ) {
       
            if ( $service.Status -ne 'Running' ) {
           
                throw "Could not start $serviceName. Aborting..."
           
            } else {
           
                "$serviceName was started successfully" | Out-File -Append $logFile
           
            }
       
        }
       
        "Waiting $timeToWait seconds to give time to the process start correctly" | Out-File -Append $logFile
       
        Start-Sleep -Seconds $timeToWait
       
    }   
   
} catch {

    $error[0].exception | Out-File -Append $logFile


} finally {


}

Partes interessantes para comentar do código:
  • Procure o nome dos serviços em Computer Management, Services and Application, Services (pelo menos este é um dos caminhos no Windows Server 2003, pode variar em outras versões).
  • Depois que os serviços são parados, o array é invertido para que os serviços sejam iniciados novamente na ordem correta.
  • Repare que as mensagens de saída padrão e erro padrão do defrag.exe são redirecionadas para o arquivo de log com um "2>&1" (ideia vergonhosamente copiada do que existe na maioria dos shell scritps de sistemas UNIX-like). Existem formas mais elegantes (e trabalhosas) para fazer isto com as classes System.Diagnostics.ProcessStartInfo e System.Diagnostics.Process, mas você vai ter que aprender um pouco de .Net para usá-las.
  • No caso, o script realiza a desfragmentação nas unidades C:\ e D:\ do servidor, talvez você tenha uma combinação diferente.
  • O script espera um tempinho para dar tempo dos serviços serem iniciados corretamente. O tempo necessário para isto pode variar bastante.
  • Não é que eu esqueci de colocar algo interessante dentro do block finally, eu simplesmente não achei nada interessante para fazer ali.
Depois disso, é só agendar a tarefa para executar em algum horário interessante e partir para o abraço.


Se você gosta de emoções fortes, pode até fazer isto em ambiente de produção, mas eu não faria isto se fosse você: esse tipo de coisa tem que ser bem programada e acompanhada de perto.

Este script Powershell, assim como outros, é parte do projeto de código aberto Siebel GNU Tools. O website do projeto está localizado em https://code.google.com/p/siebel-gnu-tools/.

Nenhum comentário:

Postar um comentário