Em algumas ocasiões, temos a necessidade de construir automações RPA para atender processos que acontecem em VMs (Virtual Machines, ou seja, Máquinas Virtuais) diferentes. Neste artigo, vamos entender melhor o que é conexão RDP e como utilizar a seu favor no momento de acessar sistemas em máquinas virtuais para que seu processo seja automatizado.
O que é conexão RDP?
Conexão RDP, ou Remote Desktop Protocol, que significa Protocolo de Área de Trabalho Remota, trata-se de um protocolo que foi desenvolvido pela Microsoft para controlar remotamente um computador por uma interface gráfica, fornecendo acesso remoto pelo sistema operacional Windows de maneira segura e eficiente.
Como se conectar em uma VM pela conexão RDP?
Para que você possa se conectar a um computador remoto utilizando o protocolo RDP, é necessário saber o endereço IP ou o nome deste computador, o usuário e a senha. Se o processo fosse manual, você precisaria seguir os seguintes passos:
- No computador local, pesquise por “Conexão de Área de Trabalho Remota” no menu Iniciar do Windows e clique no aplicativo sugerido;
- Insira no campo “Computador” o nome do computador ou então seu endereço IP;
- Em seguida, clique em “Conectar” e, quando solicitado, insira as credenciais com nome de usuário e senha para que a autenticação aconteça com sucesso;
- Após a autenticação, você poderá ter acesso normalmente ao computador remoto.
Mas, como vamos construir uma automação RPA para acessar um computador de outro, vamos utilizar o poder da visão computacional para fazer todo esse processo de maneira automatizada.
O que saber antes de construir sua automação RPA
Para que sua automação consiga fazer os processos necessários, é importante garantir que o seu computador local, ou a VM que vai executar o robô para acessar a outra VM onde os sistemas estão, tenha os permissionamentos necessários para executar comandos em powershell, scripts etc.
Também é importante que identifique quais são as tarefas a serem automatizadas e valide todas as credenciais que serão necessárias para acessar as VMs e os sistemas envolvidos. Além disso, considere guardar essas credenciais de maneira segura. No passo a passo, vamos entender como fazer isso pelo BotCity Orquestrador.
Outro cuidado importante será a questão das resoluções da VM. Isto porque vamos utilizar a visão computacional para procurar pelos recortes das telas, visto que todas as etapas serão pela área de trabalho. Então, durante o processo de desenvolvimento, vamos considerar a configuração fixa das resoluções.
Por que utilizar conexão RDP para sua automação?
Essa abordagem pode ser bastante útil em casos nos quais não temos a possibilidade de executar scripts e comandos diretamente no computador alvo.
Além disso, também pode ser um grande apoio para sua automação, caso só exista a possibilidade de acessar o software que será automatizado, através de uma conexão remota.
Exemplo de desenvolvimento
Nossa automação deverá acessar uma máquina virtual por uma conexão RDP do Windows para cadastrar produtos de um arquivo do tipo .json no sistema Fakturama, software desktop gratuito para gerenciamento de produtos e notas fiscais.
Segue o exemplo de arquivo com os produtos chamado payload.json para serem cadastrados:
{ "load": { "customer": "BOTTEST", "products": [ { "item_number": "0000000000001", "name": "PRODUCT DEMO 1", "category": "ELECTRONICS", "gtin": "0000000000123", "supplier_code": "SUPPLIER1", "description": "PRODUCT DEMO 1", "price": "100.00", "cost": "50.00", "allowance": "0.00", "vat": "Free of Tax", "stock": "100" }, { "item_number": "0000000000002", "name": "PRODUCT DEMO 2", "category": "ELECTRONICS", "gtin": "0000000000124", "supplier_code": "SUPPLIER1", "description": "PRODUCT DEMO 2", "price": "94.90", "cost": "47.50", "allowance": "1.90", "vat": "Free of Tax", "stock": "143" } ] } }
Além disso, seguem um modelo de arquitetura para o nosso caso de exemplo com o BotCity Orchestrator, que precisa ser atendido:

Como acessar um computador remoto pela automação
Para desenvolver essa automação, vamos utilizar o framework Python para desktop. Você pode acompanhar os primeiros passos por este tutorial em nossa documentação e também realizar a instalação do plugin do BotCity Studio para Visual Studio Code, caso seja essa a IDE que você utilize.
Seguindo o passo a passo, você terá um projeto com a seguinte estrutura (estamos chamando o robô de BotRDP):
BotRDP
├── bot.py: aqui é onde iremos trabalhar e desenvolver nosso robô.
├── resources: pasta contendo os arquivos auxiliares para o robô.
├── build.bat: script em Batch para gerar o pacote.
├── build.ps1: script em PowerShell para gerar o pacote.
├── build.sh: shell script para gerar o pacote.
├── requirements.txt: arquivo descrevendo todas dependências externas para seu robô.
└── BotRDP.botproj: arquivo utilizado para carregar o projeto no BotStudio, caso não utilize pelo plugin do Visual Studio Code.
Dentro dessa estrutura, vamos adicionar na pasta resources, o arquivo payload.json que contém os produtos a serem cadastrados. Ou, caso prefira, você pode enviar o conteúdo do arquivo como parâmetro para sua automação.
Saiba mais: Documentação de parâmetros da automação
Lendo o arquivo payload.json
# abrindo o arquivo .json with open(r'resources\payload.json') as json_file: json_data = json.load(json_file) # definindo um nome para poder buscar as credenciais de acordo com o nome do cliente customer_label = json_data["load"]["customer"] # definindo um nome para a lista de produtos que consta no arquivo payload.json products = json_data["load"]["products"]
Como adicionar as credenciais no BotCity Orquestrador
Para segurança da sua automação, você pode utilizar a funcionalidade de Credenciais que está disponível no BotCity Orquestrador.
No menu da lateral esquerda do orquestrador, identifique a opção “Credentials” em “Operation Tools”. Clique em “New Credential” e adicione as informações solicitadas:
- Label: adicione o nome da credencial;
- Repository: insira o repositório que poderá ter acesso a essas credenciais;
- Secrets: clique em “Add” para adicionar as informações:
- Key: nome da chave da credencial;
- Value: o valor da credencial.
Você pode adicionar quantas chave/valor forem necessárias.

Em nosso exemplo vamos fazer da seguinte maneira:
- Label: BOTTEST;
- Repository: DEFAULT;
- Secrets:
- Key: remote_ip;
- Key: username;
- Key: password;
- E para cada uma das keys, adicione seus respectivos valores.

No código, você poderá acessar as credenciais da seguinte forma:
remote_ip = maestro.get_credential(customer_label, "remote_ip") username = maestro.get_credential(customer_label, "username") password = maestro.get_credential(customer_label, "password")
Observação: caso você queira executar o robô localmente, para que você consiga se conectar ao Orquestrador e validar que está conseguindo acessar a credencial, você precisa adicionar primeiro esse código para fazer login na ferramenta:
maestro.login( server="adicione o server aqui", login="adicione o login aqui", key="adicione a chave aqui" )
Para saber qual é o login e a key para esse login ser feito com sucesso, você deverá acessar a área chamada “Dev Environment” pelo menu da lateral esquerda do seu orquestrador. Saiba mais em: documentação de Dev Environment.
⚠️Lembre-se de que este trecho de código servirá apenas para executar localmente. Você deve retirar esse código antes de disponibilizar o robô no orquestrador para ser executado automaticamente.
Como criar uma função para conectar na VM por RDP
Para nos conectarmos ao computador remoto, vamos utilizar a biblioteca subprocess do Python, que nos ajudará a executar o powershell, facilitando a abertura da conexão. Entenda como fizemos o código, criando um novo arquivo commands.py e adicionando o seguinte código:
import subprocess def run_start_rdp(remote_ip: str, user: str, password: str): # comando para iniciar a sessão: mstsc start_rdp_command = f''' cmdkey /generic:"{remote_ip}" /user:"{user}" /pass:"{password}" mstsc /v:{remote_ip} /w:1600 /h:900 cmdkey /delete:{remote_ip}''' # executando o powershell com o comando criado acima subprocess.run(["powershell", start_rdp_command])
No comando, os itens /w e /h são para configurar de maneira fixa a resolução da tela do computador remoto que você vai acessar. Fixar a resolução e posicionamento, como faremos em outras partes do código também, ajudará a garantir a execução da automação com sucesso.
⚠️Observe que nas primeiras execuções, podem ser que apareçam caixas de diálogo para algumas confirmações de certificado ou ainda de login e senha para a conexão RDP. Você pode utilizar a visão computacional para interagir com essas caixas de diálogo ou ainda deixar um check na opção “não aparecer novamente”.
Após isso, basta fazer a importação deste arquivo no seu código principal:
from commands import run_start_rdp
E, depois, adicionar a chamada da função:
# já possuirá os parâmetros por ter buscado a informação nas credenciais do Orquestrador run_start_rdp(remote_ip, username, password)
Como deixar a tela da VM em foco para a execução da automação
Vamos adicionar o seguinte trecho de código:
bot.connect_to_app(best_match="Conexão de Área de Trabalho Remota", timeout=30000) main_rdp_window = bot.app.top_window() main_rdp_window.set_focus() bot.wait(3000)
Pode ser uma boa prática em algumas etapas do código, você utilizar a função wait() do framework da BotCity. Lembre-se de que você estará executando algo em uma máquina virtual, que pode ser normalmente mais lenta que um computador local.
Fakturama
Para abrir o Fakturama, vamos fazer uma pesquisa na barra do menu Iniciar do Windows da máquina virtual. Mas antes dessa pesquisa ser feita, vamos limitar a área em que ela deve acontecer, para que assim a visão computacional não confunda o recorte feito com o seu computador local ou com a VM incorreta.
Então antes de abrir, vamos garantir a posição da janela:
main_rdp_window = bot.app.top_window() window_rect = main_rdp_window.client_rect() x, y, width, height = window_rect.left, window_rect.top, window_rect.width() + 50, window_rect.height() + 50
Neste código, x e y são a posição da tela e width e height serão a garantia da resolução da tela que, no início, para nos conectarmos ao computador remoto, deixamos configurado de maneira fixa como 1600 x 900. Ou seja, a consulta vai considerar apenas dentro dessa tela e não fora dela, evitando problemas de confundir em qual tela deverá encontrar o que será pedido.
Mapeando a barra de pesquisa do menu iniciar da VM por visão computacional
Podemos seguir os próximos passos utilizando o plugin do BotStudio para Visual Studio Code. Se quiser fazer dessa forma, lembre-se de que deve seguir o passo a passo da instalação e configuração da documentação do plugin do Studio.
Lembrando que, caso vá utilizar o Fakturama para seguir o exemplo, ele deverá ser instalado seguindo as instruções da documentação do Fakturama.
No Visual Studio Code, deixe o cursor no local onde o novo código deverá ser inserido automaticamente. Clique no plugin no menu lateral esquerdo e você terá a janela disponível para tirar os prints dos recortes que deseja mapear para a sua automação.
Neste momento, vamos mapear o ícone de pesquisa para digitarmos “Faktumara.exe” no menu Iniciar do Windows da máquina virtual.
Deixe a tela do BotCity Studio em cima da tela que vamos tirar o print. Clique no ícone que consta no menu da lateral esquerda identificado como “Screenshot” com o símbolo de uma máquina fotográfica. Isso fará com que a tela seja printada.

Após isso, clique uma vez no ícone de pesquisa do menu iniciar e, em seguida, clique e arraste o mouse, selecionando o ícone correspondente. Caso você erre o clique, basta pressionar a tecla “ESC” no seu teclado e clicar novamente onde deseja selecionar.
Ao selecionar o ícone de pesquisa, adicione um nome para ele e a ação de “Click”, deixando o modo “Image” selecionado e clicando em “Submit”.

Ao retornar para o código, você observará que um código parecido com o trecho abaixo foi adicionado em seu projeto:
if not bot.find("search_icon", matching=0.97, waiting_time=10000): not_found("search_icon") bot.click()
Todos os recortes que você mapear ficarão guardados dentro da pasta resources do seu projeto. Sem esses recortes, o código não conseguirá encontrar os itens na tela que você precisará ter para que a automação seja executada corretamente.
Neste código, na função find(), vamos adicionar como parâmetros, a posição e a resolução configurada anteriormente. Então o código ficará assim:
if not bot.find("search_icon", matching=0.97, waiting_time=10000, x=x, y=y, width=width, height=height): not_found("search_icon") bot.click()
Após isso, o robô deverá escrever “fakturama.exe” na barra de pesquisa, em seguida dar “enter” para abrir o sistema. E, para garantir que dará tempo do software abrir antes dos próximos passos, adicionaremos um tempo.
bot.type_keys("fakturama.exe") bot.enter() bot.wait(4000)
Outra forma de adicionar o nome na pesquisa é utilizar outra função, de acordo com as orientações da documentação do paste().
Cadastro de produtos no Fakturama
Para garantir que estamos com a tela do Fakturama em destaque, podemos mapear o nome do sistema e considerar um tempo de espera maior, assim ele só prosseguirá se encontrar o Fakturama em destaque na tela.
Seguindo o mesmo procedimento do mapeamento do recorte do ícone de pesquisa, vamos mapear o nome do Fakturama. O código poderá ficar parecido com o abaixo:
if not bot.find("label_fakturama", matching=0.97, waiting_time=60000): not_found("label_fakturama")
Como temos uma lista de produtos dentro do arquivo payload.json na pasta resources, vamos utilizar o for para iterar dentro dessa lista e cadastrar todos os produtos. O código poderá ficar parecido com o que consta abaixo:
for product in products: # precisamos primeiro clicar em “New Product” if not bot.find("button_new_product", matching=0.97, waiting_time=10000): not_found("button_new_product") bot.click() # o próximo passo é adicionar os valores nos campos if not bot.find("label_item_number", matching=0.97, waiting_time=10000): not_found("label_item_number") bot.click_relative(84, 4) bot.type_keys(product["item_number"]) print(product["item_number"]) # você pode utilizar “tab()” ou ainda mapear cada um dos campos por visão computacional bot.tab() bot.type_keys(product["name"]) bot.tab() bot.type_keys(product["category"]) bot.tab() bot.type_keys(product["gtin"]) bot.tab() bot.type_keys(product["supplier_code"]) bot.tab() bot.type_keys(product["description"]) bot.tab() # como já fica com um número 0 em alguns campos, podemos utilizar control_a() para selecionar todo o conteúdo e digitar em cima o valor correto bot.control_a() bot.type_keys(product["price"]) bot.tab() bot.control_a() bot.type_keys(product["cost"]) bot.tab() bot.control_a() bot.type_keys(product["allowance"]) # o campo vat não precisará ser alterado, então vamos apenas utilizar tab() para ir para o próximo bot.tab() bot.tab() bot.control_a() bot.type_keys(product["stock"])
Mesmo após preencher os dados do produto, podemos salvar o que foi criado e fechar a aba do produto. Para isso, mapeamos o botão save, ainda dentro do for:
if not bot.find("button_save", matching=0.97, waiting_time=10000): not_found("button_save") bot.click()
E também dentro do for, mapeamos o x da aba do produto para poder clicar nela para fechá-la:
if not bot.find("button_close_product", matching=0.97, waiting_time=10000): not_found("button_close_product") bot.click()
Como finalizar o Fakturama e a conexão RDP
Como boa prática, podemos sempre fechar os sistemas e a conexão utilizadas na automação do processo. Uma das formas de se fazer isso, é com o seguinte código (já fora do for para que fechem apenas após o término do cadastramento dos produtos):
# como a tela do Fakturama está em destaque, podemos apenas fechar pelo comando bot.alt_f4() # fechando a conexão RDP main_rdp_window = bot.app.top_window() main_rdp_window.close()
Como vamos executar nossa automação pelo orquestrador, precisamos adicionar a finalização da tarefa. Aqui você também pode mapear outros tipos de situações como erros e status diferentes, de acordo com o que acontecer com a automação. Veja o exemplo abaixo e explore outras oportunidades em nossa documentação sobre as tarefas.
maestro.finish_task( task_id=execution.task_id, status=AutomationTaskFinishStatus.SUCCESS, message="Task Finished OK." )
Código completo
Entenda como poderá ficar o código principal completo:
from commands import run_start_rdp from botcity.core import DesktopBot from botcity.maestro import * # Disable errors if we are not connected to Maestro BotMaestroSDK.RAISE_NOT_CONNECTED = False def main(): maestro = BotMaestroSDK.from_sys_args() execution = maestro.get_execution() print(f"Task ID is: {execution.task_id}") print(f"Task Parameters are: {execution.parameters}") bot = DesktopBot() with open(r'botPython\resources\payload.json') as json_file: json_data = json.load(json_file) customer_label = json_data["load"]["customer"] products = json_data["load"]["products"] remote_ip = maestro.get_credential(customer_label, "remote_ip") username = maestro.get_credential(customer_label, "username") password = maestro.get_credential(customer_label, "password") run_start_rdp(remote_ip, username, password) bot.connect_to_app(best_match="Conexão de Área de Trabalho Remota", timeout=30000) main_rdp_window = bot.app.top_window() main_rdp_window.set_focus() bot.wait(3000) main_rdp_window = bot.app.top_window() window_rect = main_rdp_window.client_rect() x, y, width, height = window_rect.left, window_rect.top, window_rect.width() + 50, window_rect.height() + 50 if not bot.find("search_icon", matching=0.97, waiting_time=10000, x=x, y=y, width=width, height=height): not_found("search_icon") bot.click() bot.type_keys("fakturama.exe") bot.enter() bot.wait(4000) if not bot.find("label_fakturama", matching=0.97, waiting_time=60000): not_found("label_fakturama") for product in products: if not bot.find("button_new_product", matching=0.97, waiting_time=10000): not_found("button_new_product") bot.click() if not bot.find("label_item_number", matching=0.97, waiting_time=10000): not_found("label_item_number") bot.click_relative(84, 4) bot.type_keys(product["item_number"]) bot.tab() bot.type_keys(product["name"]) bot.tab() bot.type_keys(product["category"]) bot.tab() bot.type_keys(product["gtin"]) bot.tab() bot.type_keys(product["supplier_code"]) bot.tab() bot.type_keys(product["description"]) bot.tab() bot.control_a() bot.type_keys(product["price"]) bot.tab() bot.control_a() bot.type_keys(product["cost"]) bot.tab() bot.control_a() bot.type_keys(product["allowance"]) bot.tab() bot.tab() bot.control_a() bot.type_keys(product["stock"]) if not bot.find("button_save", matching=0.97, waiting_time=10000): not_found("button_save") bot.click() if not bot.find("button_close_product", matching=0.97, waiting_time=10000): not_found("button_close_product") bot.click() bot.alt_f4() main_rdp_window = bot.app.top_window() main_rdp_window.close() maestro.finish_task( task_id=execution.task_id, status=AutomationTaskFinishStatus.SUCCESS, message="Task Finished OK." ) def not_found(label): print(f"Element not found: {label}") if __name__ == '__main__': main()
E aqui o código do arquivo commands.py:
import subprocess def run_start_rdp(remote_ip: str, user: str, password: str): start_rdp_command = f''' cmdkey /generic:"{remote_ip}" /user:"{user}" /pass:"{password}" mstsc /v:{remote_ip} /w:1600 /h:900 cmdkey /delete:{remote_ip}''' subprocess.run(["powershell", start_rdp_command])
Deploy e execução da tarefa
Antes de prosseguir para essa etapa, vale sempre testar o que você desenvolveu, localmente. E lembre-se de, antes do deploy no orquestrador, deletar o trecho de código de login.
Para fazer o deploy, você pode seguir as orientações neste artigo sobre como criar e executar tarefas da sua automação no BotCity Orquestrador ou ainda acompanhar o passo a passo em nossa documentação sobre deploy.
Para executar a sua tarefa, você deve ter o BotCity SDK instalado e abrir, através dele, o BotCity Runner no computador que executará a automação e que precisa abrir a VM para executar o sistema que consta nela.
O que achou da possibilidade de automatizar processos em VMs por conexão RDP?
Para ir mais a fundo neste assunto, te convidamos a participar da nossa comunidade global de RPA, é só entrar no nosso Slack ou ainda entrar em contato pelo nosso fórum. Qualquer dúvida, só chamar a gente! E não esqueça de criar a sua conta gratuita para testar as funcionalidades que estamos explorando em nossos conteúdos. Ao criar suas automações para aprender como utilizar a ferramenta, lembre-se de compartilhar com a comunidade pelo Repositório de Bots.