When starting to use classes with powershell I found it a useful addition to facilitate complex scripts and make my code easier to read. But if you'd liked to use classes with parameter input, global variables and modules it was hard to have a setup which enables the use of all together. This post will help you to use modules with classes and benefit from an easier to read code. My work is based on following blogs and posts. So if you need a better understanding, please consult those websites first.
Basic Folder Setup
I only use classes in modules. The benefit, they're logically separated from a main.ps1 script. Your code will stay clean and easy to read.
Example folder structure
<root>/src
------main.ps1
<root>/resources
------helper.psm1
------helper.psd1
main.ps1
It contains all parameter declarations, global variables, invocation variable setup, requirementschecks to run my code. This script will be executed from an external source and can be integrated into Azure functions or classic task scheduler operations.
#Parameter Input
Param(
[Parameter(Mandatory=$true, HelpMessage = "Please enter value")]
[String]$firstname = "John",
[string]$lastname = "Doe",
)
#Invocation variable setup / global variables
$Global:srcPath = split-path -path $MyInvocation.MyCommand.Definition
$Global:mainPath = split-path -path $srcPath
$Global:root = split-path -path $mainPath
$Global:resourcespath = join-path -path "$mainPath" -ChildPath "resources"
#Requirements Check
if (($psversiontable.psversion.Major -lt 5)) {
"$(Get-Date) [RequirementsCheck] Please Install Powershell 5" >> $Global:logFile
Write-Error -Message "Please Install Powershell Version 5" -ErrorAction Stop
}
One major benefit is the invocation variable setup. It allows you to execute, access or import additionals resources by predefined variables. $srcPath variable points to <root>/src folder and $resourcespath to <root>/resources folder. Those variables only work if you execute the script from the <root>/src.
Import modules with classes
Creating your helper.psd1 can be done through New-ModuleManifest cmdlet. Two options are important for my cause. RootModule tells which .psm1 file is associated with your manifest. In FunctionsToExport I define a Get-Helper function. The main use of this function is to instantiate my class. With this workaround I can use all the benefits of modules and use class abilities within a seperate file.
# Script module or binary module file associated with this manifest.
RootModule = 'Helper.psm1'
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
FunctionsToExport = @(Get-Helper)
helper.psm1
At the top my module uses a function as defined previously to instantiate the class. This trick enables you to use the import-module cmdlet, load the module and with the function we create a New Helper Object and benefit from classes.
function Get-Helper(){
return [Helper]::new()
}
class Helper {
[String] $firstname
[String] $lastname
Helper(){
}
}
Last but no least somewhere in your main.ps1 you can now Import your module and use the Get-Helper function to instantiate your class.
Import-Module -Force "$resourcespath\Helper.psm1"
$NewHelperObject = Get-Helper()
Summary
Classes aren't loaded within powershell modules. Classes can help you organize your code and modules are useful to logically separate your actions. The post helped you to create a basic main execution file (main.ps1) and used Import-Module cmdlet to load a helper module (helper.psm1) which contains class structures. Modules need a manifest (helper.psd1) to work properly and make the function available for your main execution file.
コメント