CreateFile.psm1

enum ensure {
    Absent
    Present
}

class reason {
    [DscProperty()]
    [string] $code

    [DscProperty()]
    [string] $phrase
}

function Get-DSCFile {
    param(
        [parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [String]$path,

        [ensure]$ensure
    )

    $filePresent = [reason]::new()
    $filePresent.code = 'file:file:path'

    $fileExists = Test-path $path -ErrorAction SilentlyContinue
    if ($true -eq $fileExists) {
        $filePresent.phrase = "The file was expected to be: $ensure `
                               `nThe file exists at path: $path"

        $ensure = 'Present'
    }
    else {
        $filePresent.phrase = "The file was expected to be: $ensure `
                               `nThe file does not exist at path: $path"

        $ensure = 'Absent'
    }

    return @{
        ensure  = $ensure
        path    = $path
        reasons = @($filePresent)
    }
}

function Set-DSCFile {
    param(
        [parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [String]$path,

        [ensure]$ensure
    )

    Remove-Item $path -Force -ErrorAction SilentlyContinue
    if ($ensure -eq "Present") {
        New-Item $path -ItemType File -Force
    }
}

function Test-DSCFile {
    param(
        [parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [String]$path,

        [ensure]$ensure
    )

    $test = $false
    $get = Get-DSCFile @PSBoundParameters
    
    if ($get.ensure -eq $ensure) {
        $test = $true
    }
    return $test
}

[DscResource()]
class CreateFile {
    [DscProperty(Key)]
    [string] $path

    [DscProperty(Mandatory)]
    [ensure] $ensure

    [DscProperty()]
    [reason[]] $reasons

    [CreateFile] Get() {
        $get = Get-DSCFile -ensure $this.ensure -path $this.path
        return $get
    }
    
    [void] Set() {
        $set = Set-DSCFile -ensure $this.ensure -path $this.path
    }

    [bool] Test() {
        $test = Test-DSCFile -ensure $this.ensure -path $this.path
        return $test
    }
}