How to run commands in Windows and Linux Servers using Python

Marcelo Schirbel Gomes
4 min readSep 12, 2018

Hi everyone! How are you? I hope you are all doing fine.

In this article I’m going to explain how you can connect into remote computers using Python.

I’m well aware that there are multiple tools which are able to perform this task, such as Ansible, Chef, Rundeck, and others. But if you want something simpler or maybe you want to get your hand dirty, let’s see the code!

I tested everything with Python 3.6.5 — which you can get here

After you installed it, make sure its on you Path.

Now you are going to install some libraries, in order to do that you may open a terminal and type:

python -m pip install --upgrade pip
pip install jupyter-notebook
pip install paramiko
pip install pypsexec

You can see I installed Jupyter-Notebook, and there is a good reason behind that, which I am going to explain later on this article.

Paramiko and PyPsExec are the libraries responsible for running your commands. We will get into that later.

Now, open a terminal and go the directory that you will save you script.

Take note that, we are going to make a Jupyter-Notebook file, which extension is .ipynb

Once you get to your directory, type:

jupyter-notebook

This will pop-up your default browser on http://localhost:8888/home

This is the default URL for Jupyter-Notebook. If you never used it, you will thank me later. It is awesome.

Now we will jump into the code.

First of all, import all libraries.

On a selected cell in the notebook:

import pypsexec.client import Client
import os
import time
import sys
import paramiko

You can hit Ctrl+Enter, this will run the selected cell. Or you can use Alt+Enter, which will do the same thing but will add another cell below the selected one.

Just to be safe, you can do a little test to see if the Python version is correct:

!(sys.executable} --version

The output will be your Python version. Nice isn’t it?

To make you life easier, you should declare a variable for

  • the remote host
  • domain and username
  • password
host = 'the admin/customer IP'
user = 'DOMAIN\username'
pass = 'password'

We will start with the Windows connection. We will use the PyPsExec library, which can be found here.

Now, we are going to open a client, so:

c = Client(host, username=user, password=pass, encrypt=False)

This will create a client with your user and your password to the remote host though port 445, which is the default port used by this library.

If you want another port, you can pass it:

c = Client(host, username=username, password=password, encrypt=False, port=139)

3389 is the default port for RDP. But why the default port is 445? Because it is the SMB port.

SMB stands for ‘Server Message Blocks’ is a protocol that is used for providing shared acess to files and pipes that operate on the OS Application layer.

And I set the encrypt to False because I bumped into a problem when I was trying to connect to a Windows Server 2008 and 2012.

Now that the client is set, just connect it to the server:

c.connect()

In order to run the commands, you can do a try and finally. Like this:

try:
c.create_service()
stdout = c.run_executable("cmd.exe", arguments="iisreset")
finally:
c.cleanup()
c.remove_service()
c.disconnect()

This is a simple example. In my job i had to restart IIS remotely, that is why I left the command there. But it can be anything!

I believe that the code is pretty straightforward, but if you had any doubt, send me a message!

So, you have done your job. But still…where is the output?

To get a nice, pretty looking view of it:

output = []
output = stdout[0].decode("utf-8")
print(output.split("\r\n")[1:3]

And there you go!

For the Linux part, I found this one trickier than the Windows one.

That is because you cannot run sudo commands with SSH. Unless you allow it in a OS level, but let’s be honest, sometimes you can assure that this will be possible. So…

My way around it was:

Use the Paramiko’s invoke shell.

Open a client to SSH and add unknown hosts.

ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

Now connect to the remote host:

ssh.connect(hostname=host, username=user, password=pass)

Once you are connected, invoke the shell:

shell = ssh.invoke_shell()

Now you are able to send even sudo commands to the host.

shell.send(command + "\n")

This will open a shell interactively, if the server allows it. Most of them does. With that, you will be able to run sudo commands.

If you want to just get a command’s output, you may want to try this:

ssh.exec_command('hostname')

Whenever you run a command, you also want to see the output, am I right?

It can be done like this:

stdin, stdout, stderr = ssh.exec_command('date')
output = []
for i in range(0,6):
output.append(stdout.readlines(i))
print(output)

Once you’d done everything you needed, do not forget to close you connection

ssh.close()

Well, I believe that is it!

If you have any questions, send me a message on my Linkedin

See you all soon!

--

--

Marcelo Schirbel Gomes

This is just a bit of my life. Writing another line everyday!