-
Notifications
You must be signed in to change notification settings - Fork 17
Description
When using a custom class-based DSC resource, the **Invoke-DscResource **cmdlet fails.
The issue seems to be in the function Invoke-DscClassBasedResource in the PSDesiredStateConfiguration.psm1 of the PSDesiredStateConfiguration module:
$script = @"
using module $path
Write-Host -Message ([$type]::new | out-string)
return [$type]::new()
"@
When $path is a string with white spaces for example: C:\My Modules\MyModule.psd1 the path gets cut off at the first space and results in C:\My. This leads to an error when trying to use the module, due to the fact that the path is invalid.
Steps to reproduce
- Create a Dsc Resource located in : C:\My Modules\MyDscResource.psm1 or the standard Module path: C:\Program Files\WindowsPowerShell\Modules
enum Ensure
{
Absent
Present
}
[DscResource()]
class FileResource
{
[DscProperty(Key)]
[string]$Path
[DscProperty(Mandatory)]
[Ensure] $Ensure
[DscProperty(Mandatory)]
[string] $SourcePath
[DscProperty(NotConfigurable)]
[Nullable[datetime]] $CreationTime
[void] Set() {
$fileExists = $this.TestFilePath($this.Path)
if ($this.ensure -eq [Ensure]::Present) {
if (-not $fileExists) {
$this.CopyFile()
}
}
else {
if ($fileExists) {
Write-Verbose -Message "Deleting the file $($this.Path)"
Remove-Item -LiteralPath $this.Path -Force
}
}
}
[bool] Test() {
$present = $this.TestFilePath($this.Path)
if ($this.Ensure -eq [Ensure]::Present) {
return $present
} else {
return -not $present
}
}
[FileResource] Get() {
$present = $this.TestFilePath($this.Path)
if ($present) {
$file = Get-ChildItem -LiteralPath $this.Path
$this.CreationTime = $file.CreationTime
$this.Ensure = [Ensure]::Present
}
else {
$this.CreationTime = $null
$this.Ensure = [Ensure]::Absent
}
return $this
}
[bool] TestFilePath([string] $location) {
$present = $true
$item = Get-ChildItem -LiteralPath $location -ea Ignore
if ($item -eq $null) {
$present = $false
} elseif ($item.PSProvider.Name -ne "FileSystem") {
throw "Path $($location) is not a file path."
}
elseif ($item.PSIsContainer) {
throw "Path $($location) is a directory path."
}
return $present
}
[void] CopyFile() {
if (-not $this.TestFilePath($this.SourcePath)) {
throw "SourcePath $($this.SourcePath) is not found."
}
[System.IO.FileInfo] $destFileInfo = new-object System.IO.FileInfo($this.Path)
if (-not $destFileInfo.Directory.Exists) {
Write-Verbose -Message "Creating directory $($destFileInfo.Directory.FullName)"
[System.IO.Directory]::CreateDirectory($destFileInfo.Directory.FullName)
}
if (Test-Path -LiteralPath $this.Path -PathType Container) {
throw "Path $($this.Path) is a directory path"
}
Write-Verbose -Message "Copying $($this.SourcePath) to $($this.Path)"
Copy-Item -LiteralPath $this.SourcePath -Destination $this.Path -Force
}
} # This module defines a class for a DSC "FileResource" provider.
- Invoke the DSC Resource with the Invoke-DscResource cmdlet
$invokeParams = @{
Name = 'FileResource'
Modulename = 'MyDscResource'
Method = 'Test'
Property = @{
Path = "C:\Test\sample data.txt"
SourcePath = "C:\Test\sample data.txt"
Ensure = "Present"
}
Verbose = $true
}
Invoke-DscResource @invokeParams
Expected behavior
Should Invoke the resource correctly and return a valid result.
Actual behavior
Throws various exceptions due to not parsing the module path correctly.
Environment data
$psversiontable info
PSVersion | 7.0.3
PSEdition | Core
GitCommitId | 7.0.3
OS | Microsoft Windows 10.0.18363
Platform | Win32NT
PSCompatibleVersions| {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion | 2.3
SerializationVersion |1.1.0.1
WSManStackVersion |3.0