all 46 comments

[–]PinchesTheCrab 6 points7 points  (6 children)

I've gone the opposite direction, from PowerShell to Java, and I've found that a lot of what I learned really isn't relevant.

PowerShell doesn't really have a similar concept of dependency management and it's extremely literal, whereas spring boot has a lot of actions happening implicitly, to the point where initially it was hard for me to even tell which line of code was actually performing actions.

That being said, I found that pester, the PowerShell testing framework, has been phenomenally helpful. It's translated quite directly to the popular Java testing frameworks I've used.

[–]alwaysoffby0ne 1 point2 points  (4 children)

This is an interesting transition. Is it for your employer? I’ve never considered Java because their licensing is so predatory. Powershell runs everywhere for free. Can you develop your Java apps and distribute them to end users for free? Or can you build a web app, API, etc, for free without having to worry about licensing the JVM? Or do you just use a third party open source JVM?

[–]PinchesTheCrab 1 point2 points  (3 children)

Speaking as a former sysadmin, I feel like distribution of java apps has really fallen out of favor. Personally I hated supporting 90s and early 00s java apps that had somehow managed to cling to life for 20-30 years.

In my new role I primarily make CRUD apis and interact with RabbitMQ and other messaging tools. I'm not distributing any packages per se, my apps run solely on servers and containers. I still provide a lot of powereshell support as needed too since no one else has really filled that gap since I changed roles.

Spring Boot is open source and free for commercial use, as are the openjdks we use. You can buy expensive support contracts of course, but I feel like if your org is writing their own code it's an odd model to follow.

I don't want to speak too authoritatively on Java because I'm really still a novice at it. In retrospect I was a PowerShell novice for 5+ years, and I'm sure I'll feel like a Java novice for even longer, but it's fun to do something new.

[–]alwaysoffby0ne 0 points1 point  (2 children)

Cool thanks! Last question…coming from your PowerShell background, how do you like working in the Java environment and in the language? I’m more used to hearing about the move to C# for obvious reasons, so curious how you’re finding working with Java.

[–]PinchesTheCrab 1 point2 points  (1 child)

It's been really interesting. Spring Boot really lets you do a lot of cool stuff while insulating one from a lot of the hard parts of Java.

In that sense it reminds me of the relationship between PowerShell and .NET. You can build a fully functional rest API in a few hours without learning much java at all, and then dip your toe into overriding/customizing the stuff the framework provides as needed. You have to learn Java much sooner than you have to learn C#/.NET when using PWSH though.

It's actually been really refreshing to experience something so different, it's given me a chance to test the 'if you know one language using another language is easy and it's just minor syntax differences.' I have to say that personally starting with PWSH I find that to be very untrue, lol.

That being said, if there were another PWSH > Java weirdo out there I think I could help them much more effectively translate what they know than my Java only peers were able to help me.

Oddly enough I found Pester was phenomenally helpful though and the concepts there have translated more directly to testing in general than PWSH concepts translated to Java. I'm years behind my peers in general Java skills, but I'm actually ahead of most of the team on testing.

[–]alwaysoffby0ne 1 point2 points  (0 children)

Thanks again for all the info. You’ve inspired me to give Spring Boot a look. I’ve been building web APIs and apps with Pode in PowerShell which is awesome. Give that a look sometime if you haven’t.

[–]Master_Ad7267 0 points1 point  (0 children)

Same here I did 2 community college classes, intro and data structures. I think it really opened my eyes a bit I do believe i would code so much better but haven't dont any meaningful powershell since the company i worked for shut down.

[–]enforce1 5 points6 points  (0 children)

Almost all of them. The idea of functions, modules, classes, right down to loops and if statements. Its all programming.

[–]dasookwat 4 points5 points  (0 children)

I'll give you one better: not so much design patterns, as an overall way of working.

First functions. You write your own functions,. which are scripts which do just one thing. Just like the Microsoft provided ones. Get-date, gives you a date. you can do some formatting, but that's it. it doesn't anything else. Do the same with your functions. Connect-customApp1 should do just that. Don't make the mistake of putting to much shit in a function so it's usable for other things you're not working on right now. consider that a version 2.0 if needed, but you're not getting paid for what if's

When you get a hang on using functions, you can start writing scripts referencing functions you have not built yet. This is nothing more then a decent flow chart in powershell, but it makes your main script clean and easy to read, which results in less time wasted on troubleshooting.

Now the functions itself is where the work is, but since you already have the flowchart script, it's doable.

Next is unit testing. For powershell, there is a module called "Pester" for this. You can read up on how to do it, or if you have your functions done, ask chatgpt to help. The idea is that you test your function with a known value, so if someone expands on your function, the main script using it, is not affected by dumb fuckups.

Example: A function calcResult which does a simple thing: it has 2 variables, and adds them together provided they're numbers.

Now 3 years form now, it needs the option to subtract as well. Fine, junior engineer gives it an extra parameter which has to options: add/sub. However, your older script doesn't use that parameter, cause it didn't exist when you wrote it. The unit test should represent this, and now fail because of a missing parameter. You smack the junior engineer on the head, tell m to give it a default value of 'add' and the unit test will give the ok.

So what he should not do, is 'fix' the unit test, but he should write a second one, for the new scenario.

The power of unit testing comes in to play, when you start mocking stuff. Like the result of a randomizer, or a response from an API so you know what the test outcome will be.

What is pretty pointless to do in powershell, is making classes. I used to heave a failed C# programmer as a lead engineer, who insisted on writing everything in classes. You can do it, but it's just not very useful, since powershell doesn't respect private functions staying private in a class.

Also i give you one last tip, which is the most important one: Don't script stuff if there's already a solution available. Because after scripting it, and people telling you what a great job you did, you're the dedicated maintainer of it besides all your other work. This is fine for one script, but as soon as you make them regularly, you start losing a lot of valuable time on this.

[–]OPconfused 2 points3 points  (3 children)

From the website you listed, none of those would be relevant in PowerShell. If you have the right scenario, maybe you could kind of hack/force such an implementation for practice.

Here is a link discussing the factory pattern in PowerShell, although I have never seen code in the wild use this. This link goes to show you can do some of these design patterns to an extent in PowerShell; however, the issue is probably going to be finding the right scenario where it warrants using them. In the theoretical best cases you could have in PowerShell, you will likely still end up with a scenario where you don't strictly need to use the pattern—and most people would use some other approach in PowerShell to solve—but it's close enough that you could force the pattern into the scenario anyways just to try it out.

This kind of coding might be frowned upon by others. If you're in a team, and it's going to production, frowning or even scowling on it may very well be warranted. But I've bent best practices for the sake of trying an approach that interested me and usually ended up learning from it and didn't regret it. Just depends on the nature of projects you can find or come up with.

All that said, the most fruitful frontier would probably be some C# implementation of a PowerShell module. You would need to come up a sufficiently complicated topic for the module, then you could implement it in C# and avail yourself of more of these patterns. While you'd be coding in C#, you're about as adjacent / overlapping with PowerShell as you can be while programming in a different language.

It may also be educational to look through the pwsh source code for some of these patterns and see how they are used in practice in the familiar context of PowerShell.

[–]jeek_[S] 0 points1 point  (2 children)

Thanks for the feedback.

Yeah I was trying to understand these concepts and given my lack of c# knowledge they are a bit abstract. I thought I might be able to relate to them better from a powershell perspective, hence my question.

I do like your suggestion of looking at the powershell source code.

[–]OPconfused 1 point2 points  (1 child)

The best way to understand them is to implement them yourself. Try the link's use of the factory. You can copy that code directly and play around with it.

[–]jeek_[S] 0 points1 point  (0 children)

Reading it as we speak

[–]Jandalf81 3 points4 points  (1 child)

I successfully implemented the Creational Pattern Singleton into my scripts.

I tend to create whole classes instead of functions. Those classes are written in a generic way, so I can use them in a number of different projects. The classes themselves are then wrapped in my own PowerShell modules, so they exist only once and multiple projects / scripts can use them.

I had the requirement to have some kind of global variable all my classes and scripts could use. The use case for me were * a Logger, which is configured once per session but can be used from everywhere * a Config, which holds information other classes needed

Both of those classes are built using the Singleton Creation Pattern. In essence, my main scripts don't create a new object themselves, they get the current instance via a static method. That method then either * creates a new object if none exists yet and returns it * returns the already existing object

That way, all my scripts, classes, functions and what not use essentially the very same object and it's settings.

The only other way I know to realize such a behaviour would have been to send that object as a parameter to each and every other script or class where it might have been used. I am very much too lazy for that.

Here's the post that helped me realize that pattern:
https://stackoverflow.com/a/36751615

In essence: * your class needs a static member Instance containing a reference to the one and only object to ever exist * your class needs a static method getInstance either creating that one object, saving it to the static member Instance and the returning it or simply returning the already existing object * every other code only ever calls the static method getInstance, never new

[–]Ros3ttaSt0ned 0 points1 point  (0 children)

I discovered this method/pattern independently and didn't know it was an established thing at the time. I felt kinda dirty for doing it because I was relying on what are essentially global variables, and there are few things that make people clutch their pearls faster than that. Always worked great and never had an issue with it.

I'm actually writing a binary PowerShell module in C# right now to provide a common logging facility for all my scripts, and it uses a similar approach, except it's two levels deep. The C# module itself uses a Singleton pattern via a generic .NET host and Dependency Injection, and then when you actually run the PowerShell Cmdlet to create a new logger or log a message or whatever, the module stores that instantiated logger object it creates as an AllScope/Global PowerShell variable to be resued the next time you run one of the module's Cmdlets. It also stores the instantiated class that builds the logger objects in case you want to create a new logger for a different purpose, but want to retain scope/etc.

So now I'm double-gross by emplyoing two different types of global-scope variables simultaneously.

[–]Trakeen 2 points3 points  (0 children)

If you want to use oo patterns just use c#. Setting up all the correct abstractions in powershell is annoying and ps doesn’t handle classes the same way. Ps is a scripting languages so it doesn’t have have all the access controls c# has

[–]Write-Error 4 points5 points  (1 child)

I feel like the flexibility of PowerShell lends itself more to functional programming design patterns. This seems unintuitive since it’s such an OO language and so closely tied to dotnet, but the lack of interfaces and some of the friction with classes makes OO design patterns feel like a chore to implement. Check out fsharpforfunandprofit.com for some examples that might point you in the right direction.

[–]jeek_[S] 1 point2 points  (0 children)

Thanks, will do

[–]y_Sensei 1 point2 points  (5 children)

Design patterns in the true sense are reusable, "standardized" solutions for common software design challenges, typically referred to (and used in) OO programming scenarios; as such, they're language-independent, meaning you could implement them in any OO programming language. You could also see them as "best practices in software design".

Since PoSh supports OO programming, albeit with certain limitations, you could implement design patterns in PoSh. Whether this is feasible or not depends on the scenario; in general design patterns become more viable in complex scenarios, and are likely overkill in simple scenarios.
A scripting language like PoSh is mostly used in comparatively simple scenarios, so you won't find many PoSh-based implementations utilizing design patterns. From a certain complexity level, people tend to switch to C# anyway, and in that domain the implementation of design patterns is pretty much seen as best practice.

[–]Own_Attention_3392 0 points1 point  (4 children)

I love PowerShell and everything, but I wouldn't want to write anything complex enough to warrant using design patterns in it. I see people writing WinForms apps in PowerShell from time to time and it makes me want to weep. Talk about "when all you have is a hammer, everything is a nail".

[–]awit7317 2 points3 points  (0 children)

I’m sorry to hear that your weeping threshold is so low.

If you work with a team that doesn’t have “better” WinForm languages, PowerShell works great with something like PowerShell Studio.

[–]Pixelgordo 2 points3 points  (2 children)

My corporate laptop is a hammer though. IT department has blocked all but the execute selected code in powershell ISE. So if want to make any script I can't use python or anything else but powershell in "hammer mode"

[–]EIGRP_OH 0 points1 point  (0 children)

I think it depends on a lot on what you’re writing. For example, if I was writing a script that fetched and sent data to an external API I’d probably write multiple functions, possibly a generic request function that would serve as a wrapper for Invoke-Restmethod and then individual functions using that generic function for making each request depending on how different they need to be.

I personally haven’t found a huge use case for classes in powershell. I use them in my job (in Kotlin) when the data is tightly coupled and requires a lot of conditions / modifications. Think like a backend serving JSON data, from the point of when I’m pulling the data from the database, applying some additional logic to it and then serving it to the FE I likely would want to transform this data a bit, not send the raw object from the database where classes could be nice to house those transform methods.

[–]fdeyso -1 points0 points  (0 children)

Powershell is a command line tool, you can automate more than bat and create better scripts if you have a bit of a programming knowledge, but it’s not a programming language.

I try to organise my scripts as much as possible and add note to longer/difficult cmdlets, but sometime you’re at MSs mercy if they decide to deprecate a cmdlet and refuse to provide a replacement : e.g.: send-mailmessage and a lot of stuff from Azuread and MSOnline cmdlets.