Início > Windows PowerShell > PoSh – Comparando arquivos com o command let Compare-Object

PoSh – Comparando arquivos com o command let Compare-Object

abril 24, 2016

Olá pessoALL,

Neste post eu irei falar sobre um command let excelente que acompanha o Windows PowerShell: o Compare-Object.

Ao longo do nosso dia a dia de trabalho, comparar determinado arquivo, conteúdo entre diretórios, objetos no Active Directory e outras necessidades mais podem nos pegar de surpresa e fazer com que uma solução de terceiros seja utilizada, por exemplo, um addin do Notepad++.

Entretando, algumas pessoas desconhecem que o Windows PowerShell tem um command let que permite este tipo de ação facilitando a nossa vida na comparação entre uma coisa e outra coisa.

Introdução

Durante o nosso dia a dia de trabalho certamente haverão situações onde se faz necessário verificar determinados itens para gerar evidências de que uma ação foi executada de fato.

Comparar a existência do mesmo serviço em dois ou mais nós em um Failover Cluster, um diretório de log em dois ou mais servidores que suportam uma aplicação balanceada, etc.

Pode parecer trivial quando estamos falando de poucos servidores a serem verificados, poucos arquivos, etc., mas em grande escala, isso pode ser algo passível de erros humanos quando feito pelo olho humano.

Por este motivo, automatizar esta tarefa para garantir que o resultado final está de fato em conformidade com o que é esperado se torna muito importante.

O cenário

Você é uma das pessoas responsáveis por executar mudanças em seu ambiente de trabalho. Constantemente o time de desenvolvimento envia mudanças que se resumem na troca da versão de arquivos necessários para a execução de suas soluções.

Após executar diversas mudanças, você é procurado por um dos desenvolvedores que relata que sua solução não está apresentando a melhoria que deveria apresentar após a mudança.

O desenvolvedor suspeita que os arquivos que deveriam ter sido substituídos não foram e solicita a você que confirme que os arquivos enviados na mudança estão de fato no diretório do servidor onde a solução está implementada.

Você verifica o pacote onde estão os arquivos que copiou e constata que há uma centena de arquivos. Compará-los um a um seria um processo bem demorado e nada produtivo, então você se pergunta: há uma forma mais rápida e prática de se obter este resultado?

A solução

Como eu informei no inicio do post, o conhecimento de que há um command let para comparar saídas não é algo muito comum até mesmo entre profissionais que usam Windows PowerShell, logo, vamos ver a seguir como é simples a comparação de arquivos neste tipo de situação.

Digamos que existe um diretório C:\App1 onde a solução do desenvolvedor está instalada e que existe um sub diretório chamado BIN onde existem diversas DLLs que a solução faz uso.

A mudança solicitada pelo desenvolvedor consiste em copiar o conteúdo do diretório BIN localizado em um repositório central para o diretório C:\App1\BIN no servidor de aplicação.

Por questões de segurança e centralização, existe um repositório localizado em um NAS, File Server ou qualquer outro tipo de recurso de rede onde os arquivos utilizados nas mudanças estão armazenados.

Vamos utilizar neste exemplo o local \\W11001PFS02\CM_REPOSITORY\App1\P00001.

Então para chegarmos ao objetivo deste post, nós vamos começar abrindo o Windows PowerShell e executando o comando abaixo:

PoSh-Compare-Object-Files-0001

Vejamos que situação interessante é esta acima onde você pode comparar a saída de outros command lets do Windows PowerShell. Apenas com o exemplo acima é possível pensar em outras situações onde o mesmo tipo de conceito pode ser aplicado.

Vamos voltar ao nosso objetivo e entender o que foi retornado no comando anterior. Por padrão, todo command let tem uma saída definida para o uso do pipe e no caso do Get-ChildItem a saída padrão é o atributo Name. Da forma que os command lets foram usado, não é possível determinarmos se os arquivos são ou não iguais.

Para colocarmos em check esta validação, nós vamos utilizar duas propriedades retornadas pelo Get-ChildItem:

  • Name
  • LastWriteTime

Mas como nós podemos utilizar estas propriedades em conjunto com o Compare-Object? Simples! O command let Compare-Object possui um parametro chamado -Property onde é possível determinarmos quais propriedades serão comparadas entre as saídas.

Deixe-me alterar o comando anterior para que ele reflita o que nós esperamos comparar:

PoSh-Compare-Object-Files-0002

E aqui estamos com o que pretendiamos e para finalizar, vamos entender o que significa a coluna SideIndicator. esta coluna mostra três (3) tipos de sinais:

  • == significa que não há diferenças entre os objetos;
  • => significa que a diferença está no objeto informado no parametro -DiffenrentObject;
  • <= significa que a diferença está no objeto informado no parametro -ReferenceObject.

Com base na imagem acima, nós podemos deduzir que a mudança não foi feita como esperado pelo desenvolvedor e que os arquivos estão completamente diferentes, então, vamos atualizar o diretório da aplicação App1 e executar o comando novamente para compararmos a saída.

PoSh-Compare-Object-Files-0003

Agora o que nós temos são repositório e diretório da aplicação equalizados como o esperado e o nosso objetivo atingido: comparar arquivos entre diretórios de tal forma que seja possível validar que ambos estão idênticos ou não.

Conclusão

Uma solução simples, que muitas vezes não é tão obvia para muitos profissionais e que pode ser utilizada não somente na situação que exemplificamos agora, mas em muitas outras, como por exemplo, validar que dois servidores possuem os mesmos serviços, com o mesmo tipo de configuração de inicialização.

Imagine um Failover Cluster de serviços genéricos onde um serviço X foi instalado apenas em um dos nós.

Infelizmente o processo de inclusão de um serviço genérico em um recurso do WSFC não valida se o mesmo está presente em todos os nós e se você não verificar este item, certamente você irá perceber que cometeu o erro de não instalar o serviço em todos os nós apenas no momento em que ocorrer o failover do recurso.

É isto pessoal! Neste post nós aprendemos como verificar e validar propriedades oriundas de outros command lets através do Compare-Object de forma fácil para garantir que ambos os itens comparados estão de acordo com o esperado e caso não, seja possível corrigir suas diferenças.

Até o próximo post…

%d blogueiros gostam disto: