Quem lembra do net send do Windows XP, pois bem, chegou a hora de aposentar ele.

Bem-vindo msg.exe!

O msg.exe envia uma mensagem para um usuário. Este usuário deve estar conectado como usuário de domínio (Perfil de Domínio). O que significa que o seguinte funciona apenas em um ambiente de domínio. Para técnicos de rede: msg usa a porta 445 (SMB / CIFS). Se você enviar uma mensagem para um usuário, precisará fornecer um nome de computador e um nome de usuário. Ou você pode tentar enviar uma mensagem para si mesmo:

 

* significa que a mensagem é enviada a todos os usuários conectados. Lembre-se de que o Windows é um sistema operacional multiusuário. Não esqueça os outros!

Imagine a seguinte situação, você precisa enviar uma mensagem a todos os computadores clientes que estejam armazenados em um OU (Unidade Organizacional) específica, denominada Desktops. Você deseja informar a todos usuários conectados a esses computadores. Vamos usar o comando Invoke-Command. Verifique se os computadores clientes aceitam comandos do Remote PowerShell. Você pode executar o Enable-PSRemoting em cada um deles. Ou você pode configurar o WinRM usando diretivas de grupo, conforme demostrei neste artigo aqui.

Pré requisitos

  • Todos os computadores devem residir no mesmo domínio.
  • O WinRM deve ser ativado nos computadores clientes executando Enable-PSRemoting ou configurando através de Diretivas de Grupo, conforme descrito no link acima. Observe que, nos sistemas operacionais Windows Server 2012/2016, o WinRM é ativado por padrão, mas não nos sistemas Windows Client.
  • Abrir a porta 445 no firewall.

 

Powershell e msg.exe em Ação

 

 

 

 

Primeiro execute o Powershell como administrador.

Vamos aprender agora enviar uma mensagem a todos os usuários conectados nas estações de trabalho que estão na OU (Unidade Organizacional) com o nome Desktops, com a seguinte mensagem: “Feche todos os arquivos abertos. O servidor será desligado em 5 minutos.”.

Agora vamos aprender a enviar a mesma mensagem, mas com um diferencial, vamos ter um time, a mensagem vai ficar 15 minutos ou até a hora que usuário ler e clicar em OK na mensagem enviada.

Observação: O parâmetro time será contado em segundos. 900 é o que equivalente a 15 minutos.

 

Um outro parâmetro que podemos adicionar um usuário específico, neste exemplo será o carlos.luiz, o comando fica assim:

Observação: O usuário deve estar conectado no momento.

 

Agora vamos usar o msg.exe sem o Powershell.

Primeiro execute o CMD (Prompt de Comando) como administrador.

Podemos enviar mensagens para um computador e usuários, ambos devem estar conectados. Para isso usamos o seguinte comando:

Observação: o parâmetro server é o hostname do computador no qual queremos enviar a mensagem que é o DESKTOP-6KHKKLM, também devemos colocar o usuário que estar conectado, neste exemplo será o usuário gabriel.luiz.

 

Referências

 

 

 

 

https://docs.microsoft.com/pt-br/windows-server/administration/windows-commands/msg

https://docs.microsoft.com/en-us/powershell/module/addsadministration/get-adcomputer?view=win10-ps

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/invoke-command?view=powershell-7

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/foreach-object?view=powershell-7

 

Inscreva-se no meu canal do YouTube!

25 Responses

  1. Boa tarde estou executando do comando através do Windows 10 Pro, e o comandao Get-ADComputer não é reconhecido. Eu preciso habilitar algo além das configurações acima citadas?

  2. Boa tarde Gabriel Luiz,

    Obrigado pelo post, muito útil, fiquei com duvidas somente em dois pontos.

    Na linha de comando que você enviou com o timer de 15 minutos, ficou identica a primeira, entao nao consegui entender as variaveis para o tempo, se puder mandar por favor, ambas estão assim:

    (Get-ADComputer -SearchBase “OU=Desktops,DC=contoso,DC=local” -Filter *).Name | Foreach-Object {Invoke-Command -ComputerName $_ {msg * “Feche todos os arquivos abertos. O servidor será desligado em 5 minutos.”}}

    Outra coisa é que o nome do dominio por aqui é task.local então eu precisaria colocar DC=task, DC=local?

    • Bom dia. Muito obrigado por prestigiar o meu trabalho.
      Foi apenas um erro de digitação, já fiz a correção. Correto DC=task, DC=local se seu domínio for igual a task.local. Mas são se esqueça de colocar o caminho da OU, onde encontra-se os objetos de computadores do seu AD.

  3. Boa tarde. Quando ou o comando: (Get-ADComputer -SearchBase “OU=Computadores,DC=cetamsede,DC=local” -Filter *).Name |Foreach-Object {Invoke-Command -ComputerName $_ {msg * “Mensagem de teste”}}

    Tenho essa msg de erro: Não é possivel validar o argumento no parametro “ComputerName” . O argumento é nulo ou vazio.

    Alguma ideia doq possa ser?

    Estou usando windows server 2008 R2

  4. Olá, boa tarde, ao tentar executar o comando para todos recebo a seguinte mensagem,

    Get-ADComputer : O distinguishedName fornecido deve pertencer a uma das seguintes partições: ‘DC=sell,DC=local ,
    CN=Configuration,DC=sell,DC=local , CN=Schema,CN=Configuration,DC=sell,DC=local , DC=DomainDnsZones,DC=sell,DC=local ,
    DC=ForestDnsZones,DC=sell,DC=local’.
    No linha:1 caractere:2
    + (Get-ADComputer -SearchBase “OU=Desktops,DC=task,DC=local” -Filter *) …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidArgument: (:) [Get-ADComputer], ArgumentException
    + FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.ArgumentException,Microsoft.ActiveDirectory.Management.Comm
    ands.GetADComputer

    • Boa noite. Muito obrigador por prestigiar o meu trabalho.

      Você deve esta informando o distinguishedName “OU=Desktops,DC=contoso,DC=local” de forma errada para informar a OU aonde contém os objetos computadores do AD.

      (Get-ADComputer -SearchBase “OU=Desktops,DC=contoso,DC=local” -Filter *).Name | Foreach-Object {Invoke-Command -ComputerName $_ {msg * “Feche todos os arquivos abertos. O servidor será desligado em 5 minutos.”}}

  5. Olá Gabriel, parabéns pelo conteúdo!

    Existe alguma maneira prática de enviar uma mensagem programada (por exemplo, de 2 em 2 horas) para todos os PCs da rede?

    Gostaria de enviar um alerta para todos os usuários, conforme abaixo:

    “Está na hora de beber água! Pare por alguns minutos e se hidrate, a seu corpo e a sua saúde agradecem!”

    • Bom dia. Muito obrigado por prestigiar o meu trabalho. Existe sim. Bastar criar um bat no servidor e agendar a tarefa usando o agendador de tarefas do Windows para o horário que deseja executar.

  6. Boa noite Gabriel, tudo bem ? Primeiramente obrigado por partilhar esse conteúdo. Vê se consegue me ajudar por gentileza.

    Estou tendo a seguinte dificuldade: Quanto tiro do comando OU=Computadores e deixo somente o domínio DC=gpmmhmg,DC=local dá certo.

    COMANDO:
    PS C:\Windows\system32> (Get-ADComputer -SearchBase “OU=Computadores,DC=gpmmhmg,DC=local” -Filter *).Name | Foreach-Object
    {Invoke-Command -ComputerName $_ {msg * “Essa e uma mensagem de teste.”}}

    ERRO:

    Get-ADComputer : Directory object not found
    At line:1 char:2
    + (Get-ADComputer -SearchBase “OU=Computers,DC=gpmmhmg,DC=local” -Filte …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : ObjectNotFound: (:) [Get-ADComputer], ADIdentityNotFoundException
    + FullyQualifiedErrorId : ActiveDirectoryCmdlet:Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException,M
    icrosoft.ActiveDirectory.Management.Commands.GetADComputer

    • Boa tarde. Muito obrigado por prestigiar o meu trabalho. Seu erro é um erro clássico que acontece. Bem provável que em seu domínio você esteja armazenando os objetos computadores (Computers) no Contêiner. Lembre-se contêiner e não OU (unidade organizacional) por isto acontece o erro, você mandou procurar em Get-ADComputer -SearchBase “OU=Computadores,DC=gpmmhmg,DC=local” “OU=Computadores”.

      O que eu recomendo, crie uma OU na raiz do seu domínio gpmmhmg.local chamada Estações de trabalho e altere o comando para Get-ADComputer -SearchBase “OU=Estações de trabalho,DC=gpmmhmg,DC=local

      Depois manda o feedback aqui.

      • Fala Gabriel, boa noite! É exatamente isso cara, deu certo. Só fiquei na dúvida porque eu tinha criado a OU, e ela estava dentro de outra OU (Ex: OU Empresas – OU Computadores), ai não funcionou. Quando puxei para raiz como vc disse, funcionou. Obrigado mais uma vez.

          • Boa tarde Gabriel, tranquilo ?
            Me tira uma dúvida por gentileza, o ad aqui está estruturado, exemplo tem o diretório Empresas – Empresa x – Setor ADM – Usuários – Computadores. Ai cada setor tem suas sub OUs Computadores, usuários, grupos, etc. Ai segue tbm para Financeiro – Computadores – MKT – Computadores…etc.
            Quando coloco a OU principal (Ex: Empresas) que está na raiz e que engloba todas essas outras abaixo que incluiu computadores de todos setores, a msg não vai. Funciona apenas se eu tiver uma OU na raiz e colocar todas as contas de computadores nela ?
            Obrigado.

          • Bom dia. Muito obrigado por prestigiar o meu trabalho.

            Agora vamos a sua dúvida. Utilize o atributo distinguishedName para localizar o caminho completo da OU no qual o objeto computadores estão inseridos.

            Exemplo: Se você tem uma OU Computadores dentro da OU Financeiro, que está dentro da OU Setores, que por sua vez está dentro do domínio contoso.local. O caminho seria: OU=Computadores,OU=Financeiro,OU=Setores,DC=contoso,DC=local

            O caminho completo da OU aparece no atributo distinguishedName, em Editor de Atributo. Você pode acessar ele através de Usuários e Computadores do Active Directory, para visualizar está aba necessário ir em Exibir, logo depois clicar em Recursos avançados.

            Após colocar o atributo distinguishedNamem, basta colocar no comando, conforme demostra o exemplo abaixo:

            (Get-ADComputer -SearchBase “OU=Computadores,OU=Financeiro,OU=Setores,DC=contoso,DC=local” -Filter *).Name | Foreach-Object {Invoke-Command -ComputerName $_ {msg * “Feche todos os arquivos abertos. O servidor será desligado em 5 minutos.”}}

  7. Olá bom dia, pode me tirar uma duvida a respeito do AD? gostaria de replicar um comando de exclusao de arquivos temporarios, cache, como conseguiria? qual comando usaria?

  8. Olá amigo tudo bem, conteúdo muito bom. To com uma duvida no comando Get-ADComputer.. na rede em qual trabalho nosso dominio é dr.gov, os computdaores estão na Unidade Organizacionao DR e dentro outra como Computadores. Minha dúvida coloco assim: “(Get-ADComputer -SearchBase “OU=DR,OU=Computadores,DC=dr,DC=gov” -Filter *).Name | Foreach-Object {Invoke-Command -ComputerName $_ {msg r.teixeira “Feche todos os arquivos abertos. O servidor será desligado em 5 minutos.”}} “, caso eu queira mandar pra um user só? E se ao invés de um user especifico eu quisesse mandar pra uma maquina especifica q pode ser usada por várias pessoas como ficaria?

    • Boa tarde. Muito obrigado por prestigiar o meu trabalho. Isto é demostrado também no artigo. Leia o artigo com calma.

      Um outro parâmetro que podemos adicionar um usuário específico, neste exemplo será o carlos.luiz, o comando fica assim:

      (Get-ADComputer -SearchBase “OU=Desktops,DC=contoso,DC=local” -Filter *).Name | Foreach-Object {Invoke-Command -ComputerName $_ {msg carlos.luiz “Feche todos os arquivos abertos. O servidor será desligado em 5 minutos.”}}

  9. Boa tarde.

    Muito obrigado pelo tutorial.

    Algumas máquinas estão com erro WinRm, como solucionar o erro?

    PS C:\Users\Administrador> (Get-ADComputer -SearchBase “OU=Computadores,DC=hvm,DC=local” -Filter *).Name | Foreach-Object {Invoke-Command -ComputerName $_ {msg * “TESTE – TI”}}
    [DESKTOP-EGAS9M4] Falha ao conectar ao servidor remoto DESKTOP-EGAS9M4 com a seguinte mensagem de erro: O WinRM não
    pode concluir a operação. Verifique se o nome do computador especificado é válido, se o computador está acessível
    pela rede e se uma exceção de firewall para o WinRM está habilitada e permite acesso desse computador. Por padrão, a
    exceção de firewall do WinRM para perfis públicos limita o acesso a computadores remotos na mesma sub-rede local. Para
    obter mais informações, consulte o tópico da Ajuda about_Remote_Troubleshooting.
    + CategoryInfo : OpenError: (DESKTOP-EGAS9M4:String) [], PSRemotingTransportException
    + FullyQualifiedErrorId : WinRMOperationTimeout,PSSessionStateBroken
    [HVM-100] Falha ao conectar ao servidor remoto HVM-100 com a seguinte mensagem de erro: O WinRM não pode concluir a
    operação. Verifique se o nome do computador especificado é válido, se o computador está acessível pela rede e se uma
    exceção de firewall para o WinRM está habilitada e permite acesso desse computador. Por padrão, a exceção de firewall
    do WinRM para perfis públicos limita o acesso a computadores remotos na mesma sub-rede local. Para obter mais
    informações, consulte o tópico da Ajuda about_Remote_Troubleshooting.
    + CategoryInfo : OpenError: (HVM-100:String) [], PSRemotingTransportException
    + FullyQualifiedErrorId : WinRMOperationTimeout,PSSessionStateBroken
    [HVM-87] Falha ao conectar ao servidor remoto HVM-87 com a seguinte mensagem de erro: O WinRM não pode concluir a
    operação. Verifique se o nome do computador especificado é válido, se o computador está acessível pela rede e se uma
    exceção de firewall para o WinRM está habilitada e permite acesso desse computador. Por padrão, a exceção de firewall
    do WinRM para perfis públicos limita o acesso a computadores remotos na mesma sub-rede local. Para obter mais
    informações, consulte o tópico da Ajuda about_Remote_Troubleshooting.
    + CategoryInfo : OpenError: (HVM-87:String) [], PSRemotingTransportException
    + FullyQualifiedErrorId : WinRMOperationTimeout,PSSessionStateBroken
    [HVM-134-2] Falha ao conectar ao servidor remoto HVM-134-2 com a seguinte mensagem de erro: O WinRM não pode concluir
    a operação. Verifique se o nome do computador especificado é válido, se o computador está acessível pela rede e se
    uma exceção de firewall para o WinRM está habilitada e permite acesso desse computador. Por padrão, a exceção de
    firewall do WinRM para perfis públicos limita o acesso a computadores remotos na mesma sub-rede local. Para obter mais
    informações, consulte o tópico da Ajuda about_Remote_Troubleshooting.
    + CategoryInfo : OpenError: (HVM-134-2:String) [], PSRemotingTransportException
    + FullyQualifiedErrorId : WinRMOperationTimeout,PSSessionStateBroken

    • Bom dia.

      Muito obrigado por prestigiar o meu trabalho. Parece que o seu firewall estar barrando a comunicação.

      Você verificou os requisitos para utilização?

      Se deseja explanar melhor o meu problema com imagens ou vídeo, entre no mue grupo do Telegram https://t.me/gabrielluizbrasil

      ATENÇÃO: AO ENTRAR NO GRUPO DO TELEGRAM, RESPONDA RÁPIDO AS DUAS PERGUNTAS DE SEGURANÇA OU SERÁ BANIDO PELO ROBÔ.

      #MVPBuzz

  10. Apenas um Adendo o comando só vai funcionar se tiver comunicação com o WINRM habilitado nas máquinas.
    Para habilitar usar o comando (Bem porcamente resumido)” Enable-PSRemoting -Force ” ira habilitar tudo e aceitar tudo, o que pode ser habilitado pela GPO também.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Microsoft MVP
Siga e curta!
Follow by Email
YouTube
YouTube
Set Youtube Channel ID
LinkedIn
LinkedIn
Share
Entre no meu grupo do Telegram
Categorias
Arquivo
Inteligência artificial em seu servidor.