PowerShell Great Debate: Script or Function?

One of the most frequent comments in The Scripting Games this year was along the lines of, "you should have submitted this as a function, not a script." Of course, the second-most frequent comment was something like, "you shouldn't have submitted this as a function."

Let's be clear: if an assignment explicitly asks for a function, you should write one. What we're debating are the pros and cons of a single tool being written one way or another. Read that again: a single tool. If you're writing a library of tools, it's obvious that writing them as functions for inclusion in a single file (like a script module) is beneficial.

Some argue that any tool is potentially going to be included in a function... so why not write it that way to begin with? Others argue that functions are a smidge harder to test, so why not just write a script?

This is a debate I don't personally have a strong stake in. I mean, we're literally talking about a single keyword. Take any script, add the function keyword, a function name, and a couple of curly brackets, and you've got a function. This really shouldn't be a criteria when you're looking at a contest entry... or even when you're looking at something a colleague offered to you.

Or should it?

[boilerplate greatdebate]

About the Author

Don Jones

Don Jones is a Windows PowerShell MVP, author of several Windows PowerShell books (and other IT books), Co-founder and President/CEO of PowerShell.org, PowerShell columnist for Microsoft TechNet Magazine, PowerShell educator, and designer/author of several Windows PowerShell courses (including Microsoft's). Power to the shell!

6 Comments

  1. My approach is to draw out the flow of a script and consider what parts of it I will want to re-use. If I am pushed for time, I write the whole thing as a script with the intention of moving the parts that should be a function later. if I have time, I write the re-useable bits as functions straight away then use those in the script. I think it comes down to recognise what is of value to you and others outside of the task you're doing and make decisions based on that.

    I agree it's a single keyword, but a function should do a single thing and do it well, so turning a script into a function is not really something that lines up with Best Practices.

  2. I tend to approach thus based on what the tool is doing. If it is more of a 1-time king of thing or only has ine use case I will write a script. Otherwise I try to write reusable functions wherever possible.

  3. Personally, I rarely write scripts. I generally write several functions relating to the same subject area and put them in a module. When you have a library of thousands of functions the idea of having a single file for each makes me cringe.

  4. I follow Mike Shepard's logic also. However, I tend to limit the functions/module; to things that I either us as a series, or tend to use on a regular basis as a system admin tools. If they are things that their need is much rarer, then I tend to save them as a script. There are also a few things that are scheduled tasks, which are saved as scripts. However, there is a need to run them outside of this schedule. There, is where sometimes I leave them as a script, so I can run it manually, but there are some instances where I also include the same process as a function in my module for daily uses. It comes down to had saves me a few clicks and key strokes for my daily routine.

  5. I think it really depends on what you trying to accomplish, besides - functions are scripts, and for me scripts are a bunch of functions. If I have a project that calls for a script (generally something complicated or needs a workflow or multiple tasks), then I take the traditional approach of breaking down the entire project into smaller tasks. These tasks become functions in my script. The main body of my script will set variables and call these functions for the most part.

    For day-to-day admin I write tons of functions. I even write one-line functions just to help me remember some complicated aspect of the line (like a complex regex in a match statement), or to help me shorten another one-liner. Sometimes I'll even write a one-liner function at the command prompt which I'll never use again if it will help get through a task.

    I throw related functions in script modules (I have a module for reading and writing to the registry; a module for reporting and creating records in DNS; a module for network centric tools like ping, telnet-like functions; a module that has a bunch of functions that I wrote that wrap perl code into functions to manage some 'nix appliances; etc; etc; etc...). For unrelated functions I generally throw them in my powershell profile.

    I don't have any particular rules. Multi-task projects will end up being a series of functions in a script, and single task projects will end up being a function for the most part, but even then sometimes I'll wrap multiple tasks into a single function and I'll write a script to accomplish a single task. It all depends on what I need at the moment.

    I use functions often, I don't write many advanced functions for my personal tools, so they are really easy to throw together. I wrap powershell functions around DOS commands like dig.exe, ping.exe, etc. PowerShell is so flexible. I don't want to jump into a cmd window or a GUI, and then back to PowerShell. I want to do everything in PowerShell. I rarely use a GUI anymore and I'm managing AD, Exchange, SQL, MySQL, 'nix appliances, Windows Servers, Unix servers, VMWare, etc. I would say that 90% of all my work I do through PowerShell ISE. I feel the reason I've attained this level of functionality (no pun intended) is because I use functions so liberally.

    PowerShell purists would probably hate me, but I find my methodology highly effective for me. What's great is that PowerShell lets you be a purist or a hack or anything inbetween. Just like everyone learns differently, everyone is highly effective differently.

    I don't think that you should be graded lower or higher in a scripting game if the use of a function/'or not' is not specified in the rules. I think it should be left up to the individual writing the script to determine where best to use functions or not.

    As a final thought - PowerShell work that I share with others I generally try to follow best practices so that they can read and understand my work better, so it is good to know how to be a purist in case you need it.

  6. There's no firm line here, but I tend to write functions when it will act more or less like a cmdlet: One command, one task (with the Verb-Noun naming convention). I write scripts when something more complex is called for. (ie, "Connect to each server on a list, query them for current status information, save it in a database, compare the current status to the last known status, send out alerts based on changes in condition, etc").