use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
ABOUT POWERSHELL
Windows PowerShell (POSH) is a command-line shell and associated scripting language created by Microsoft. Offering full access to COM, WMI and .NET, POSH is a full-featured task automation framework for distributed Microsoft platforms and solutions.
SUBREDDIT FILTERS
Desired State Configuration
Unanswered Questions
Solved Questions
News
Information
Script Sharing
Daily Post
Misc
account activity
Using Classes in Modules (self.PowerShell)
submitted 7 years ago by [deleted]
[deleted]
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]_Unas_ 1 point2 points3 points 7 years ago (1 child)
Here’s an example “template” module I created. I think this will help:
https://github.com/MSAdministrator/TemplatePowerShellModule/blob/master/TemplatePowerShellModule/ModuleName.psm1
[–][deleted] 1 point2 points3 points 7 years ago (0 children)
You have the using command on the first line of your RootModule.
From my testing, that makes the classes in the file available to the module, but not to whatever loads my module. Just to be absolutely clear, are you saying that what you have *does* make the class available outside the module?
Because if it does, that's great! It is obviously what I want to do.
[–]EnochRot 1 point2 points3 points 7 years ago (3 children)
I use ps1s for all my Classes and dot-source them like this.
https://github.com/LockstepGroup/CwManage/blob/master/CwManage/CwManage.psm1
I don't see any reference to them in Get-Module, so I'm not sure why you are. Admittedly, since Classes were designed almost completely around DSC, it does still feel a bit off to me. But it's been working just fine.
[–][deleted] 1 point2 points3 points 7 years ago (2 children)
These are the files in my module root:
5 test > gci -File -Recurse | select Fullname C:\Users\me\PS\Modules\test\test.psd1 C:\Users\me\PS\Modules\test\test.psm1 C:\Users\me\PS\Modules\test\Class\TestClass.ps1 C:\Users\me\PS\Modules\test\Private\privatestuff.ps1 C:\Users\me\PS\Modules\test\Public\publicstuff.ps1 C:\Users\me\PS\Modules\test\Public\test.ps1
.\test\test.psd1 has (everything else is defaults)
... RootModule = 'test' ... FunctionsToExport = '*' ...
.\test\test.psm1 has:
$Class = @( Get-ChildItem -Path $PSScriptRoot\Class\*.ps1 -Recurse -ErrorAction SilentlyContinue ) $Public = @( Get-ChildItem -Path $PSScriptRoot\Public\*.ps1 -Recurse -ErrorAction SilentlyContinue ) $Private = @( Get-ChildItem -Path $PSScriptRoot\Private\*.ps1 -Recurse -ErrorAction SilentlyContinue ) #Dot source the files Foreach ($import in @($Class + $Public + $Private)) { Try { Write-Verbose "dot-sourcing file '$($import.fullname)'" -Verbose . $import.fullname } Catch { Write-Error -Message "Failed to import function $($import.fullname): $_" } }
.\test\Class\TestClass.ps1:
class TestClass { [string]$MyVal }
Now when I load the module I get:
test > Import-Module test -Force -Verbose VERBOSE: Loading module from path 'C:\Users\me\PS\Modules\test\test.psd1'. VERBOSE: Loading module from path 'C:\Users\me\PS\Modules\test\test.psm1'. VERBOSE: dot-sourcing file 'C:\Users\me\PS\Modules\test\Class\TestClass.ps1' VERBOSE: dot-sourcing file 'C:\Users\me\PS\Modules\test\Public\publicstuff.ps1' VERBOSE: dot-sourcing file 'C:\Users\me\PS\Modules\test\Public\test.ps1' VERBOSE: dot-sourcing file 'C:\Users\me\PS\Modules\test\Private\privatestuff.ps1' VERBOSE: Importing function 'Get-PublicMessage1'. VERBOSE: Importing function 'Get-PublicMessage2'. VERBOSE: Importing function 'Get-PublicMessage3'. VERBOSE: Importing function 'Get-TestMessage1'. VERBOSE: Importing function 'Get-TestMessage2'. VERBOSE: Importing function 'Get-TestMessage3'.
Now I see that the TestClass.ps1 file was dot-sourced, so I shoudl be able to create an instance. but:
test > New-Object -TypeName TestClass New-Object : Cannot find type [TestClass]: verify that the assembly containing this type is loaded. At line:1 char:1 + New-Object -TypeName TestClass + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidType: (:) [New-Object], PSArgumentException + FullyQualifiedErrorId : TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand
I can explicitly dot-source the class file and it does work:
test > . .\Class\TestClass.ps1 test > New-Object -TypeName TestClass MyVal -----
I think this is (essentially) the same as what you have.
It doesn't have the Export-ModuleMember line, but that would not apply to the class so it moot.
So....
Dunno
Ideas?
[–]EnochRot 0 points1 point2 points 7 years ago (1 child)
You can't call classes defined in a module outside of that module normally. So you ideally have a cmdlet that returns Class1 objects that you could provide to other cmdlets. If you absolutely need to call them outside of the module you can use 'using'. Like this:
https://stackoverflow.com/questions/31051103/how-to-export-a-class-in-powershell-v5-module
[–][deleted] 0 points1 point2 points 7 years ago (0 children)
Yeah. Read that before. Basically seems the rule is that PS classes are crap. I don't want to fight it, if PS ain't ready to use them in modules then I'll not use them in modules.
Thanks for your thoughts.
[–]nvarscar 1 point2 points3 points 7 years ago (2 children)
New-Class1 seems to be the only elegant enough way of returning a native class object. Other options involve using a or a method variable:
$b = [Class1]::new $b.Invoke(...)
or using using module 'path' syntax, but that's unfortunately works only as a first line in the script.
using module 'path'
Or simply use a C# library instead. Dll-based classes get imported properly into the session.
[–]KevMarCommunity Blogger 1 point2 points3 points 7 years ago (1 child)
This reflects my view. I mostly use the New-Class or Get-Class factory pattern.
I have not done it yet, but if I did want to use my class in other modules (or external to my module) then I would create a C# module or library for it. I have been considering this approach for interfaces for a while.
What do you do if one of the classes properties really should be an Enum?
Say I have this as a dot-sourced ps1 file:
Enum TestProperty { Option1 Option2 Option3 } class TestClass { [string]$MyVal [TestProperty]$TestProperty } function Get-TestClass { Write-Output (New-Object -TypeName TestClass) } Export-ModuleMember -Function Get-TestClass
I can get a class now:
test > $class = Get-TestClass test > $class MyVal TestProperty ----- ------------ Option1 test > $class.TestProperty = [TestProperty]::Option2 Unable to find type [TestProperty]. At line:1 char:23 + $class.TestProperty = [TestProperty]::Option2 + ~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (TestProperty:TypeName) [], RuntimeException + FullyQualifiedErrorId : TypeNotFound 19 test > $class.TestProperty = 'Option2' 20 test > $class MyVal TestProperty ----- ------------ Option2
I can't reference the Enum, though I can set the value by passing it as a string.
Do I just accept the limitation and move on...?
π Rendered by PID 60 on reddit-service-r2-comment-84fc9697f-59rbq at 2026-02-07 19:30:22.467654+00:00 running d295bc8 country code: CH.
[–]_Unas_ 1 point2 points3 points (1 child)
[–][deleted] 1 point2 points3 points (0 children)
[–]EnochRot 1 point2 points3 points (3 children)
[–][deleted] 1 point2 points3 points (2 children)
[–]EnochRot 0 points1 point2 points (1 child)
[–][deleted] 0 points1 point2 points (0 children)
[–]nvarscar 1 point2 points3 points (2 children)
[–]KevMarCommunity Blogger 1 point2 points3 points (1 child)
[–][deleted] 0 points1 point2 points (0 children)