From PowerShell to Python: Notes From The Field

Author: Zachary Loeber Posted In: Cloud, DevOps

Picking up Python when you already know PowerShell isn’t that hard but there are some key differences.

Introduction

If you finally have come to terms with PowerShell and have been itching to delve into Python, this article can be considered a decent starting point. I’m going to cover some high level differences that you would otherwise have to figure out on your own.

Similarities

PowerShell and Python share many common traits. Here are a few that stick out.

Interpreted – For starters, both PowerShell and Python are interpreted languages. That means they are run directly from source code via an interpreter without any intermediate compile/link stages that many other languages have to perform to get running results. This all happens magically through the python or powershell (or pwsh) interpreter. This is likely why they are both so popular for automation; they provide immediate results.

Multiplatform – They both run on multiple platforms. Arguably, Python has historically been more cross-platform than PowerShell. but with PowerShell 6.0 running off of .Net core you can now run PowerShell on mac, Linux, and ARM platforms as well so that gap is closing fast.

Community – Both languages have a large community of passionate users with an ever growing code base of modules and example code to learn from.

Object Oriented – Almost everything in Python and PowerShell is technically an object. That’s pretty cool right?

Differences

I’m purposefully going to slant this section toward those who use PowerShell regularly and are looking to expand their horizons into Python. I consider these “differences” the distilled essence of what one would need to know to quickly come to terms with Python and start being productive with the language. It should be noted that ANY basic programming knowledge above and beyond PowerShell would be a boon in this journey. Also, this is far from a comprehensive list.

Spaces Matter

In PowerShell you could write a 100 line script without ever indenting a single code block (though you would look totally unprofessional if you did). In Python this is simply not possible. If you want to have any kind of code block it requires appropriate indentation. This is in place of curly braces in the PowerShell realm.

function multiply ([int]$x, [int]$y) {
    $x * $y
}

And the same in Python (Pay attention to the colon delimiter indicating a block of code will be starting in the next line):

def multiply(x, y):
    return x * y

There is No Pipeline in Python

PowerShell has a rich set of features that encourage the piping of data from one cmdlet/function to another via ‘the pipeline’. You gain performance benefits by using this feature correctly in PowerShell and it is darn convenient at times. Python doesn’t have any baked in equivalent. That doesn’t make Python any less of a language though. It is just something you will have to not lean on so heavily.

Null = None

In PowerShell you have $null for unassigned variables or objects attributes. This is a non-object type that is used judiciously in PowerShell. Generally if you know that an empty string and null are not the same you are in good shape. In fact, one of my favorite methods for checking for null is using a built in string type method:

$a = $null
$b
if ([string]::isnullorempty($a)) { 'A is empty or null (or unassigned)' }
if ([string]::isnullorempty($b)) { 'B is empty or null (or unassigned)' }

# Or simpler but cannot test $b without throwing errors:
if ($a -eq $null) { 'A is empty or null (or unassigned)' }
if ($b -eq $null) { 'B is empty or null (or unassigned)' }

In Python the equivalent to Null is ‘None’. Sometimes I’ve seen it referenced as Nil as well. Testing for None is pretty easy as well. Though it is more difficult to really test for existence in your scope (there is a good argument to be made that you should refactor your code so one doesn’t even have to worry about checking for existence of variables…):

a = None
a is None
try:
    b
except:
    b = None
b is None

Array = List

PowerShell Example:

$a = @()
$b = 1,2,3,'abc'
$a += 'something'
$c = $a + $b
$c.count
5

Python Example:

a = []
b = [1,2,3,'abc']
a += ['something']
c = a + b
len(c)
5

You will notice I was explicitly using the brackets in Python. This is important as Python also has other constructs you don’t hear about in PowerShell, namely a ‘tuple’ (and a less heard of ‘set’). Tuples are simply immutable lists. You create them by default if you don’t use brackets. If you continue the prior Python example you will see what kind of issues this might cause if you aren’t careful:

# Create a tuple
d = a, b
# This works fine, c is a list
c += ['test1']
# This does not, d is an immutable tuple
d += ['test1']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate tuple (not "list") to tuple

Hash = Dictionary

A key-pair lookup table in PowerShell land is called a ‘hash’. Python has the same thing but calls it a ‘dictionary’

PowerShell Example

$a = @{mykey='myvalue'}
$a['mykey2'] = 'myvalue2'
$a
Name                           Value
----                           -----
mykey2                         myvalue2
mykey                          myvalue

Python Example

a = {'mykey':'myvalue'}
a['mykey2'] = 'myvalue2'
a
{'mykey2': 'myvalue2', 'mykey': 'myvalue'}

Other Differences

Here is a rapid fire list of other differences to be aware of:

  • Python variables are case sensitive, PowerShell’s are not.
  • Python classes and OOP capabilities are phenomenal, PowerShell is sorta getting there.
  • Python has PEP 8 style guidelines which have been around since 2001, PowerShell has this style guideline (which I’ve seen evolve in the last few years).
  • Python rocks with YAML, Powershell rocks with CSV/JSON/XML but not YAML (just a personal opinion here).
  • Python generally falls into two versions 2.7 and 3.6, PowerShell has several versions but 2.0 and 5.0+ are pervasive for Windows, 6.0 for Linux/Mac/Other.
  • Install additional modules or whole programs with the pip command in Python. PowerShell modules and scripts can be installed via the PowerShellGet in PowerShell 5.0 or greater.

Conclusion

Should you learn Python if you already are fluent in PowerShell? Yes, I believe every aspiring DevOps pro should learn them both. This is even more true if you are looking to delve into SecOps where Python and PowerShell seem to dominate the arena of frameworks and tools. There is room in this world for multiple hacker friendly languages (using ‘hacker’ in the traditional and true definition of the word). It is in your best interest as a professional to be able to use multiple tools to get work done.

Note: As I was authoring this article I ran across the following two articles ( 1 and 2 ) which are definitely worth reading and go into further detail how to accomplish different tasks in Python vs. PowerShell.