Skip to content

Invoke-DscResource cmdlet throws an exception when using class-based DSC Resource, when module path contains a space #73

@KristiyanGK

Description

@KristiyanGK

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

  1. 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.
  1. 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.

image

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions