Hey all,
I’m trying to figure out if I’m doing something wrong or if this has always behaved this way with classes in particular.
MyClass.psm1:
CLASS MyClass {
[string]$MyMember
#[int]$MyInt
MyClass( [string]$Message ) { #, [int]$Number) {
$this.MyMember = $Message
#$this.MyInt = $Number
}
}
Behavior:
PS > $PSVersionTable
Name Value
---- -----
PSVersion 7.2.0
PSEdition Core
GitCommitId 7.2.0
OS Microsoft Windows 10.0.19044
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
PS > Get-Module
ModuleType Version PreRelease Name ExportedCommands
---------- ------- ---------- ---- ----------------
Manifest 7.0.0.0 Microsoft.PowerShell.Management {Add-Content, Clear-Content, Clear-Item, Clear-ItemProperty…}
Manifest 7.0.0.0 Microsoft.PowerShell.Utility {Add-Member, Add-Type, Clear-Variable, Compare-Object…}
Script 2.1.0 PSReadLine {Get-PSReadLineKeyHandler, Get-PSReadLineOption, Remove-PSReadLineKeyHandler, Set-PSReadLineKeyHandler…}
PS > Import-Module .\MyClass.psm1
PS > Get-Module
ModuleType Version PreRelease Name ExportedCommands
---------- ------- ---------- ---- ----------------
Manifest 7.0.0.0 Microsoft.PowerShell.Management {Add-Content, Clear-Content, Clear-Item, Clear-ItemProperty…}
Manifest 7.0.0.0 Microsoft.PowerShell.Utility {Add-Member, Add-Type, Clear-Variable, Compare-Object…}
Script 0.0 MyClass
Script 2.1.0 PSReadLine {Get-PSReadLineKeyHandler, Get-PSReadLineOption, Remove-PSReadLineKeyHandler, Set-PSReadLineKeyHandler…}
PS > [MyClass]::New("Hello World!")
InvalidOperation: Unable to find type [MyClass].
PS > Remove-Module MyClass
PS > Get-Module
ModuleType Version PreRelease Name ExportedCommands
---------- ------- ---------- ---- ----------------
Manifest 7.0.0.0 Microsoft.PowerShell.Management {Add-Content, Clear-Content, Clear-Item, Clear-ItemProperty…}
Manifest 7.0.0.0 Microsoft.PowerShell.Utility {Add-Member, Add-Type, Clear-Variable, Compare-Object…}
Script 2.1.0 PSReadLine {Get-PSReadLineKeyHandler, Get-PSReadLineOption, Remove-PSReadLineKeyHandler, Set-PSReadLineKeyHandler…}
PS > Using Module .\Documents\Scripts\Powershell-Local\MyClass.psm1
PS > Get-Module
ModuleType Version PreRelease Name ExportedCommands
---------- ------- ---------- ---- ----------------
Manifest 7.0.0.0 Microsoft.PowerShell.Management {Add-Content, Clear-Content, Clear-Item, Clear-ItemProperty…}
Manifest 7.0.0.0 Microsoft.PowerShell.Utility {Add-Member, Add-Type, Clear-Variable, Compare-Object…}
Script 0.0 MyClass
Script 2.1.0 PSReadLine {Get-PSReadLineKeyHandler, Get-PSReadLineOption, Remove-PSReadLineKeyHandler, Set-PSReadLineKeyHandler…}
PS > [MyClass]::New("Hello World!")
MyMember
--------
Hello World!
PS > Remove-Module MyClass
PS > Get-Module
ModuleType Version PreRelease Name ExportedCommands
---------- ------- ---------- ---- ----------------
Manifest 7.0.0.0 Microsoft.PowerShell.Management {Add-Content, Clear-Content, Clear-Item, Clear-ItemProperty…}
Manifest 7.0.0.0 Microsoft.PowerShell.Utility {Add-Member, Add-Type, Clear-Variable, Compare-Object…}
Script 2.1.0 PSReadLine {Get-PSReadLineKeyHandler, Get-PSReadLineOption, Remove-PSReadLineKeyHandler, Set-PSReadLineKeyHandler…}
PS > [MyClass]::New("Hello World!")
MyMember
--------
Hello World!
PS >
1.) I understand classes are not supported by Import-Module (found it on MSDN).
2.) How do I enable tab completion for my class and methods? I.E. PS > [MyCl<TAB>
3.) How do I remove my class (i.e., modify PSM1 file and want to refresh)?
I don’t mind restarting PowerShell, so I’m interested in why this behavior is this way and what (if anything) I’m doing wrong. I noticed specifically that my class object type has no “ExportedCommands”, which I assume is relevant for automatic type conversion (.ToString()
, .CompareTo()
, etc).
Here’s another odd one, classes seem to not be unloaded from memory after script completion:
#MyClass.psm1:
CLASS MyClass {
[string]$MyMember
#[int]$MyInt
MyClass( [string]$Message ) { #, [int]$Number) {
$this.MyMember = $Message
#$this.MyInt = $Number
}
}
#Instance.ps1
Using Module .\MyClass.psm1
$Instance = [MyClass]::New('Hello World!')
$Instance
#Output:
PS > $data = .\Instance.ps1
PS > $data
MyMember
--------
Hello World!
PS > $data | Get-Member -Static -Name new
TypeName: MyClass
Name MemberType Definition
---- ---------- ----------
new Method MyClass new(string Message)
#Modified MyClass.psm1: Added MyInt member.
PS > Get-Content .\MyClass.psm1
CLASS MyClass {
[string]$MyMember
[int]$MyInt
MyClass([string]$Message,[int]$Number) {
$this.MyMember = $Message
$this.MyInt = $Number
}
}
PS > Remove-Variable data
#Expected output:
PS > $data = .\Instance.ps1
MethodException: ...\Instance.ps1:3
Line |
3 | $Instance = [MyClass]::New('Hello World!')
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Cannot find an overload for "new" and the argument count: "1".
#Actual Output:
PS > $data = .\Instance.ps1
PS > $data
MyMember
--------
Hello World!
PS > $data | Get-Member -Name new -Static
TypeName: MyClass
Name MemberType Definition
---- ---------- ----------
new Method MyClass new(string Message)
PS >
::EDIT:: To be clear, the test above with Instance.ps1 was from a fresh console
Thanx in advance,
Steve