I am trying to test some custom DSC resources written as a class with the help of pester. However I am struggling to work out how to make the class available to a different file. This is not a pester issue really, I can not do this in powershell either. I have a module with a class in it much like the following in a SxDeployment.psm1 file
[DscResource()]
class SxWindowsService {
[void]Set(){
}
[bool]Test(){
return $true;
}
[SxWindowsService]Get(){
return $this
}
}
This module has a corresponding .psd1, which is listing the SxWindowsService class as a 'DscResourcesToExport'. It is being registered as a module, I can see this module when I do a Get-Module -ListAvailable and can also perform an Import-Module upon it.
I suppose my question really is how can I create a a reference to this class from another file?
Say I have a different file test.ps1 with the following
Import-Module SxDeployment
$class = [SxWindowsService]::new()
I get the following error, "Unable to find type [SxWindowsService]."
UPDATE After a little more tinkering, I can create an instance of the class by changing the .psm1 file to a .ps file and changing the import-module statement for . .\SxDeployment.ps1. So it seems the problem is how do you consume resources defined in a DSC resource module file outside of a DSC configuration?
The type literal [SxWindowsService] won't be accessible outside the module. This is by design. Here is a quote from the release notes:
Class keyword >>> Defines a new class. This is a true .NET Framework type. Class members are public, but only public within the module scope. You can't refer to the type name as a string (for example, New-Object doesn't work), and in this release, you can't use a type literal (for example, [MyClass]) outside the script/module file in which the class is defined.
Edit:
Well after having said the above. Since there is a bit of a mismatch between object activation in .NET and PowerShell then I thought to myself, there might just be a way. And I found it:
Import-Module C:\ps\StackOverflow\32743812\issue.psm1 -Force
function New-PSClassInstance {
param(
[Parameter(Mandatory)]
[String]$TypeName,
[object[]]$ArgumentList = $null
)
$ts = [System.AppDomain]::CurrentDomain.GetAssemblies() |
Where-Object Location -eq $null |
Foreach-Object {
$_.Gettypes()
} | Where-Object name -eq $TypeName |
Select-Object -Last 1
if($ts) {
[System.Activator]::CreateInstance($ts,$ArgumentList )
} else {
$typeException = New-Object TypeLoadException $TypeName
$typeException.Data.Add("ArgumentList",$ArgumentList)
throw $typeException
}
}
New-PSClassinstance -TypeName SxWindowsService