Profil de DemétrioDemétrio Silva - Sql Ser...BlogListesRéseauPlus Outils Aide

Demétrio Silva - Sql Server

Demétrio Silva

Occupation
Lieu
Dossiers publics
22 novembre

Acesso remoto com PowerShell

Ae galera, estou estudando o PS a fundo. Em várias fontes que li, apenas mostra como executar comandos PS em máquinas remotas que estão na mesma rede. O comando é mais ou menos assim ( para o caso de informações sobre discos lógicos ). Farei alguns comentários no código para melhor entendimento. O "#" é o indicador de comentário do PS

clear-host #mesma coisa que cls
Get-WmiObject "win32_logicaldisk" -ComputerName "NomeOuIPdaMáquinaRemota" #retorna um objeto WMI com informações dos discos lógicos


No entanto, se você estiver em uma VPN ou numa rede que seu usuário do Windows não possui acesso às máquinas, o script acima vai gerar o seguinte erro

Acesso negado. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
At :line:1 char:13
+ Get-WmiObject <<<<  "win32_logicaldisk" -ComputerName "NomeOuIPdaMáquinaRemota"

Pois é necessário indicar o usuário e senha para acesso ao PC remoto. Daí muitos blogs, livros, etc postam o seguinte código:

clear-host
$cred = Get-Credential "Domínio\usuario ou apenas usuário" #retorna um objeto com as credenciais do usuário 
Get-WmiObject "win32_logicaldisk" -ComputerName "NomeOuIPdaMáquinaRemota" -Credential $cred

Agora sim, passo o usuário e o PS consegue acessar o PC remoto tranquilamento ok?

Não. A Microsoft, nos seus novos produtos, adotou os procedimentos de "Defaul Protected" ( Seguro por Padrão ). Logo, o PS não permite que os programadores informem a senha nos scripts. Com isso, o script acima funciona sim, no entanto, o Windows Abre uma tela para que o executor do script acima informe a senha do usuário.

Imagine que você precise executar um script desses acima em 200 máquinas? Ao menos na primeira vez, você teria que especificar a senha 200 vezes. Isso não é nada elegante.

Conversando com alguns MVPs em scripts, em especial o Shay ( que o meu amigo Laerte me apresentou ), fiquei sabendo que posso salvar as credenciais de usuários em arquivos criptografados e depois passar essas credenciais via PS. Para isso, usei o pass through authentication ( conversando com meu amigo Alberto, MVP Forefront, fiquei sabendo que se tenho o mesmo usuário nas 200 máquinas com a mesma senha, quando logo na primeira máquina tenho acesso à todas as outras ). Com isso, precisei apenas salvar uma credencial. Segue script abaixo:

clear-host
$cred=get-credential "nomeDaMaquina"
$cred.password | ConvertFrom-SecureString | Set-Content c:\nomeDoArquivoASerGravadaACredencial.txt

O Script acima salva as informações das credenciais informadas pelo usuário ( o Windows abre uma tela para que o programador informe user e senha )

Uma vez criada a credencial, podemos usá-la quantas quisermos em nossos scripts. Veja abaixo:

$pw = Get-Content c:\nomeDoArquivoASerGravadaACredencial.txt | ConvertTo-SecureString
$cred = New-Object System.Management.Automation.PsCredential("userName", $pw) #onde userName é o usuário informado no script acima

Get-WmiObject Win32_logicaldisk -computername "nomeDaMaquina" -Credential $cred #onde -computername é o mesmo do script acima.

Agora sim, podemos executar o script via agendador de tarefas sem qualquer intervenção do usuário.

Espero que a dica tenha sido útil.

Abraços

Demétrio Silva















Baixando e instalando o PowerShell

Ae galera, estou há um tempo sem postar nada no blog pois as coisas estão meio corridas para mim ( fazendo cursos, novo emprego, faculdade, etc. ).

A partir de hoje vou também sobre o Windows PowerShell. O PowerShell, também conhecido como PS, é um novo Shell do Windows que é orientada a objetos e que nos ajuda muito em tarefas do dia-a-dia ( verificar espaço em disco, configuração da rede, do PC, etc ).

Onde baixar?

http://technet.microsoft.com/pt-br/scriptcenter/dd742419(en-us).aspx

Para ajudar na construção dos códigos, eu uso a IDE PowerGUI. ( melhor IDE para o PowerShell )

http://www.powergui.org/index.jspa

Bom, vamos deixar de conversa e mostrar alguma coisa que o PS pode fazer. Após baixar e instalar o PS,  instale o PowerGui ou execute o PS via linha de comando ( executar / cmd / powershell ), isso exibe uma janela com o shell do PS.

E pra finalizar, não podemos de executar o Hello Word, como qualquer exemplo inicial das linguagens.

Digite "Hello Word".

O que? Só isso? Isso mesmo, é o menor Hello Word que existe. Viu como é simples?

Logo postarei mais detalhes.

Não deixem de visitar o blog do meu amigo Laerte. Melhor fonte de informações sobre PS em SQL Server do Brasil.

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

Abraços
8 septembre

Situações onde o bloco catch não é executado

Galera,

 

Hoje vou falar sobre um assunto bem interessante: Situações onde o bloco catch não é executado. Essa semana eu estava lendo sobre este assunto e achei útil mostrar em que situações o bloco catch não é executado.

 

Abaixo temos alguns exemplos:

 

KILL ou Timeout do comando

 

Imagine ter um código onde você realiza vários updates em uma ou várias tabelas dentro de um bloco begin try e, caso exista algum problema durante a atualização, a transação deve ser revertida e a linha e mensagem de erro devem ser logadas em uma tabela destinada ao log de erros.

 

Bom, vamos criar nossa base de dados e as tabelas conforme script abaixo:

--CRIA E COLOCA EM USO O DATABASE

CREATE DATABASE DB_TESTE

GO

 

USE DB_TESTE

GO

 

--CRIA TABELA QUE VAI ARMAZENAR OS ERROS OCORRIDOS

CREATE TABLE TB_ERROR(ELINE INT ,  EMESSAGE nvarchar(2048))

 

--CRIA A TABELA PARA TESTAR O UPDATE

CREATE TABLE CLIENTE ( ID INT, NOME VARCHAR(10), STATUS CHAR(1))

GO

 

--ADICIONA UMA CHECK PARA O CAMPO STATUS ( A = ATIVO, I = INATIVO )

ALTER TABLE CLIENTE  WITH CHECK ADD  CONSTRAINT CK_STATUS CHECK ( STATUS = 'A' OR STATUS = 'I')

GO

 

--POPULA A TABELA

INSERT INTO CLIENTE( ID, NOME, STATUS ) VALUES ( 1, 'DEMÉTRIO', 'A' )

INSERT INTO CLIENTE( ID, NOME, STATUS ) VALUES ( 2, 'MARIA', 'A' )

INSERT INTO CLIENTE( ID, NOME, STATUS ) VALUES ( 3, 'JOSÉ', 'A' )

INSERT INTO CLIENTE( ID, NOME, STATUS ) VALUES ( 4, 'JOÃO', 'I' )

INSERT INTO CLIENTE( ID, NOME, STATUS ) VALUES ( 5, 'PEDRO', 'I' )

 

--VERIFICA OS DADOS INSERIDOS

SELECT * FROM CLIENTE

Bom, conforme podemos verificar, o script abaixo realiza dois updates na tabela, sendo que o segundo gera um erro. Ao capturar o erro, o bloco catch realiza o rollback da transação e insere a linha e mensagem de erro na tabela TB_ERROR.

BEGIN TRY

     

      BEGIN TRAN

           

            --ATUALIZA TODOS OS DADOS DO CAMPO NOME DA TABELA

            UPDATE CLIENTE SET NOME += '_'

           

            --ATUALIZA TODOS OS STATUS PARA 'L', VAI GERAR ERRO POR CAUSA DA CHECK CONSTRAINT

            UPDATE CLIENTE SET STATUS = 'L'

     

      COMMIT

     

END TRY

BEGIN CATCH

 

      --SE HOUVE ERRO, REVERTE A TRANSAÇÃO E LOGA O ERRO NA TABELA

      IF @@TRANCOUNT > 0

            ROLLBACK

 

      INSERT INTO TB_ERROR ( ELINE, EMESSAGE )

      SELECT

            ERROR_LINE(),

            ERROR_MESSAGE()        

           

END CATCH

 

 

Como podemos verificar no select abaixo, o primeiro update é revertido e um registro é gravado na tabela de log.

SELECT * FROM CLIENTE

SELECT * FROM TB_ERROR

--LIMPA O LOG DE ERROS

DELETE TB_ERROR

Até agora sem problemas. Mas, e se alguém executar um kill ou mesmo existir um timeout na conexão que está executando o update?

A transação é revertida, não através do rollback contido no bloco catch, mas sim porque esse é procedimento executado quando utilizamos um kill contra algum processo. No entanto, note que o insert na tabela de log não é executado, ou seja, isso é uma prova que o bloco catch não foi executado.

Abra duas conexões no SSMS e execute o código abaixo:

BEGIN TRY

     

      BEGIN TRAN

           

            --ATUALIZA TODOS OS DADOS DO CAMPO NOME DA TABELA

            UPDATE CLIENTE SET NOME += '_'

           

--AGUARDA 5 MINUTOS PARA DAR TEMPO DE REALIZAR O KILL

            WAITFOR DELAY '00:05:00'

           

            --ATUALIZA TODOS OS STATUS PARA 'L', VAI GERAR POR CAUSA DA CHECK CONSTRAINT

            UPDATE CLIENTE SET STATUS = 'L'

     

      COMMIT

     

END TRY

BEGIN CATCH

 

      --SE HOUVE ERRO, REVERTE A TRANSAÇÃO E LOGA O ERRO NA TABELA

      IF @@TRANCOUNT > 0

            ROLLBACK

 

      INSERT INTO TB_ERROR ( ELINE, EMESSAGE )

      SELECT

            ERROR_LINE(),

            ERROR_MESSAGE()        

           

END CATCH

Verifique o spid da conexão que está o script acima e na outra janela do SSMS execute o comando KILL passando o spid da conexão acima.

Após matar o processo acima, volte na janela que encontra-se o script acima e veja que o SQL Server gerou o seguinte erro.

Msg 0, Level 11, State 0, Line 0

A severe error occurred on the current command.  The results, if any, should be discarded.

Msg 0, Level 20, State 0, Line 0

A severe error occurred on the current command.  The results, if any, should be discarded.

Agora, verifique que a transação foi revertida mas que nenhuma linha foi inserida no log de erros:

SELECT * FROM CLIENTE

SELECT * FROM TB_ERROR

Esse é um dos casos onde o catch não é executado, o mesmo acontece quando existe um timeout, devemos ficar atento quando estivermos utilizando o catch e fazendo algum tratamento dentro do mesmo.

É isso ai, num próximo post irei mostrar outras situações onde o bloco catch não é executado.

Abraços

11 août

SQL Server 2008 R2 CTP

Galera,

Pra quem ainda não viu, a Microsoft acaba de disponibilizar a versão CTP do SQL Server 2008 R2 para Download.

Mais informações:

http://www.microsoft.com/sqlserver/2008/en/us/R2.aspx
http://msdn.microsoft.com/en-us/evalcenter/ee315247.aspx

Abraços
22 juillet

Revista Codificando.NET

Ae galera,

Pra quem ainda não conhece, o grupo Codificando.Net disponibiliza uma revista eletrônica gratuitamente, o material é de muito boa qualidade e vale a pena dar uma olhada.

http://www.codificandomagazine.net/revista/

Abraços