how to export a class in powershell v5 module

后端 未结 10 692
不思量自难忘°
不思量自难忘° 2020-12-08 14:53

I\'ve got a module setup to be like a library for a few other scripts. I can\'t figure out how to get a class declaration into the script scope calling Import-Module

相关标签:
10条回答
  • 2020-12-08 15:11

    the using statement is the way to go if it works for you. otherwise this seems to work as well.

    testclass.psm1

    Use a function to deliver the class

    class abc{
        $testprop = 'It Worked!'
        [int]testMethod($num){return  $num * 5}
    }
    
    function new-abc(){
        return [abc]::new()
    }
    
    Export-ModuleMember -Function new-abc
    

    someScript.ps1

    Import-Module path\to\testclass.psm1
    $testclass = new-abc
    $testclass.testProp        # returns 'It Worked!'
    $testclass.testMethod(500) # returns 2500
    
    
    $testclass | gm
    
    Name        MemberType Definition
    ----        ---------- ----------
    Equals      Method     bool Equals(System.Object obj)
    GetHashCode Method     int GetHashCode()
    GetType     Method     type GetType()
    testMethod  Method     int testMethod(System.Object num)
    ToString    Method     string ToString()
    testprop    Property   System.Object testprop {get;set;}
    
    0 讨论(0)
  • 2020-12-08 15:11

    I've encountered multiple issues regarding PowerShell classes in v5 as well.

    I've decided to use the following workaround for now, as this is perfectly compatible with .net and PowerShell:

    Add-Type -Language CSharp -TypeDefinition @"
    namespace My.Custom.Namespace {
        public class Example
        {
            public string Name { get; set; }
            public System.Management.Automation.PSCredential Credential { get; set; }
            // ...
        }
    }
    "@
    

    The benefit is that you don't need a custom assembly to add a type definition, you can add the class definition inline in your PowerShell scripts or modules.

    Only downside is that you will need to create a new runtime to re-load the class definition after is has been loaded for the first time (just like loading assemblies in a c#/.net domain).

    0 讨论(0)
  • 2020-12-08 15:12

    The way I've worked around this problem is to move your custom class definition into an empty .ps1 file with the same name (like you would in Java/C#), and then load it into both the module definition and your dependent code by dot sourcing. I know this isn't great, but to me it's better than having to maintain multiple definitions of the same class across multiple files...

    0 讨论(0)
  • 2020-12-08 15:22

    I found a way to load the classes without the need of "using module". In your MyModule.psd1 file use the line:

    ScriptsToProcess = @('Class.ps1')
    

    And then put your classes in the Class.ps1 file:

    class MyClass {}
    

    Update: Although you don't have to use "using module MyModule" with this method you still have to either:

    • Run "using module MyModule"
    • Or run "Import-Module MyModule"
    • Or call any function in your module (so it will auto import your module on the way)

    Update2: This will load the Class to the current scope so if you import the Module from within a function for example the Class will not be accessible outside of the function. Sadly the only reliable method I see is to write your Class in C# and load it with Add-Type -Language CSharp -TypeDefinition 'MyClass...'.

    0 讨论(0)
提交回复
热议问题