PowerShell Modules can be Painful

Preamble

Building a PowerShell module should not be too hard. In fact, on the surface it’s pretty simple. Collect a bunch of functions, classes, enumerations, (whatever else you want), bundle them together and provide a wrapper in the form of a PSD1/PSM file. My go-to reading and guidance material for this is PowerShell Scripting in a Month of Lunches. Building a module should be straightforward – and it is – except when you make dumb mistakes. Don’t make my mistakes.

The problem exists when you are writing a bunch of scripts and then completely change the way you want to do the work.

In my current project, I’m writing a series of functions to interact with the Telligent Community’s REST API. It’s by no means egregious, but I started down one path, realized I was heading the wrong way and had to pivot completely.

I’m not a “professional” developer. I don’t do development work for pay. I like PowerShell because it’s easy to comprehend and works pretty much everywhere now. You’ve been warned.

Me, Everyday

Loops and Authentication

My issue was two-fold: the first was all about the way I was looping through results, the second was all about how I wanted to handle authentication, and finally, I found myself creating custom output types for pretty much everything.

Loops (and their omission)

The environment where I’ve been working is small. Terribly small by comparison to most Telligent Communities. And because of that, I was erroneously happy when I pulled data and the result size was under the default PageSize (20 elements). I got complacent and started working on the next function, then the next, then the next.

After I tried to run the same functions against a real environment, I was baffled that I was only getting back 20 elements when I knew there were several hundred, if not thousands of results. What gives?

After being a daft oaf, I went back and read some of the Developer Training and realized I was doing pretty much everything wrong. I went back and had to reconfigure at least 12 previously working functions to run with do { ... } while (<condition>) loops. None of this was terribly difficult, but if I would have thought (and read) about the process beforehand, I could have saved myself some time.

Long story short, try and remember all possible permutations before getting started. Unfortunately, I took that advice and went way too far when it came to authentication.

Authentication (and the many ways of)

The RESTful API authenticates via a token + username combination that is all wrapped up and put into the HTTP header. This is nothing new. Other platforms have been doing this for years and years.

Where did my problem occur? When I decided to write a version of the authentication mechanism that would be universally operable. You have the token and the authentication URL? I’ll support it. How about the stuff saved in a file in your user profile? I’ll support that. What about passing it all as a hash table? Sure! Why not?

This turn what should have been simple code into a mess of various Parameter Set Names to handle each and every one of the permutations. It was only this week that I decided what I really needed to do was simplify.

Output Types (and what not to do)

Each of the calls to the API returns slightly different information types: users, posts, threads, comments, etc. And for each one of these, I needed something now like right now to help me do some work. Normally it was reporting on a specific forum or a thread or something else innocuous. Unfortunately, handing over a bunch of JSON or a hash table of object data isn’t useful for anyone except myself or a programmer.

So, I started looking at ways to make this simpler for other team members. The simplest way is something akin to reformatting the output to a simple, flat (think CSV) style. But there were elements within objects I wanted to expose, so I needed to retrieve them to the “topmost” level. I ended up building at least a dozen $PropertiesToReturn blocks.

This works, but I lose so much relevant data. What I should have done was build a whole bunch of classes and enumerations that automatically format my results. But did I? No. Because I was rushed (either for good reason or of my own accord) to complete this function now.

The lessons learned? Think about everything before you commit to putting anything down in code. Think about how you’re getting the data. Think about how you are presenting the data. Think about how you’ll manipulate the data. In summary, stop and think so you don’t have to re-do as much as I have.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.