PowerShell How-To

Treat Your Scripts Like Cattle

Standardization will ensure that your code works today, tomorrow and down the road.

There's been a saying going around the DevOps watercooler that says "Treat your servers like cattle, not pets."  The premise behind this statement has to do with standardizing server configurations to the point at which they are all the same. They are simply treated like an unnamed object in a big server resource pool called on when needed and discarded when not. If IT needs more I/O for a peak time of usage, they would simply bring up a few more server nodes to handle the load and remove them just as quickly.

They are "cattle" in a sense that they require no specific care and feeding. They are simply thrown a bunch of "food" and they all just figure out how much they need. They are just objects that do our bidding which we have no specific work attached to and are identical to the "cow" beside them.  It's a great concept for referring to server configurations but can also be applied to scripts as well.

As with server configurations, scripts should be built with standardization in mind from the moment you type the first character.  Well-written scripts are those that accomplish what they were written to do not only today but tomorrow and the next day as well. These scripts are written in a generic fashion so that they are portable. These scripts can be written for Active Directory, for example, in one organization and just as easily be run in another Active Directory environment. The differences are accounted for in the parameters to the script; not in the actual code itself.

For example, let's say I have a tiny script that pulls computer names from a text file and updates a field in Active Directory.  Quite a common task that could be used across a multitude of different organizations.  Here's one way to treat this script like a snowflake.

$Servers = Get-Content -Path C:\Computers.txt
foreach ($Server in $Servers) {
Set-AdComputer -Identity $Server -Location 'Data Center 1'

This script will be called Update-ServerLocations.ps1 and will be called without any parameters. At first glance it may seem like nothing is wrong with this and it's true. It will work in your environment today. But, what happens if I take this out and try to use it tomorrow or in another environment?  We'll have problems.  First, my text file might not be called Computers.txt and might not be located in the root of the C drive.  Also, the location I'm assigning to each computer account isn't "Data Center 1."  Additionally, maybe I like your script but I need to update a different attribute all together?  It will fail and need reworked.

Let's now build this like cattle to show the difference.

param ($FilePath,$Attribute)
$Servers = Get-Content -Path $FilePath
foreach ($Server in $Servers) {
Set-AdComputer -Identity $Server -Location $Attribute

This script will be called Update-ServerAttributes.ps1 and will be called by using the $FilePath and $Attribute parameters.

.\Update-ServerAttributes.ps1 -FilePath  C:\SomeDirectory\Servers.txt -Attribute 'OperatingSystem'

In this example, I was easily able to use a different file path as well as a different attribute. You'll notice that I didn't have to change anything with the script itself if I wanted to use my old text file path and attribute.  Treating your scripts like cattle standardizes them and move all the specificity up to the parameters so it can be used anywhere!


About the Author

Adam Bertram is an independent consultant, technical writer, trainer and presenter. Adam specializes in consulting and evangelizing all things IT automation mainly focused around Windows PowerShell. Adam is a Microsoft Windows PowerShell MVP, 2015 powershell.org PowerShell hero and has numerous Microsoft IT pro certifications. He is a writer, trainer and presenter and authors IT pro course content for Pluralsight. He is also a regular contributor to numerous print and online publications and presents at various user groups and conferences. You can find Adam at adamtheautomator.com or on Twitter at @adbertram.

comments powered by Disqus

SharePoint Watch

Sign up for our newsletter.

I agree to this site's Privacy Policy.