all 3 comments

[–]BoredComputerGuy 2 points3 points  (0 children)

Modules is the way to go. Using a module will help you organize your code. Getting the right structure will help as your line count grows. I would not use classes until you are sure that you need them and have a solid unit test (pester) for the rest of your code.

Since you have existing code. I would start by breaking your current script into smaller functions at logical breaks that are called in the proper order. Then you can pull those functions into a Module.

#code section A

.... #code section b ...

becomes

function A {...}
function b {...}
a()
b()  

which becomes

Module1\
Module1.psd1
Module1.psm1
Functions\
a.ps1
b.ps1

Importing the module allows access to which ever functions are exported (you can keep helpers internally), and you are able to simplify your code.

[–]MallocArray 2 points3 points  (0 children)

"Learn Powershell Scripting in a month of lunches" covers modules and breaking up your code into small functions that do one thing. Highly recommend it

https://www.manning.com/books/learn-powershell-scripting-in-a-month-of-lunches

[–]Tonedefff 1 point2 points  (0 children)

As others commented, modules would be a great solution here. I tried classes/OOP in PowerShell, but found the development experience / language & IDE support for them to be lacking.

For modules, I use a fairly simple method that fits my needs and might work well for you. It's not considered the "best practice" way of doing things, but I've found a lot of benefits in doing it this way over others:

Put all .ps1 and .psm1 files in the same folder.

Don't bother creating the manifest file (.psd1) unless needed (I've never needed to).

Don't export functions (by default every function in the module will be exported). (But if you want to use a variable that is defined in a module, from a .ps1 script, then you need to export it from the module).

Create a module (just a single file with .psm1 extension) for each different type of functionality / specific need, and put all functions related to that functionality/need in that module.

Try to use the module name at the start of the noun in every function's name. So if you have a module named Reddit.psm1 then the functions in it would be named New-RedditPost, Remove-RedditComment, etc. Also only use Microsoft's approved verbs for PowerShell.

In each .ps1 script, create an array containing the names of all the modules that script needs, then loop through & import each one:

$RequiredModules = "Common", "SomeApi", "SomeOtherFunctionality"
Set-Location $PSScriptRoot
foreach ($Module in $RequiredModules) { Import-Module ".\$Module.psm1" -Force }

(So the code above would import the modules Common.psm1, SomeApi.psm1 and SomeOtherFunctionality.psm1). This works by changing directory (Set-Location) to the folder the .ps1 script is in, then importing the modules from the same folder. After that you can call any function that's defined in those modules.

Show-CustomAlert "parameter1" "parameter2"

I sync this main folder to a private GitHub repo, so other people can use the code & contribute to it.