1

I'm not sure how to structure a larger PowerShell script that uses classes, and I cannot find anything. I have five classes in one file. How do I call them without a main class? Is it proper to create a standalone script that simply instantiates the other classes and calls them?

In PowerShell, most everything I see is based on functions, not classes. And, PowerShell OOP and OOD it isn't exactly like designing OOP in the C# or Java sense. There is a lot the same concepts, but the structure is eluding me. It isn't enough to have keywords and classes, if I cannot design with them in a comprehensive way.

What search am I missing, they keywords? How should I structure my script? I have a lot of PowerShell classes already that I'd like to put into Production. Now what?

I've searched, and I've looked on SO and Github, but do not know what's "right."

My particular case is using v5, but other times I have access to v7, if that matters. I have, for example:

class A
{

}

class B
{

}

class C
{

}

There's no Main to start things off in PowerShell.

learntofix
  • 87
  • 5

1 Answers1

5

There's no Main to start things off in PowerShell.

The top-level scope of your script (.ps1 file) is the equivalent of a Main entry point. That is, any statements outside class class and function definitions are executed.

You're free to place class definitions anywhere in your script, as they are parsed before execution (this contrasts with functions, whose definitions must be placed before code that calls them).

Alternatively, you can place classes:

  • in a separate .ps1 file that you must then dot-source in your main script, before attempting to use them.

    • E.g., to dot-source classes.ps1 located in the same folder as your script:

      . $PSScriptRoot/classes.ps1
      
  • in a supporting module, which your main script must import via a using module statement at the start of your script (Import-Module does not work, because it doesn't import classes)

    • E.g., in the simplest case, if your classes are located in a stand-alone classes.psm1 script-module file in the same folder as the script:

      # Place at the top; no other statements (except other `using` ones) 
      # allowed before it.
      using module ./classes.psm1
      

Note:

  • Unless you need your classes to be used from multiple scripts, potentially via module auto-loading, there is no benefit to using a module.

  • A general caveat:

    • classes are a relatively late addition to the PowerShell language and, in terms of features, are not on par with C#'s classes - neither currently (see GitHub issue #6652 for list of current problems), nor is that the design goal.

    • While PowerShell is perfectly capable of operating on objects (class instances), most typically by accessing their properties, less often by calling their methods, the PowerShell language itself is not object-centric and uses an imperative control flow based on commands (scripts, functions, external programs).

    • For that reason - rather than trying to structure PowerShell code as if it were a C# application - it is advisable to limit the use of classes to providing occasional helper classes, such as strongly-typed "property bags", while implementing the control flow via scripts, functions, and cmdlets.

mklement0
  • 382,024
  • 64
  • 607
  • 775