How To Connect To Your Raspberry Pi’s Graphical Desktop From Windows 10

Here I’m going to show you how to easily connect to your Raspberry Pi over the network from your Windows 10 machine.[1]

This is going to be accomplished with the Remote Desktop Protocol (RDP).

This will allow you to quickly and conveniently access the Raspberry Pi’s graphical desktop without having to disconnect and move any of your cables (USB, HDMI, etc.) around.

A real pain in the butt!

Then you can easily experiment and test all of the open source software that the Raspberry Pi platform has to offer:

Here are a few quick examples:

1.) LibreOffice

Opensource Alternative to Microsoft Office

2.) Programming In Python For Beginners

Any Linux platform is going to come with amazing programming IDEs for dozens of popular programming languages: C, C++, Ruby, Python, Perl, you name it!

Raspberry Pi has one in particular for Python beginners.

Thonny Python IDE (to name just one of dozens)

3.) Raspberry Pi Documentation

If you want to go down the Raspberry Pi and/or Debian rabbit hole, you can access all of their References, Guides, and Help files:

Raspberry Pi OS Commands

To get this RDP solution implemented, we will need to:

  1. Install the latest Raspberry Pi OS updates (as a Best Practice)
  2. Install the open source version of RDP onto your Raspberry Pi: Xrdp
sudo apt-get update #update list of available updates
sudo apt-get upgrade #actually installs latest software versions
sudo apt-get install xrdp #installs XRDP onto Raspberry Pi

“RDP” to your Raspberry Pi

From your Windows 10 machine, type mstsc into your search bar and select Remote Desktop Connection

Enter your Raspberry Pi’s IP Address and click Connect

Click Yes if you see the following warning:

Enter the username and password of a valid Raspberry Pi account.

The one you use to Putty with should work.

Then you will be presented with the Raspberry Pi’s graphical desktop:


[1]Curated from the following website:

How to Enable Linux on Windows 10 (for FREE)

If your goal is to learn Linux and all you have is a Windows 10 machine, this post is for you.

You have to enable a feature called Windows Subsystem for Linux (WSL).

As of writing this article, there is the new and improved WSL 2, but I will only cover WSL 1 in this post.

WSL 1 is simpler to enable, supported on more Windows 10 versions, and is perfect for getting you started with Linux ASAP.

Exciting stuff!

Enable WSL 1 on Windows 10

First…enable WSL

Install Ubuntu for WSL

Microsoft’s WSL Store:

Then…get a WSL image from Microsoft’s Store

BASH Script On Raspberry Pi To Show Filehandles

Solved an interesting problem on Unix recently that I automated with the shell; which I will demonstrate on Raspberry Pi


I performed a logrotate on a log file which performed the following transformation:

service.log => service.log.1

which is pretty straight forward, but here was the problem:

After logrotate did its thing, logs were being written to the archived log file service.log.1 and NOT service.log.

This of course defeats to whole purpose of logrotate, so to begin troubleshooting, I needed to answer this question:

What process (or processes) are keeping a handle on that file being logrotated?


So my first step was to figure out what command I could start with to answer my question.

After a quick google search and testing, I found fuser to be a great spring board.

I began my testing by using the common binary file /usr/sbin/sshd:

root@raspberrypi:~# fuser /usr/sbin/sshd
/usr/sbin/sshd: 406e 776e 846e

Now, according to man 1 fuser, it:

outputs only the PIDs to stdout, everything else is sent to stderr.

Hence, the following will clean up the original output a bit:

root@raspberrypi:~# fuser /usr/sbin/sshd 2> /dev/null
406 776 846root@raspberrypi:~#

(No newline is printed at the end of the output so the prompt was returned back on the same line.)

Now, if we pipe the output to xargs, it will work and give use the information we want. But not in most user-friendly format:

root@raspberrypi:~# fuser /usr/sbin/sshd 2> /dev/null | xargs -n1 ps -p
406 ? 00:00:00 sshd
776 ? 00:00:00 sshd
846 ? 00:00:00 sshd

Not too pretty.

Reason being, it ran a ps -p on EACH PID.

Instead, we want to run a single ps -p on ALL PIDs at once:

Here’s a way to run ps -p on ALL PIDS at once (-f added to ps command):

root@raspberrypi:~# ps -p $(fuser /usr/sbin/sshd 2> /dev/null | tr -s ' ' | sed -e 's/ /,/g' -e 's/^,//') -f
root 406 1 0 22:30 ? 00:00:00 /usr/sbin/sshd -D
root 776 406 0 22:31 ? 00:00:00 sshd: pi [priv]
pi 846 776 0 22:31 ? 00:00:00 sshd: pi@pts/0

Let’s pause here and make a couple of quick observations:

  • The end result is getting more useful
  • But getting there (the code) is starting to outgrow the shell
  • And, its not easy to re-run this code on ANY filename



If we “parameterize” the filename AND make it a script, the end result will look something like this:

root@raspberrypi:~/Documents# sh ./ /usr/sbin/sshd

Here is the source code for ./


echo "******************************************"
echo "*"
echo -n "* Parameter passed in: "
echo $1
echo "*"
echo "******************************************"

export MYFILE=$1

ps -p $(fuser $MYFILE 2> /dev/null  | tr -s ' ' | sed -e 's/ /,/g' -e 's/^,//') -f

Now we can fuser ANY file we want to investigate (30 second demo below):

sh ./ <filename>

Quickly Create An Ansible Task (Part 1)

Ansible is a great, agentless, automation tool any linux SYSADMIN needs to learn and implement NOW!

Especially if you have at least 1/2 a dozen or more linux boxes.

In this post, I’m assuming you already have Ansible installed and configured (ansible.cfg).

This not a introduction to Ansible, this is specifically for current Ansible users.

We’re going to take the bash command

apt-get install nano


And convert it to an Ansible command (there’s actually 3 different kindz!)


Every Ansible task has a syntax (duh! I know).

But BEFORE we us it, lettuce understand it and visualize it FIRST!!

In our mind’s-eye and with pencil and paper..all one-in-the-same IMHO.

Below is my own visualization of any Ansible command.

This representation is totally arbitrary and is just how I “see it”:



Now, it just so happens that Ansible has a module specifically for ‘apt-get’ commands

If we take what Ansible provides, and again, visualize it, we get something like this:



Remember, we have not written any Ansible code yet. We are still visualizing and brainstorming. Which is probably the most important part of this entire process anyway.

Next, we will select only that parameters and values we needs for our particular purpose.




SUMMARY (So far..)

We took our original bash command:

apt-get install nano

and visualized it according to Ansible’s module page and got:


Now that we have this visualization, the rest of our mission becomes 1000x easier.

We will take our visualization and transform it into valid Ansible code in our next post.

And because we did most of the cognitive heavy-lifting upfront: brainstorming!

The rest of our work, writing actual Ansible syntax, becomes a lot easier.


Exposing Python’s Module Search Path!

I recently bought a Raspberry Pi and started getting my hands dirty with Python (again).

The project I copied was very simple and all it did was make an LED blink.

But one line from the program puzzled me:

import RPi.GPIO as GPIO

So naturally, once I got confused, I started to get curious…the programmer in me asked:

  • What is that line actually doing (beside obviously importing a Python module)?
  • What does the code from that module actually look like?
  • Which directories did Python actually search to find the module?

Knowing this will allow me to dig a little deeper with programming, Python, and Raspberry Pi.

Especially when I start developing my own projects from scratch to build my multi-million dollar solution 🤑 But I digress.


Go a head and copy the following code into


import sys

for p in sys.path:
print p

Then call it from your command line:

root@raspberrypi:~# python

The above output shows us every single directory Python searched when it hit the line:

import RPi.GPIO as GPIO


We can take this a step further and see every Python module we have available to us:

root@raspberrypi:~# python | xargs -n1 -I {} find {} -name "*.py"

Now, we can search for the module I was curious about in the beginning:

root@raspberrypi:~# python | xargs -n1 -I {} find {} -name "*.py" | grep RPi.GPIO
find: ‘/usr/lib/python2.7/lib-old’: No such file or directory

Not to mention, we have a pretty good troubleshooting technique as well.