Como instalar um servidor de email na máquina virtual de Visual Studio ALM (VSALM VM)

Se você usa a máquina virtual de Visual Studio ALM, seja para estudos ou demonstrações, pode já ter sentido a necessidade de configurar um servidor de emails na máquina virtual.

Essa necessidade fica ainda mais óbvia quando queremos testar (ou praticar) funcionalidades cujo fluxo de trabalho dependa extensivamente de emails, como a Aprovação de Releases ou a Solicitação de Feedback.

Explorei algumas opções, e acho que finalmente cheguei numa que atendeu perfeitamente à minha necessidade.

Mas já não tem um servidor de email configurado na VM?

Na verdade não. O que vem pré-configurado na VM é apenas o Serviço de SMTP. E um serviço de SMTP não é a mesma coisa que um servidor de emails, pois ele cuida apenas de uma parte do processo: o envio dos emails. Ou seja, você consegue enviar emails a partir da máquina virtual, mas não consegue recebe-los usando uma das contas locais usadas na VM (tal como a VSALM\brian).

Minha principal premissa ao usar essa máquina virtual – seja para minhas palestras ou para apresentações/treinamentos em clientes – é sempre que ela seja auto-suficiente. Sendo assim, qualquer processo de envio, armazenamento e leitura de emails deve acontecer dentro da máquina virtual, sem depender de nenhum serviço de email externo como o Office 365, Outlook.com ou Gmail.

Por isso, o serviço de SMTP pré-configurado não basta. Preciso de um servidor completo, que ofereça não apenas o envio (SMTP) mas também o armazenamento e o acesso para leitura (via POP3, IMAP, ActiveSync ou equivalente).

Servidores de Email para Windows

Como a "VM do Brian Keller" 1 é um Windows Server, busquei servidores de email para Windows. A única 2 resposta da Microsoft é o Exchange Server, o que – como é de se esperar – não é uma opção viável, dado que não quero deixar minha VM mais "pesada" que o necessário. O Exchange Server é um excelente produto, mas é absurdamente exagerado para as minhas necessidades simples de envio e recebimento de emails.

Fui então procurar alternativas leves e gratuitas, que pudesse instalar sem maiores preocupações na minha VM. Foi aí que descobri o hMailServer.

o hMailServer é um servidor de email de código aberto e gratuito, escrito para ambientes Windows. Ele oferece os serviços essenciais de que preciso – SMTP, IMAP e POP3 – sem consumir as dezenas de gigabytes de um Exchange Server. Resolve meu problema! 😃

Instalando o hMailServer

Primeiramento, ligue a máquina virtual e conecte-se a ela com o usuário Administrator.

Fazendo login na VM com o usuário Administrator
Fazendo login na VM com o usuário Administrator

A instalação do hMailServer é, em si, trivial. Next-Next-Finish típico do Windows. O único ponto de atenção é que, antes de instalar o hMailServer, é preciso desativar o serviço de SMTP que veio pré-instalado na VM.

Para isso, execute os seguintes comandos num prompt elevado de PowerShell (sempre dentro da máquina virtual):

Stop-Service smtpsvc
Set-Service smtpsvc -StartupType Disabled

Por fim, pode baixar e iniciar o instalador do hMailServer.

Durante a instalação ele oferece dois backends: um mais simples, baseado em SQL Server Compact Edition, e outro baseado em um servidor de banco de dados externo (como MySQL, PostgreSQL ou SQL Server). Como para a nossa finalidade não precisamos de nada muito robusto, aceite a sugestão do instalador e escolha Use built-in database engine (Microsoft SQL Compact).

Tela de seleção do backend do hMailServer
Tela de seleção do backend do hMailServer

Agora, é preciso selecionar uma senha para o usuário Administrator. Por uma questão de consistência (fica mais fácil de lembrar), sugiro que você coloque a senha P2ssw0rd (a senha-padrão usada por todos os usuários da VM).

Tela de configuração da senha do administrator do hMailServer. Sugestão: use "P2ssw0rd" (sem as aspas)
Tela de configuração da senha do administrator do hMailServer. Sugestão: use "P2ssw0rd" (sem as aspas)

Com isso, está feita a instalação. Agora, vamos começar a configuração.

Configurando o serviço de email

Ainda que a instalação seja simples, o que temos até agora é um servidor que não faz absolutamente nada. Precisamos primeiramente:

  1. Configurar um domínio. Para criar contas de email, é necessário definir um domínio DNS para esse emails. Como quero uma VM auto-suficiente (e não quero ter de subir um servidor de DNS só para isso), vou criar um domínio local vsalm.local;
  2. Criar as contas de email. Quero que cada usuário local da VM tenha sua própria conta de email. Assim, posso fazer várias simulações de envio de emails (por exemplo, definindo diferentes aprovadores num workflow de Release Management). O email do usuário Brian Keller, por exemplo, ficaria brian@vsalm.local;
  3. Configurar o Outlook. A VM já vem com o Office pré-instalado (na versão 2017 da VM, temos o Office 2016). Por uma questão de conveniência, quero poder acessar os emails de um dado usuário partir do Outlook, bastando eu estar logado com esse usuário;
  4. Reconfigurar o TFS. Como o TFS vem pré-configurado para utilizar o serviço de SMTP nativo do Windows, precisaremos fazer alguns pequenos ajustes.

Toda a configuração do hMailServer pode ser feita pela interface gráfica (aliás, essa é a maneira sugerida pelo próprio produto), mas é possível fazer também pela linha de comando. Como a automação do hMailServer é feita através de uma API COM, usaremos o PowerShell para interagir com os objetos do hMailServer.

Como fazer pela linha de comando é mais simples e robusto (além de mais legal 😃), vamos fazer tudo pela linha de comando!

Configuração do domínio

A configuração do domínio implica em criar, dentro no hMailServer, um domínio de emails para o endereço vsalm.local. Como todo o processo de envio e recebimento de emails acontece dentro do próprio hMailServer (lembre-se, quero uma VM auto-suficiente), não preciso me preocupar com DNS, registros MX nem nada do gênero. Sempre que eu enviar um email para algum endereço @vsalm.local, o hMailServer deverá entender que se trata de um domínio local e, portanto, não precisará fazer relay para um SMTP externo. Toda essa explicação serve para dizer que não preciso me preocupar com resolução de endereços. Tudo acontece no localhost.

# Conecta ao hMailServer
$app = New-Object -ComObject 'hMailServer.Application'
$app.Authenticate('Administrator', 'P2ssw0rd')

# Cria o novo domínio
$domain = $app.Domains.Add()
$domain.Name = 'vsalm.local'
$domain.Active = $true
$domain.Save()

Criação das contas de email

Para criar as contas de email, vou enumerar as contas locais no servidor (ignorando as contas especiais Guest e DefaultAccount). O script é abaixo é idempotente, então basta executá-lo novamente para adicionar novas caixas de correio, no caso de você ter adicionado outros usuários locais ao Windows.

# Conecta ao hMailServer
$app = New-Object -ComObject 'hMailServer.Application'
$app.Authenticate('Administrator', 'P2ssw0rd')
$domain = $app.Domains.ItemByName('vsalm.local')

# Obtém a lista de usuários
$users = Get-WmiObject -Class Win32_UserAccount -Filter "LocalAccount='True'" | Select Name, FullName | Where Name -NotIn ('DefaultAccount', 'Guest')

# Cria as contas
foreach($u in $users)
{
    $email = "$($u.Name)@vsalm.local"
    
    # Evita a criação de duplicatas
    if ($domain.Accounts.ItemByAddress($email))
    {
        Write-Warning "Email $email já existe. Ignorando..."
        Continue
    }
    
    Write-Output "Criando $email..."
    $acct = $domain.Accounts.Add()
    $acct.Address = $email
    $acct.Password = "P2ssw0rd"
    $acct.Active = $true
    $acct.Save()
}

Configuração do Outlook

Ao abrir o Outlook pela primeira vez na VM é iniciado automaticamente o assistente de configuração. Como não estamos usando um serviço de DNS nem um Exchange Server não dá para usar a Auto-descoberta ("AutoDiscovery") para configurar automaticamente o Outlook. Assim, na página inicial, selecione a opção de Configuração Manual:

Página inicial do assistente de configuração do Outlook 2016, com a opção de Configuração Manual selecionada
Página inicial do assistente de configuração do Outlook 2016, com a opção de Configuração Manual selecionada

Na página seguinte, selecione a opção POP ou IMAP:

Página do assistente de configuração do Outlook 2016 para a seleção do tipo de conta, com a opção "POP ou IMAP" selecionada
Página do assistente de configuração do Outlook 2016 para a seleção do tipo de conta, com a opção "POP ou IMAP" selecionada

Na última etapa do assistente, entre com os dados do usuário com quem você está logado agora:

  • Seu nome: Nome do usuário logado
  • Endereço de email: Endereço de email (<nome do usuário>@vsalm.local)
  • Tipo de conta: IMAP
  • Servidor de entrada: localhost
  • Servidor de saída: localhost
  • Nome de usuário: Repita o endereço de email (<nome do usuário>@vsalm.local)
  • Senha: P2ssw0rd

Página final da configuração da conta de email, com os dados da conta
Página final da configuração da conta de email, com os dados da conta

Enxágue e repita. Será preciso logar ao menos uma vez com cada um dos usuários para os quais você quer configurar o Outlook. Repita todo o processo acima para cada usuário que deve poder enviar e/ou receber emails no Outlook.

Reconfiguração do TFS

Agora precisamos "ensinar" ao TFS como usar esse novo servidor de email. Isso implica em duas coisas:

  1. Alterar as configurações de SMTP do TFS, para que ele seja capaz de enviar os emails através do servidor correto; e
  2. Definir o endereço de email de cada usuário, para que ao configurar uma notificação ou solicitar um feedback para um dado usuário, o TFS saiba qual o usuário correspondente.

Para a primeira parte, execute o comando abaixo num prompt elevado do PowerShell:

$TfsConfig = 'C:\Program Files\Microsoft Team Foundation Server 15.0\Tools\TfsConfig.exe'

& $TfsConfig configureMail /Enabled:true /FromEmailAddress:tfs-noreply@vslam.local /SmtpHost:localhost

Dica

Repare que defini o endereço do remetente com tfs-noreply@vsalm.com. Tenho o hábito de usar sempre esse endereço de email ("tfs-noreply@…") como forma de indicar aos destinatários dos emails gerados pelo TFS que aqueles são email automáticos, gerados pelo TFS, e que não devem ser respondidos pois não vêm de uma caixa de email monitorada. Não é obrigatório, mas é uma boa prática.

Já para a segunda parte, o script é um pouco mais complexo. Entretanto, é infinitamente mais conveniente do que ter de logar com cada usuário, abrir a home do TFS e entrar na seção My Profile para informar o Preferred email address

Mais uma vez: Abra um prompt elevado de PowerShell, logado como Administrator, e execute o script abaixo.

Add-Type -Path 'C:\Program Files\Common Files\microsoft shared\Team Foundation Server\15.0\Microsoft.TeamFoundation.Client.dll'
Add-Type -Path 'C:\Program Files\Common Files\microsoft shared\Team Foundation Server\15.0\Microsoft.TeamFoundation.WorkItemTracking.Client.dll' 

$uri =  [uri]'http://vsalm:8080/tfs/'
$creds = New-Object 'System.Net.NetworkCredential' -ArgumentList @('Administrator', 'P2ssw0rd')
$server = New-Object 'Microsoft.TeamFoundation.Client.TfsConfigurationServer'-ArgumentList @($uri, $creds)
$server.EnsureAuthenticated();

$ims = $server.GetService([type] 'Microsoft.TeamFoundation.Framework.Client.IIdentityManagementService2')
$groups = $ims.ReadIdentity([Microsoft.TeamFoundation.Framework.Common.IdentitySearchFactor]::AccountName, "[TEAM FOUNDATION]\Team Foundation Valid Users", [Microsoft.TeamFoundation.Framework.Common.MembershipQuery]::Expanded, [Microsoft.TeamFoundation.Framework.Common.ReadIdentityOptions]::IncludeReadFromSource).Members
$users = $ims.ReadIdentities($groups, [Microsoft.TeamFoundation.Framework.Common.MembershipQuery]::Expanded, [Microsoft.TeamFoundation.Framework.Common.ReadIdentityOptions]::ExtendedProperties) | ? { $_.UniqueName -Like 'vsalm*' -and -not $_.IsContainer}

foreach($u in $users)
{
    Write-Output "Atualizando o email de $($u.UniqueName)..."

    $accountName = $u.GetProperty("Account")
    $u.SetProperty('CustomNotificationAddresses', "$accountName@vsalm.local")
    $ims.UpdateExtendedProperties($u)
}

Pronto! Missão cumprida!

Conclusão

A "VM do Brian Keller" tem muita coisa legal para ajudar a experimentar o TFS e seus diversos recursos de ALM e DevOps – e ela fica ainda mais legal com um servidor de emails de verdade, que nos permita reproduzir mais fielmente o dia-a-dia de usuários da ferramenta.

E aí, o que você achou? Deixe seu comentário!

Um abraço,
Igor


  1. Brian Keller era um evangelista da Microsoft que, originalmente, foi o responsável pela máquina virtual distribuída com os produtos de ALM da Microsoft (TFS, Visual Studio). Já faz muito tempo que o Brian passou o bastão e não é mais o "dono da VM" – atualmente ele está numa outra função dentro da Microsoft – mas depois de ficar tanto tempo à frente dessa iniciativa, é difícil para o pessoal "das antigas" (como eu) se desapegar do apelido de "VM do Brian Keller".

  2. A bem da verdade, no passado a Microsoft já ofereceu um serviço de POP3 nativo no Windows Server, como complemento ao SMTP (que existe até hoje). Esse serviço, se ainda estivesse disponível, teria resolvido meu problema. Mas como foi descontinuado já há um bom tempo, não me serve de nada…

Autor: Igor Abade

Igor Abade V. Leite (igoravl@mvps.org) é Microsoft MVP (Most Valuable Professional) de Visual Studio ALM desde 2006. Palestrante em diversos eventos da comunidade de desenvolvimento de software (TechEd Brasil, The Developers’ Conference, DevOps Summit Brasil, Agile Brazil, Visual Studio Summit, QCON e outros), é também autor de artigos em revistas e sites como o MSDN Brasil. Desde março de 2011 é um dos sócios da Lambda3, uma consultoria especializada em ALM, desenvolvimento de software e treinamentos. Visite seu blog sobre VS ALM em http://www.tshooter.com.br/ e siga-o no Twitter @igorabade.

Deixe seu comentário!