Microsoft Insights 2015

Microsoft Insights 2015

Após alguns anos, o maior evento técnico da Microsoft voltou ao Brasil. Desta vez, com o nome de Microsoft Insights powered by TechED. Foram 2 dias (24 e 25 de setembro) onde tivemos mais de 90 palestras técnicas sobre a nova estratégia, os novos produtos e alguns insights (trocadilho infame, he he) de novos produtos:

  • Cloud (Azure)
  • Gerenciamento de Datacenter (Windows Server, System Center)
  • Gerenciamento de Dispositivos Móveis (Intune)
  • Desenvolvimento e Infraestrutura Multiplataforma (Visual Studio, Azure)
  • Windows 10, SQL Server e outros

Algumas palestras foram ministradas por alguns gerentes de produto que vieram da Microsoft especialmente para o evento. A lista completa das sessões, com os PPTs para download está no site do evento, www.microsoftinsights.com.br/downloads. As sessões Geral e Técnica podem ser vistas (ou revistas) no Channel 9:

Algumas fotos para vocês:

Chegando no evento

Chegando no evento

Uma selfie, he he

Uma selfie, he he

Um pouco antes da General Session

Um pouco antes da General Session

Palestra com "gringo" da Microsoft :P

Palestra com “gringo” da Microsoft😛

Nos próximos posts irei resumir algumas palestras que assisti.

 

Até a próxima.

 

Monitorando Bloqueios no SQL Server

Olá a todos!

Uma tarefa necessária com certa frequência é descobrir quais processos estão bloqueando outros processos, ou “quem está bloqueando quem” (ou ainda: “o que este processo está fazendo para causar este tipo de lock?”).

Foi uma pergunta que um cliente meu fez… além de “o que eu faço?

Bem, a partir do SQL Server 2008 temos uma funcionalidade chamada EVENT NOTIFICATION, que pode capturar vários eventos disparados pelo SQL Server, rastreando informações sobre estes para armazenamento em uma fila do Service Broker. Esta informação é entregue com uma variável no formato xml, com informações e metadados sobre o evento. O formato deste XML é o mesmo da função EVENTDATA().

Mais informações sobre esta tecnologia podem ser obtida na documentação, no link: http://msdn.microsoft.com/en-us/library/ms190427(v=SQL.105).aspx.

Então, como podemos monitorar os processos bloqueados/bloqueando utilizando esta tecnologia?

As ações que precisam ser tomadas são basicamente as seguintes:

  1. Configurar o threshold para geração do relatório de processos bloqueados;
  2. Habilitar Service Broker e configurar a captura do evento;
  3. Criar uma stored procedure para receber e tratar o evento.
Vamos iniciar.

1 – Configuração da instância

Através da procedure de sistema sp_configure, é preciso configurar o tempo que um bloqueio fica em vigor (em segundos) antes da geração e captura do evento BLOCKED_PROCESS_REPORT. No exemplo abaixo, estamos definindo este tempo em 20 segundos.
EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'blocked process threshold', 20
GO
RECONFIGURE
GO

2 – Configuração do Service Broker

O próximo passo é habilitar e configurar o Service Broker. Temos que criar uma fila em um database para armazenar as notificações. Qualquer banco de dados pode ser utilizado. No nosso exemplo, vamos criar um banco exclusivo:

CREATE DATABASE DB_Management
GO
ALTER DATABASE DB_Management SET ENABLE_BROKER
GO

… e criar os objetos de apoio:

USE [DB_Management]
GO

CREATE QUEUE que_events
GO

CREATE SERVICE svc_events
ON QUEUE que_events ( [http://schemas.microsoft.com/SQL/Notifications/PostEventNotification] )
GO

CREATE EVENT NOTIFICATION notify_locks
ON SERVER
WITH fan_in
FOR BLOCKED_PROCESS_REPORT
TO SERVICE 'syseventservice', 'current database'; -- *** importante: current database ***
GO

 
Quais eventos podem ser especificados? A view de sistema sys.sys.event_notification_event_types contém a lista.

SELECT * FROM sys.sys.event_notification_event_types

3 – Tratamento do evento

Agora, precisamos criar uma stored procedure para receber as mensagens da fila e efetuar o tratamento. A idéia é utilizar o comando RECEIVE, que funciona como um SELECT, lendo e removendo a mensagem da fila.

No meu exemplo, o processo que está bloqueando outros é finalizado, através do comando KILL, e um e-mail é enviado para o Administrador (logicamente que o Database Mail já deve estar configurado e funcionando):

SET ARITHABORT ON
GO

— CREATE ou ALTER
ALTER PROCEDURE dbo.prc_ReceiveMsg
AS

BEGIN

SET ARITHABORT ON

— variaveis de trabalho

DECLARE @spid_blocked int, @spid_blocking int;
DECLARE @hostname_blocked varchar(255), @hostname_blocking varchar(255);
DECLARE @loginname_blocked varchar(255), @loginname_blocking varchar(255);
DECLARE @event_txt varchar(max);
DECLARE @post_time varchar(32);
DECLARE @msgs TABLE (message_body xml);

DECLARE @email_body varchar(max);
DECLARE @email_subject varchar(64);
DECLARE @crlf varchar(2);

DECLARE @cmd nvarchar(255);

RECEIVE TOP(1) message_body
FROM que_sysevents
INTO @msgs;

SELECT @spid_blocked  = message_body.value('(/EVENT_INSTANCE/TextData/blocked-process-report/blocked-process/process/@spid)[1]', 'int'),
@hostname_blocked  = message_body.value('(/EVENT_INSTANCE/TextData/blocked-process-report/blocked-process/process/@hostname)[1]', 'varchar(255)'),
@loginname_blocked = message_body.value('(/EVENT_INSTANCE/TextData/blocked-process-report/blocked-process/process/@loginname)[1]', 'varchar(255)'),

@spid_blocking = message_body.value('(/EVENT_INSTANCE/TextData/blocked-process-report/blocking-process/process/@spid)[1]', 'int'),
@hostname_blocking = message_body.value('(/EVENT_INSTANCE/TextData/blocked-process-report/blocking-process/process/@hostname)[1]', 'varchar(255)'),
@loginname_blocking = message_body.value('(/EVENT_INSTANCE/TextData/blocked-process-report/blocking-process/process/@loginname)[1]', 'varchar(255)'),

@event_txt = CAST(message_body as varchar(max)),
@post_time = message_body.value('(/EVENT_INSTANCE/PostTime)[1]&#39, 'varchar(32)')
FROM @msgs
WHERE message_body IS NOT NULL;

IF @@ROWCOUNT <= 0
BEGIN
PRINT ‘Saindo… nenhuma linha encontrada (onde message_body IS NOT NULL)’;
RETURN;
END

— exibir informacoes:
PRINT 'Usuario atual: ‘ + USER_NAME()
PRINT 'Processo bloqueando:’
PRINT 'SPID  = ' + CAST(@spid_blocking as varchar(5))
PRINT 'HOST  = ' + @hostname_blocking
PRINT 'LOGIN = ' + @loginname_blocking
PRINT 'HORARIO = ' + @post_time

— finalizar processo que esta bloqueando:
SET @cmd = 'KILL ' + CAST(@spid_blocking AS varchar(5))
EXEC sp_executesql @stmt = @cmd

— enviar e-mail:
SET @crlf =  CHAR(13) + CHAR(10)
SET @email_body  = ‘Informacoes’ + @crlf
SET @email_body += ‘Bloqueando: ‘ + @crlf
SET @email_body += ‘SPID  = ‘ + CAST(@spid_blocking as varchar(5)) + @crlf
SET @email_body += ‘LOGIN = ‘ + @loginname_blocking + @crlf
SET @email_body += ‘HOST  = ‘ + @hostname_blocking + @crlf
SET @email_body += @crlf
SET @email_body += ‘HORARIO = ‘ + @post_time + @crlf
SET @email_body += @crlf + @crlf
SET @email_body += ‘Dados do evento (XML):’
SET @email_body += @event_txt

SET @email_subject = ‘SQL SERVER – Informacoes sobre processos bloqueados’

EXEC msdb..sp_send_dbmail
@recipients = ‘dba@minhaempresa.com.br’,
@subject    = @email_subject,
@body       = @email_body;

— fim

END
GO

Finalmente, associo a proc à fila e efetuo a ativação:

ALTER QUEUE que_sysevents WITH
STATUS = ON,
RETENTION = OFF,
ACTIVATION (
STATUS = ON,
MAX_QUEUE_READERS = 3,
PROCEDURE_NAME = dbo.prc_ReceiveMsg,
EXECUTE AS ‘dbo’
)
;
GO

A saída produzida pelo comando PRINT fica registrada no log do SQL Server (arquivo ERRORLOG).

Referências utilizadas na pesquisa e implementação da solução:

Dica legal!
Valeu, Paulo!

Paulo Sant´anna, MVP

Ola pessoal,

Imaginem a seguinte situação. Você chega em um cliente, que por sua vez não tem documentação do ambiente ou alguém para te dar orientações e você precisa identificar se o servidor Windows que você está acessando é fisico ou virtual e mais, se for virtual, precisa saber sob qual tecnologia de virtualização (Hypervisor) aquele servidor está rodando.

Como fazer isso? Verificando os dispositivos no Gerenciador de Dispositivos, se a ferramenta de Integração com o Hardware está instalada…

Mas podemos fazer isso utilizando a ferramenta DetectVM, gratuita e que além de identificar se o servidor em questão é virtual informa em qual hypervisor (Hyper-V, VMWare ou Citrix) está baseado.

Como utilizar? Muito simples.

Faça o download aqui e execute no servidor que você quer obter as informações conforme exemplo abaixo:

Servidor Virtual rodando em VMWare

vm

Espero que tenham gostado da dica e até a próxima.

Ver o post original

PowerShell Remoto II – Exchange Server 2010

Seguindo o assunto do último post, vou demonstrar como fiz para conectar a uma sessão Powershell para administração do Exchange Server 2010. O link do post anterior é: http://wp.me/p15MPR-8C.

Bem, como meu computador estava fora do domínio, eu fiz uma conexão a outro servidor membro, e de lá estabeleci a conexão ao servidor Exchange. Os comandos estão na própria documentação do Exchange Server (http://technet.microsoft.com/en-us/library/dd298084.aspx).

$excred = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://w-ex10.dominio.com/PowerShell/ -Authentication Kerberos -Credential $excred
Import-PSSession $Session

 

Voilà!

No exemplo da figura, executei o cmdlet Get-ExchangeServer (doc aqui) com sucesso.

 

Bom final de semana a todos!

PowerShell Remoto

Hoje resolvi me dedicar a testar uma funcionalidade que vai me ajudar muito (espero): estabelecer uma sessão PowerShell em um computador remoto.

PowerShell
Qual o problema?

Bem, estabelecer uma sessão Powershell é simples (desde que no computador destino o serviço WinRM esteja iniciado e devidamente configurado):

Enter-PSSession -ComputerName W001

 
O problema é que o meu computador móvel não faz parte de domínio nenhum, e ao prestar suporte, preciso conectar a servidores de vários clientes diferentes. Como resolver esta questão?

Fiz o download de um e-book gratuito no site http://powershellbooks.com, chamado “Secrets of PowerShell Remoting”, e segui os passos delineados ali. Vou reproduzir os comandos necessários. O meu ambiente é o seguinte:

  • Laptop com Windows 8 Pro (PowerShell 3.0)
  • Servidor Windows Server 2008 R2 (PowerShell 2.0)

Vamos lá:

Fase 1 – Servidor

Aqui precisamos iniciar e configurar o serviço WinRM (Windows Remote Management). Podemos fazer isso executando o comando abaixo no Shell do Windows (cmd.exe):

winrm quickconfig

 
O próximo passo é habilitar o PowerShell remoto. Abrindo uma sessão local de PowerShell, rodamos o comando abaixo (é importante lembrar que é necessário abrir o PowerShell com a opção “Run As Administrator”):

Enable-PSRemoting

 
Este comando inicia (se não estiver iniciado), configura o serviço WinRM para início automático, cria um listener HTTP que “ouve” em todos endereços IP e habilita uma exceção no Firewall do Windows. Por padrão, apenas os administradores poderão efetuar a conexão; isso pode ser confirmado com o comando abaixo:

Get-PSSessionConfiguration | FT Name,Permission

 
O passo seguinte é instalar um certificado para comunicação HTTPS. Isso é necessário porque não ocorre autenticação mútua quando o cliente e o servidor PowerShell não fazem parte do mesmo domínio Active Directory. Não vou detalhar como obter um certificado SSL aqui neste post; isso pode ser feito pelo snap-in Certificates no MMC, quando há uma autoridade certificadora interna, ou usando a dica no e-book (Digicert Certificate Utility).

Uma vez que o certificado esteja instalado no armazenamento de certificados pessoais do computador, precisamos extrair duas informações do certificado:

  • Subject (“Issued To”)
  • Thumbprint

De posse destas informações vamos configurar o listener (todo o comando em uma linha única):

winrm create winrm/config/Listener?Address=*+Transport=HTTPS @{Hostname="xxx"; CertificateThumbprint="yyy"}

 
Neste commando, precisamos subsitituir estes valores:

  • * (asterisco) pelo endereço IP, caso desejemos que seja utilizado um IP especifico, ao invés de todos;
  • xxx: o subject do certificado. Normalmente é o FQDN do computador;
  • yyy: o thumbprint do certificado.

Um exemplo:

winrm create winrm/config/Listener?Address=*+Transport=HTTPS @{Hostname="W001.dominio.com"; CertificateThumbprint="4e24fbffd29ed04fa67baadb2502e0f6270fa236"}

 

Fase 2 – Cliente

Antes de iniciar, temos que nos certificar que podemos contatar o servidor usando o nome especificado no certificado. No meu ambiente fiz um “contorno” (nome elegante para uma coisa muito feia J): alterei o arquivo HOSTS; também funcionaria especificar o servidor DNS correto.

Agora podemos abrir uma sessão local de PowerShell e fazer a conexão com o servidor remoto:

$c = Get-Credential DOMINIO\Administrator
Enter-PSSession -ComputerName W001.dominio.com -Credential $c -UseSSL

 
Se tudo estiver correto, deverá aparecer um prompt indicando o nome do servidor remoto:

Se ocorrer um erro, informando que não é possível validar o certificado ou verificar se o mesmo foi revogado, isso significa que não é possível contatar a autoridade certificadora que emitiu o certificado. No meu ambiente, para simplificar, fiz uma alteração nas configurações da sessão PowerShell ANTES do estabelecimento da conexão, da seguinte forma:

$sopt = New-PSSessionOption -SkipCACheck -SkipCNCheck –SkipRevocationCheck
Enter-PSSession -ComputerName W001.dominio.com -Credential $c -UseSSL -SessionOption $sopt

 

Bem, espero que esta informação seja útil.

“Função” Substring dentro do Prompt de Comando

Olá a todos.

O post que inicia a semana não é especificamente sobre SQL Server, mas pode vir a ser utilizado.
Vamos entender melhor:

Ocasionalmente, precisamos efetuar backups de bancos de dados utilizando a data e hora atuais como parte do nome (como faz a “Backup Database Task”, dentro dos planos de execução).

Extrair estes dados utilizando as linguagens T-SQL ou VBScript é simples, mas o que dizer quando a execução do backup é feita através de uma tarefa agendada que invoca SQLCMD.EXE?

Há duas alternativas:

  1. Criar um arquivo com a lógica do backup, usando T-SQL, e passar como parâmetro do utilitário SQLCMD.EXE (SQLCMD -i input.sql …)
  2. Criar um arquivo BAT ou CMD e extrair os valores de dia, mês, ano, hora, minuto das variáveis de ambiente DATE e TIME.

O foco deste post é mostrar como implementar a segunda opção.

É uma funcionalidade pouco conhecida do Shell do Windows (cmd.exe) o uso do operador :~ em conjunto com outras variáveis de ambiente.
Por exemplo:

SET VAR1=HELLO
ECHO %VAR1:~2%

O resultado é “LLO”; significa que são retornados os caracteres a partir da posição 3 (sim, o primeiro valor do índice é zero) até o fim da string.
Se quisermos apenas alguns caracteres, temos que informar a quantidade ao usar o operador:

ECHO %VAR1:~2,2%

Resultado: LL

Com base nestes resultados, já podemos criar nosso arquivo batch que fará a execução do backup:

@ECHO OFF

SET DT=%DATE:~6,4%-%DATE:~3,2%-%DATE:~0,2%

SET TM=%TIME:~0,2%-%TIME:~3,2%-%TIME:~6,2%

SQLCMD -E -S . -Q “BACKUP DATABASE [DB1] TO DISK = ‘D:\Temp\Backup\DB1_FULL_%DT%_%TM%.BAK’ WITH INIT “

Agora, podemos incrementar nosso arquivo batch com parâmetros para substituição, log, etc.

Atualização:

No meu ambiente, as configurações regionais estão definidas como Português-Brasil (formato DD/MM/YYYY. Logo, se o servidor ou estação estiver em inglês ou outro idioma, será necessário fazer uma adaptação.

 

Espero que tenha contribuído.
Boa semana a todos.