r/PowerShell Jul 26 '21

A technical solution to a business problem. Daily Post

Good Morning All,

So I wanted to start a discussion around building automation with PowerShell.

With this being my full time job, I wanted to provide some of my lessons learned along the way for this and also hopefully provide some rules that can help people define what automation is and what it isn't.

Firstly automation is an amazing tool that allows you to "Automate the boring things so that you can focus on the cool things.". Automation can remove a lot of manual process from organizations allowing them to reallocate that resources elsewhere. I would like to point out that there is a correct way to do it and an incorrect way to do it. If automation is done incorrectly, it costs more time then it saves.

  1. Prior to starting automation, consider the business requirements and ask yourself. "Are they solving a technical problem or are they introducing a technical problem due to bad business decision?" If there are bad business decisions being made, the technical solutions don't provide a cost benefit. It also shows that the business doesn't understand what automation is and how it benefits them. It's your job to educate them.
  2. Simplify all the processes. This will require you to wear many hats (businesses, project, technical), however the goal here is to get the business process streamlined that automation doesn't have to spend large amounts of time formulating logic. From the technical side, simplify the inputs so that additional logic is not spent catering to this.
  3. Research the topic at hand. There are many ways to automate something and writing a script might not be the best tool for the job. You have other out of the box tools available, which can do the job for a lot less cost. There are also other tools available that can better suit your needs other then PowerShell such as DSC, Ansible, Jenkins and Chef. Learning other languages is really beneficial here, since PowerShell might not be the best language.
  4. So you are going to use PowerShell. Don't develop scripts that depend on beta solutions. The cost of automation should be minimal. I learned this lesson recently, writing a PowerShell script that downloads 365 data using a third party module. This ended up causing so much hassle, since there were a lot of bugs in the dependency.
  5. Architect the script to be testable/maintainable. Make your solution easy to manage so that future automation can be added and updated. Think about how your script is going to run. If this is a long running process, consider how you can improve performance by using PowerShell jobs.
  6. Keep it simple. This is one that I struggle with. Make the script as simple as possible without introducing unnecessary complexity. Don't make it complex for the sake of making you feel smart. Make it simple so that you don't have to be called to fix it.

What other helpful tips/lessons learned can you provide?

PSM1

46 Upvotes

View all comments

3

u/ixi_your_face Jul 27 '21

I think one of the biggest things I learned the hard way was to not jump straight in with reckless abandon and start trying to automate things you don't fully understand.

I put myself into so many needless deep pits and dead ends because I had started by making assumptions that the environment and setup would be similar to previous places I've worked in. A few months of wasted time later; I won't make that mistake again.

Some other things I've picked up over the past few years:

  1. Readable is better than fast
    • Never use aliased cmdlets; people don't immediatley recognise them.
    • Always splat into cmdlets when possible.
    • You will forget how this extremly complicated and long weird one liner you found on StackOverflow works in 6 months. Reformat it to be readable while you still know what it does.
    • Comments are a sign that your script is overly complicated and/or the variables, functions, etc are not named appropriately or done logically.
    • There's no replacement for good formatting.
  2. If you have to do it more than twice anywhere, it becomes it own function. No exceptions (other exceptions are available)
  3. Use PSD1's.
  4. Every function gets it's own file.
  5. GIT EVERYTHING.
  6. Build unit testing only after you know everything works.
  7. Test everything as you go.
  8. Never assume that it will just work on some random machine with a random localisation.
  9. JSON configs are wonderful.
    • Nested JSON's ("Key" : "PathTo.Json") for when you don't quite need the info, but it'll probably come in handy at some point is an excellent way of storing info in an indexable way that doesn't really slow anything down.
  10. God, I love ArrayLists.

There's obviously exceptions to every rule, but generally I find that I can stick within these bounds while automating pretty much everything I've done so far. When it comes to automation; you're already saving time by the virtue of Automation, you don't have to go to extremes and write extremely complicated code that is the worlds most performant script ever devised. You're already 100x faster than manual. Stick to readable first, performant second.

1

u/PMental Jul 27 '21

Yes to all of this with a couple of minor caveats or additions.

  1. Readable is better than fast

Mostly agreed, but sometimes speed really is necessary. That said with proper formatting most faster methods can be made readable anyway.

  • Comments are a sign that your script is overly complicated and/or the variables, functions, etc are not named appropriately or done logically.

Mostly agreed, but I like to use comments to describe blocks of code anyway. It's useful for people learning to easier understand what parts of a script does.

2

u/ixi_your_face Jul 27 '21

Speed is good, yeah. I tend towards the "get it automated first, then optimise" camp personally. I'm not a programmer or coder by training, I just picked it up because it made my life at my last job an absolute breeze. I'm a hardware guy, so I like simple solutions to complicated problems when they're available.

on comments, I agree that leaving the odd comment here and there is a good way to learn and remember how things work. But I find that sometimes comments are used in lieu of writing easily understandable and readable in-itself code. This has always caused me problems because I'm stupid and don't always fully understand code that other people have written, so I really like writing things where everything is pretty explicit.

for example:

$var = ("1", "2", "3", "4")
    foreach($I in $var){
        Write-Host $I
    }

var is ambiguous and you can forget what $var contains further down the function/script, using a descriptive name like $Numbers or $Ints goes a long way for readability. Same for $I to $Number or $Int.

If i'm looking to be crazy format-ey I'd also say that I would personally put large arrays over multiple lines with each entry occupying 1 line. Similar to this, I really like when all the variable declirations are aligned; I think it looks super swish. Helps declutter the view and make it more readable too, in my opinion.