cMDTBuildLab.psm1

enum Ensure
{
    Absent
    Present
}

[DscResource()]
class cMDTBuildApplication
{
    [DscProperty(Mandatory)]
    [Ensure]$Ensure

    [DscProperty(Key)]
    [string]$Name

    [DscProperty(Key)]
    [string]$Path

    [DscProperty(Mandatory)]
    [string]$Enabled
    
    [DscProperty(Mandatory)]
    [string]$CommandLine
    
    [DscProperty(Mandatory)]
    [string]$ApplicationSourcePath
    
    [DscProperty(Mandatory)]
    [string]$PSDriveName

    [DscProperty(Mandatory)]
    [string]$PSDrivePath

    [void] Set()
    {
        if ($this.ensure -eq [Ensure]::Present) {
            $present = Invoke-TestPath -Path "$($this.path)\$($this.name)" -PSDriveName $this.PSDriveName -PSDrivePath $this.PSDrivePath
            if ( !$present ) {
                $this.ImportApplication()
            }
        }
        else {   
            Invoke-RemovePath -Path "$($this.path)\$($this.name)" -PSDriveName $this.PSDriveName -PSDrivePath $this.PSDrivePath -Verbose
        }
    }

    [bool] Test()
    {
        $present = Invoke-TestPath -Path "$($this.path)\$($this.name)" -PSDriveName $this.PSDriveName -PSDrivePath $this.PSDrivePath 

        if ($this.Ensure -eq [Ensure]::Present) {
            return $present
        }
        else {
            return -not $present
        }
    }

    [cMDTBuildApplication] Get()
    {
        return $this
    }

    [void] ImportApplication()
    {
        Import-MicrosoftDeploymentToolkitModule
        New-PSDrive -Name $this.PSDriveName -PSProvider "MDTProvider" -Root $this.PSDrivePath -Verbose:$false
        Import-MDTApplication -Path $this.Path -Enable $this.Enabled -Name $this.Name -ShortName $this.Name `
                              -CommandLine $this.CommandLine -WorkingDirectory ".\Applications\$($this.Name)" `
                              -ApplicationSourcePath $this.ApplicationSourcePath -DestinationFolder $this.Name -Verbose
    }
}

[DscResource()]
class cMDTBuildBootstrapIni
{
    [DscProperty(Mandatory)]
    [Ensure]$Ensure

    [DscProperty(Key)]
    [string]$Path

    [DscProperty()]
    [string]$Content

    [void] Set()
    {
        if ($this.Ensure -eq [Ensure]::Present) {
            $this.SetContent()
        }
        else {
            $this.SetDefaultContent()
        }
    }

    [bool] Test()
    {
        $present = $this.TestFileContent()
        
        if ($this.Ensure -eq [Ensure]::Present) {
            return $present
        }
        else {
            return -not $present
        }
    }

    [cMDTBuildBootstrapIni] Get()
    {
        return $this
    }

    [bool] TestFileContent()
    {
        $present = $false
        $existingConfiguration = Get-Content -Path $this.Path -Raw #-Encoding UTF8

        if ($existingConfiguration -eq $this.Content.Replace("`n","`r`n")) {
            $present = $true   
        }
        return $present
    }

    [void] SetContent()
    {
        Set-Content -Path $this.Path -Value $this.Content.Replace("`n","`r`n") -NoNewline -Force #-Encoding UTF8
    }
    
    [void] SetDefaultContent()
    {
            $defaultContent = @"
[Settings]
Priority=Default
 
[Default]
 
"@

        Set-Content -Path $this.Path -Value $defaultContent -NoNewline -Force #-Encoding UTF8
    }
}

[DscResource()]
class cMDTBuildCustomize
{
    [DscProperty(Mandatory)]
    [Ensure]$Ensure
    
    [DscProperty(Key)]
    [string]$Name

    [DscProperty(Key)]
    [string]$Path
    
    [DscProperty(Mandatory)]
    [string]$SourcePath

    [DscProperty(Mandatory)]
    [string[]]$TestFiles

    [DscProperty(NotConfigurable)]
    [string]$Directory

    [void] Set()
    {
        $filename = "$($this.SourcePath)\$($this.Name).zip"
        $extractfolder = "$($this.path)\$($this.name)"

        if ($this.ensure -eq [Ensure]::Present) {
            Invoke-ExpandArchive -Source $filename -Target $extractfolder -Verbose
        }
        else {
            Invoke-RemovePath -Path $extractfolder -Verbose
        }
    }

    [bool] Test()
    {
        $present = $true
        foreach ($file in $this.TestFiles) {
            if ( !(Test-Path -Path "$($this.path)\$($this.name)\$($file)") ) {
                $present = $false
                break
            }
        }

        if ($this.Ensure -eq [Ensure]::Present) {
            return $present
        }
        else {
            return -not $present
        }
    }

    [cMDTBuildCustomize] Get()
    {
        return $this
    }
}

[DscResource()]
class cMDTBuildCustomSettingsIni
{
    [DscProperty(Mandatory)]
    [Ensure]$Ensure

    [DscProperty(Key)]
    [string]$Path

    [DscProperty()]
    [string]$Content

    [void] Set()
    {
        if ($this.Ensure -eq [Ensure]::Present) {
            $this.SetContent()
        }
        else {
            $this.SetDefaultContent()
        }
    }

    [bool] Test()
    {
        $present = $this.TestFileContent()
        
        if ($this.Ensure -eq [Ensure]::Present) {
            return $present
        }
        else {
            return -not $present
        }
    }

    [cMDTBuildCustomSettingsIni] Get()
    {
        return $this
    }

    [bool] TestFileContent()
    {
        $present = $false 
        $existingConfiguration = Get-Content -Path $this.Path -Raw #-Encoding UTF8

        if ($existingConfiguration -eq $this.Content.Replace("`n","`r`n")) {
            $present = $true   
        }
        return $present
    }

    [void] SetContent()
    {
        Set-Content -Path $this.Path -Value $this.Content.Replace("`n","`r`n") -NoNewline -Force #-Encoding UTF8
    }
    
    [void] SetDefaultContent()
    {
            $defaultContent = @"
[Settings]
Priority=Default
Properties=MyCustomProperty
 
[Default]
OSInstall=Y
SkipCapture=YES
SkipAdminPassword=NO
SkipProductKey=YES
 
"@

        Set-Content -Path $this.Path -Value $defaultContent -NoNewline -Force #-Encoding UTF8
    }
}

[DscResource()]
class cMDTBuildDirectory
{
    [DscProperty(Mandatory)]
    [Ensure]$Ensure

    [DscProperty(Key)]
    [string]$Path

    [DscProperty(Key)]
    [string]$Name

    [DscProperty()]
    [string]$PSDriveName

    [DscProperty()]
    [string]$PSDrivePath

    [void] Set()
    {
        if ($this.ensure -eq [Ensure]::Present) {
            $this.CreateDirectory()
        }
        else
        {
            if (($this.PSDrivePath) -and ($this.PSDriveName)) {
                Invoke-RemovePath -Path "$($this.path)\$($this.Name)" -PSDriveName $this.PSDriveName -PSDrivePath $this.PSDrivePath -Verbose
            }
            else {
                Invoke-RemovePath -Path "$($this.path)\$($this.Name)" -Verbose
            }
        }
    }

    [bool] Test()
    {
        if (($this.PSDrivePath) -and ($this.PSDriveName)) {
            $present = Invoke-TestPath -Path "$($this.path)\$($this.Name)" -PSDriveName $this.PSDriveName -PSDrivePath $this.PSDrivePath -Verbose
        }
        else {
            $present = Invoke-TestPath -Path "$($this.path)\$($this.Name)" -Verbose
        }
        
        if ($this.Ensure -eq [Ensure]::Present) {
            return $present
        }
        else {
            return -not $present
        }
    }

    [cMDTBuildDirectory] Get()
    {
        return $this
    }

    [void] CreateDirectory()
    {
        if (($this.PSDrivePath) -and ($this.PSDriveName)) {
            Import-MicrosoftDeploymentToolkitModule
            New-PSDrive -Name $this.PSDriveName -PSProvider "MDTProvider" -Root $this.PSDrivePath -Verbose:$false | `
                New-Item -ItemType Directory -Path "$($this.path)\$($this.Name)" -Verbose
        }
        else {
            New-Item -ItemType Directory -Path "$($this.path)\$($this.Name)" -Verbose
        }
    }
}

[DscResource()]
class cMDTBuildOperatingSystem
{

    [DscProperty(Mandatory)]
    [Ensure]$Ensure

    [DscProperty(Key)]
    [string]$Name

    [DscProperty(Key)]
    [string]$Path

    [DscProperty(Key)]
    [string]$SourcePath

    [DscProperty(Mandatory)]
    [string]$PSDriveName

    [DscProperty(Mandatory)]
    [string]$PSDrivePath

    [void] Set()
    {
        if ($this.ensure -eq [Ensure]::Present)
        {
            if ( !$this.Test() ) {
                $this.ImportOperatingSystem("$($this.SourcePath)")
            }
        }
        else
        {
            Invoke-RemovePath -Path "$($this.PSDrivePath)\Operating Systems\$($this.Name)" -PSDriveName $this.PSDriveName -PSDrivePath $this.PSDrivePath -Verbose
            If ( $this.Test() ) { Write-Error "Cannot remove '$($this.PSDrivePath)\Operating Systems\$($this.Name)'" }
        }
    }

    [bool] Test()
    {
        $present = Invoke-TestPath -Path "$($this.PSDrivePath)\Operating Systems\$($this.Name)\sources\install.wim"
        return $present
    }

    [cMDTBuildOperatingSystem] Get()
    {
        return $this
    }

    [void] ImportOperatingSystem($OperatingSystem)
    {
        Import-MicrosoftDeploymentToolkitModule
        New-PSDrive -Name $this.PSDriveName -PSProvider "MDTProvider" -Root $this.PSDrivePath -Verbose:$false

        Try {
            $ErrorActionPreference = "Stop"
            Import-MDTOperatingSystem -Path $this.Path -SourcePath $OperatingSystem -DestinationFolder $this.Name -Verbose
            $ErrorActionPreference = "Continue"
        }
        Catch [Microsoft.Management.Infrastructure.CimException] {
            If ($_.FullyQualifiedErrorId -notlike "*ItemAlreadyExists*") {
                throw $_
            }
        }
        Finally {
        }
    }
}

[DscResource()]
class cMDTBuildPackage
{
    [DscProperty(Mandatory)]
    [Ensure]$Ensure

    [DscProperty(Key)]
    [string]$Name

    [DscProperty(Key)]
    [string]$Path

    [DscProperty(Mandatory)]
    [string]$PackageSourcePath
    
    [DscProperty(Mandatory)]
    [string]$PSDriveName

    [DscProperty(Mandatory)]
    [string]$PSDrivePath

    [void] Set()
    {
        if ($this.ensure -eq [Ensure]::Present) {
            $present = Invoke-TestPath -Path "$($this.path)\$($this.name)" -PSDriveName $this.PSDriveName -PSDrivePath $this.PSDrivePath
            if ( !$present ) {
                $this.ImportPackage()
            }
        }
        else {   
            Invoke-RemovePath -Path "$($this.path)\$($this.name)" -PSDriveName $this.PSDriveName -PSDrivePath $this.PSDrivePath -Verbose
        }
    }

    [bool] Test()
    {
        $present = Invoke-TestPath -Path "$($this.path)\$($this.name)" -PSDriveName $this.PSDriveName -PSDrivePath $this.PSDrivePath 

        if ($this.Ensure -eq [Ensure]::Present) {
            return $present
        }
        else {
            return -not $present
        }
    }

    [cMDTBuildPackage] Get()
    {
        return $this
    }

    [void] ImportPackage()
    {
        # The Import-MDTPackage command crashes WMI when run from inside DSC. Using workflow is a work around.
        workflow Import-Pkg {
            [CmdletBinding()]
            param(
                [string]$PSDriveName,
                [string]$PSDrivePath,
                [string]$Path,
                [string]$Source
            )
            InlineScript {
                Import-MicrosoftDeploymentToolkitModule
                New-PSDrive -Name $Using:PSDriveName -PSProvider "MDTProvider" -Root $Using:PSDrivePath -Verbose:$false
                Import-MDTPackage -Path $Using:Path -SourcePath $Using:Source -Verbose
            }
        }
        Import-Pkg $this.PSDriveName $this.PSDrivePath $this.Path $this.PackageSourcePath
    }
}

[DscResource()]
class cMDTBuildPersistentDrive
{

    [DscProperty(Mandatory)]
    [Ensure] $Ensure

    [DscProperty(Key)]
    [string]$Path

    [DscProperty(Key)]
    [string]$Name

    [DscProperty(Mandatory)]
    [string]$Description

    [DscProperty(Mandatory)]
    [string]$NetworkPath

    [void] Set()
    {

        if ($this.ensure -eq [Ensure]::Present)
        {
            $this.CreateDirectory()
        }
        else
        {
            $this.RemoveDirectory()
        }
    }

    [bool] Test()
    {

        $present = $this.TestDirectoryPath()
        
        if ($this.Ensure -eq [Ensure]::Present)
        {
            return $present
        }
        else
        {
            return -not $present
        }
    }

    [cMDTBuildPersistentDrive] Get()
    {
        return $this
    }

    [bool] TestDirectoryPath()
    {
        $present = $false

        Import-MicrosoftDeploymentToolkitModule

        if (Test-Path -Path $this.Path -PathType Container -ErrorAction Ignore)
        {
            $mdtShares = (GET-MDTPersistentDrive -ErrorAction SilentlyContinue)
            If ($mdtShares)
            {
                ForEach ($share in $mdtShares)
                {
                    If ($share.Name -eq $this.Name)
                    {
                        $present = $true
                    }
                }
            } 
        }

        return $present
    }

    [void] CreateDirectory()
    {

        Import-MicrosoftDeploymentToolkitModule

        New-PSDrive -Name $this.Name -PSProvider "MDTProvider" -Root $this.Path -Description $this.Description -NetworkPath $this.NetworkPath -Verbose:$false | `
        Add-MDTPersistentDrive -Verbose

    }

    [void] RemoveDirectory()
    {

        Import-MicrosoftDeploymentToolkitModule

        Write-Verbose -Message "Removing MDTPersistentDrive $($this.Name)"

        New-PSDrive -Name $this.Name -PSProvider "MDTProvider" -Root $this.Path -Description $this.Description -NetworkPath $this.NetworkPath -Verbose:$false | `
        Remove-MDTPersistentDrive -Verbose
    }
}

[DscResource()]
class cMDTBuildPreReqs
{
    [DscProperty(Mandatory)]
    [Ensure]$Ensure
    
    [DscProperty(Key)]
    [string]$DownloadPath

    [DscProperty(NotConfigurable)]
    [hashtable[]]
    $downloadFiles = @(
        @{
            #Version: MDT 2013 Update 2 (Build: 6.3.8330.1000)
            Name = "MDT"
            URI = "https://download.microsoft.com/download/3/0/1/3012B93D-C445-44A9-8BFB-F28EB937B060/MicrosoftDeploymentToolkit2013_x64.msi"
            Folder = "Microsoft Deployment Toolkit"
            File = "MicrosoftDeploymentToolkit2013_x64.msi"
        }
        @{
            #Version: Windows 10 v1607 (Build: 10.1.14393.0)
            Name = "ADK"
            URI = "http://download.microsoft.com/download/9/A/E/9AE69DD5-BA93-44E0-864E-180F5E700AB4/adk/adksetup.exe"
            Folder = "Windows Assessment and Deployment Kit"
            File = "adksetup.exe"
        }
        @{
            #Version: 5 (Build: 5.1.50901.0)
            Name = "Silverlight_x64"
            URI = "http://download.microsoft.com/download/0/3/E/03EB1393-4F4E-4191-8364-C641FAB20344/50901.00/Silverlight_x64.exe"
            Folder = "Silverlight_x64"
            File = "Silverlight_x64.exe"
        }
        @{
            #Version: 5 (Build: 5.1.50901.0)
            Name = "Silverlight_x86"
            URI = "http://download.microsoft.com/download/0/3/E/03EB1393-4F4E-4191-8364-C641FAB20344/50901.00/Silverlight.exe"
            Folder = "Silverlight_x86"
            File = "Silverlight.exe"
        }
        @{
            Name = "VS++Application"
            URI = "Sources\Install-MicrosoftVisualC++x86x64.wsf"
            Folder = "VC++"
            File = "Install-MicrosoftVisualC++x86x64.wsf"
        }
        @{
            Name = "VS2005SP1x86"
            URI = "http://download.microsoft.com/download/8/B/4/8B42259F-5D70-43F4-AC2E-4B208FD8D66A/vcredist_x86.exe"
            Folder = "VC++\Source\VS2005"
            File = "vcredist_x86.exe"
        }
        @{
            Name = "VS2005SP1x64"
            URI = "http://download.microsoft.com/download/8/B/4/8B42259F-5D70-43F4-AC2E-4B208FD8D66A/vcredist_x64.exe"
            Folder = "VC++\Source\VS2005"
            File = "vcredist_x64.exe"
        }
        @{
            Name = "VS2008SP1x86"
            URI = "http://download.microsoft.com/download/5/D/8/5D8C65CB-C849-4025-8E95-C3966CAFD8AE/vcredist_x86.exe"
            Folder = "VC++\Source\VS2008"
            File = "vcredist_x86.exe"
        }
        @{
            Name = "VS2008SP1x64"
            URI = "http://download.microsoft.com/download/5/D/8/5D8C65CB-C849-4025-8E95-C3966CAFD8AE/vcredist_x64.exe"
            Folder = "VC++\Source\VS2008"
            File = "vcredist_x64.exe"
        }
        @{
            Name = "VS2010SP1x86"
            URI = "http://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x86.exe"
            Folder = "VC++\Source\VS2010"
            File = "vcredist_x86.exe"
        }
        @{
            Name = "VS2010SP1x64"
            URI = "http://download.microsoft.com/download/1/6/5/165255E7-1014-4D0A-B094-B6A430A6BFFC/vcredist_x64.exe"
            Folder = "VC++\Source\VS2010"
            File = "vcredist_x64.exe"
        }
        @{
            Name = "VS2012UPD4x86"
            URI = "http://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x86.exe"
            Folder = "VC++\Source\VS2012"
            File = "vcredist_x86.exe"
        }
        @{
            Name = "VS2012UPD4x64"
            URI = "http://download.microsoft.com/download/1/6/B/16B06F60-3B20-4FF2-B699-5E9B7962F9AE/VSU_4/vcredist_x64.exe"
            Folder = "VC++\Source\VS2012"
            File = "vcredist_x64.exe"
        }
        @{
            Name = "VS2013x86"
            URI = "http://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x86.exe"
            Folder = "VC++\Source\VS2013"
            File = "vcredist_x86.exe"
        }
        @{
            Name = "VS2013x64"
            URI = "http://download.microsoft.com/download/2/E/6/2E61CFA4-993B-4DD4-91DA-3737CD5CD6E3/vcredist_x64.exe"
            Folder = "VC++\Source\VS2013"
            File = "vcredist_x64.exe"
        }
        @{
            Name = "VS2015x86"
            URI = "https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/vc_redist.x86.exe"
            Folder = "VC++\Source\VS2015"
            File = "vc_redist.x86.exe"
        }
        @{
            Name = "VS2015x64"
            URI = "https://download.microsoft.com/download/9/3/F/93FCF1E7-E6A4-478B-96E7-D4B285925B00/vc_redist.x64.exe"
            Folder = "VC++\Source\VS2015"
            File = "vc_redist.x64.exe"
        }
        @{
            Name = "WMF30x86"
            URI = "https://download.microsoft.com/download/E/7/6/E76850B8-DA6E-4FF5-8CCE-A24FC513FD16/Windows6.1-KB2506143-x86.msu"
            Folder = "WMF30x86"
            File = "Windows6.1-KB2506143-x86.msu"
        }
        @{
            Name = "WMF30x64"
            URI = "https://download.microsoft.com/download/E/7/6/E76850B8-DA6E-4FF5-8CCE-A24FC513FD16/Windows6.1-KB2506143-x64.msu"
            Folder = "WMF30x64"
            File = "Windows6.1-KB2506143-x64.msu"
        }
        @{
            Name = "WMF50x64"
            URI = "https://download.microsoft.com/download/2/C/6/2C6E1B4A-EBE5-48A6-B225-2D2058A9CEFB/Win8.1AndW2K12R2-KB3134758-x64.msu"
            Folder = "WMF50x64"
            File = "Win8.1AndW2K12R2-KB3134758-x64.msu"
        }
        @{
            Name = "KeyboardToggle"
            URI = "Sources\Toggle.reg"
            Folder = "KeyboardToggle"
            File = "Toggle.reg"
        }
        @{
            Name = "CleanupBeforeSysprep"
            URI = "Sources\Action-CleanupBeforeSysprep.wsf"
            Folder = "CleanupBeforeSysprep"
            File = "Action-CleanupBeforeSysprep.wsf"
        }
        @{
            Name = "RemoveAppsScript"
            URI = "Sources\RemoveApps.ps1"
            Folder = "RemoveApps"
            File = "RemoveApps.ps1"
        }
        @{
            Name = "RemoveApps8.1"
            URI = "Sources\RemoveApps81.xml"
            Folder = "RemoveApps"
            File = "RemoveApps81.xml"
        }
        @{
            Name = "RemoveApps10"
            URI = "Sources\RemoveApps10.xml"
            Folder = "RemoveApps"
            File = "RemoveApps10.xml"
        }
        @{
            Name = "CustomizeDefaultProfile"
            URI = "Sources\Customize-DefaultProfile.ps1"
            Folder = "Set-Startlayout"
            File = "Customize-DefaultProfile.ps1"
        }
        @{
            Name = "StartLayout"
            URI = "Sources\Default_Start_Screen_Layout.bin"
            Folder = "Set-Startlayout"
            File = "Default_Start_Screen_Layout.bin"
        }
        @{
            Name = "DesktopTheme"
            URI = "Sources\Theme01.deskthemepack"
            Folder = "Set-Startlayout"
            File = "Theme01.deskthemepack"
        }
        @{
            Name = "Extra"
            URI = "Sources\Extra.zip"
            Folder = "Extra"
            File = "Extra.zip"
        }
        @{
            Name = "Scripts"
            URI = "Sources\Scripts.zip"
            Folder = "Scripts"
            File = "Scripts.zip"
        }
        @{
            Name = "APPV51"
            URI = "Sources\appv_client_setup.zip"
            Folder = "APPV51x86x64"
            File = "appv_client_setup.zip"
        }
    )
    
    [void] Set()
    {
        Write-Verbose "Starting Set MDT PreReqs..."

        if ($this.ensure -eq [Ensure]::Present)
        {
            $present = $this.TestDownloadPath()

            if ($present) {
                Write-Verbose " Download folder present!"
            }
            else {
                New-Item -Path $this.DownloadPath -ItemType Directory -Force
            }

            #Set all files:
            ForEach ($file in $this.downloadFiles)
            {
                if (Test-Path -Path "$($this.DownloadPath)\$($file.Folder)\$($file.File)") {
                    Write-Verbose " $($file.Name) already present!"
                }
                else {
                    Write-Verbose " Creating $($file.Name) folder..."
                    New-Item -Path "$($this.DownloadPath)\$($file.Folder)" -ItemType Directory -Force
                    if ($file.URI -like "*/*") {
                        $this.WebClientDownload($file.URI, "$($this.DownloadPath)\$($file.Folder)\$($file.File)")
                    }
                    else {
                        $this.CopyFromSource("$($PSScriptRoot)\$($file.URI)", "$($this.DownloadPath)\$($file.Folder)\$($file.File)")
                        # Unpack APP-V client
                        if ($file.Name -eq "APPV51") {
                            Invoke-ExpandArchive -Source "$($this.DownloadPath)\$($file.Folder)\$($file.File)" -Target "$($this.DownloadPath)\$($file.Folder)"
                        }
                    }
                }
            }
        }
        else {
            $this.RemoveDirectory("")
        }

        Write-Verbose "MDT PreReqs set completed!"
    }

    [bool] Test()
    {
        Write-Verbose "Testing MDT PreReqs..."
        $present = $this.TestDownloadPath()

        if ($this.ensure -eq [Ensure]::Present)
        {            
            Write-Verbose " Testing for download path.."            
            if($present) {
                Write-Verbose " Download path found!"
            }            
            Else {
                Write-Verbose " Download path not found!"
                return $false
            }

            ForEach ($File in $this.downloadFiles)
            {
                 Write-Verbose " Testing for $($File.Name)..."
                 $present = (Test-Path -Path "$($this.DownloadPath)\$($File.Folder)\$($File.File)")
                 Write-Verbose " $present"
                 if(!$Present){return $false}
            }
        }
        else {
            if ($Present) {
               $present = $false 
            }
            else {
               $present = $true 
            }
        }

        Write-Verbose "Test completed!"
        return $present
    }

    [cMDTBuildPreReqs] Get()
    {
        return $this
    }

    [bool] TestDownloadPath()
    {
        $present = $false
        if (Test-Path -Path $this.DownloadPath -ErrorAction Ignore) {
            $present = $true
        }        
        return $present
    }

    [void] WebClientDownload($Source,$Target)
    {
        $WebClient = New-Object System.Net.WebClient
        Write-Verbose " Downloading file $($Source)"
        Write-Verbose " Downloading to $($Target)"
        $WebClient.DownloadFile($Source, $Target)
    }

    [void] CopyFromSource($Source,$Target)
    {
        Write-Verbose " Copying $($Target)"
        Copy-Item -Path $Source -Destination $Target
    }

    [void] RemoveDirectory($referencefile = "")
    {
        Remove-Item -Path $this.DownloadPath -Force -Verbose     
    }
}

[DscResource()]
class cMDTBuildSelectionProfile
{
    [DscProperty(Mandatory)]
    [Ensure]$Ensure

    [DscProperty(Key)]
    [string]$Name

    [DscProperty()]
    [string]$Comments

    [DscProperty(Mandatory)]
    [string]$IncludePath

    [DscProperty(Mandatory)]
    [string]$PSDriveName

    [DscProperty(Mandatory)]
    [string]$PSDrivePath

    [void] Set()
    {
        if ($this.ensure -eq [Ensure]::Present) {
            $this.ImportSelectionProfile()
        }
        else {
            Invoke-RemovePath -Path "$($this.PSDriveName):\Selection Profiles\$($this.name)" -PSDriveName $this.PSDriveName -PSDrivePath $this.PSDrivePath -Verbose
        }
    }

    [bool] Test()
    {
        $present = Invoke-TestPath -Path "$($this.PSDriveName):\Selection Profiles\$($this.name)" -PSDriveName $this.PSDriveName -PSDrivePath $this.PSDrivePath
        if ($this.Ensure -eq [Ensure]::Present) {
            return $present
        }
        else {
            return -not $present
        }
    }

    [cMDTBuildSelectionProfile] Get()
    {
        return $this
    }

    [void] ImportSelectionProfile()
    {
        Import-MicrosoftDeploymentToolkitModule
        New-PSDrive -Name $this.PSDriveName -PSProvider "MDTProvider" -Root $this.PSDrivePath -Verbose:$false
        New-Item -Path "$($this.PSDriveName):\Selection Profiles" -enable "True" -Name $this.Name -Comments $this.Comments -Definition "<SelectionProfile><Include path=`"$($this.IncludePath)`" /></SelectionProfile>" -ReadOnly "False" -Verbose
    }
}

[DscResource()]
class cMDTBuildTaskSequence
{

    [DscProperty(Mandatory)]
    [Ensure]$Ensure

    [DscProperty(Key)]
    [string]$Name

    [DscProperty(Key)]
    [string]$Path

    [DscProperty(Mandatory)]
    [string]$OSName

    [DscProperty(Mandatory)]
    [string]$Template

    [DscProperty(Mandatory)]
    [string]$ID

    [DscProperty(Mandatory)]
    [string]$OrgName

    [DscProperty(Mandatory)]
    [string]$PSDriveName

    [DscProperty(Mandatory)]
    [string]$PSDrivePath

    [void] Set()
    {
        if ($this.ensure -eq [Ensure]::Present) {
            $this.ImportTaskSequence()
        }
        else {
            Invoke-RemovePath -Path "$($this.path)\$($this.name)" -PSDriveName $this.PSDriveName -PSDrivePath $this.PSDrivePath -Verbose
        }
    }

    [bool] Test()
    {
        $present = Invoke-TestPath -Path "$($this.path)\$($this.name)" -PSDriveName $this.PSDriveName -PSDrivePath $this.PSDrivePath 
        if ($this.Ensure -eq [Ensure]::Present) {
            return $present
        }
        else {
            return -not $present
        }
    }

    [cMDTBuildTaskSequence] Get()
    {
        return $this
    }

    [void] ImportTaskSequence()
    {
        Import-MicrosoftDeploymentToolkitModule
        New-PSDrive -Name $this.PSDriveName -PSProvider "MDTProvider" -Root $this.PSDrivePath -Verbose:$false
        Import-MDTTaskSequence -path $this.Path -Name $this.Name -Template $this.Template -Comments "Build Reference Image" -ID $this.ID -Version "1.0" -OperatingSystemPath $this.OSName -FullName "Windows User" -OrgName $this.OrgName -HomePage "about:blank" -Verbose
        # Disable Windows autoupdate
        $UnattendXML = "$($this.PSDrivePath)\control\$($this.ID)\Unattend.xml"
        $unattend = Get-Content -Path $UnattendXML
        $unattend = $unattend.Replace('<ProtectYourPC>1','<ProtectYourPC>3')
        Set-Content -Path $UnattendXML -Value $unattend
    }
}

[DscResource()]
class cMDTBuildTaskSequenceCustomize
{
    # Task Sequence File
    [DscProperty(Key)]
    [string]$TSFile

    # Step name
    [DscProperty(Key)]
    [string]$Name

    # New step name
    [DscProperty()]
    [string]$NewName

    # Step type
    [DscProperty(Mandatory)]
    [string]$Type

    # Group for step
    [DscProperty(Mandatory)]
    [string]$GroupName

    # SubGroup for step
    [DscProperty()]
    [string]$SubGroup

    # Enable/Disable step
    [DscProperty()]
    [string]$Disable

    # Add this step after that step
    [DscProperty()]
    [string]$AddAfter

    # OS name for OS features
    [DscProperty()]
    [string]$OSName

    # OS features
    [DscProperty()]
    [string]$OSFeatures

    # Command line for 'Run Command line' step
    [DscProperty()]
    [string]$Command

    # Selection profile for 'Apply Patches' step
    [DscProperty()]
    [string]$SelectionProfile

    [DscProperty(Mandatory)]
    [string]$PSDriveName

    [DscProperty(Mandatory)]
    [string]$PSDrivePath

    [void] Set()
    {
        $TS = $this.LoadTaskSequence()
        
        # Set node:
        # $group - 1st level
        # $AddGroup - Group to add
        # $Step - Step (or Group) to add
        # $AfterStep - Insert after this step (may be null)
        $group = $TS.sequence.group | ?{$_.Name -eq $this.GroupName}
        if ($this.Type -eq "Group") {
            $step = $group.group | ?{$_.Name -eq $this.Name}
        }
        else {
            $step = $group.step | ?{$_.Name -eq $this.Name}
        }

        if ($this.SubGroup) {
            $AddGroup = $group.group | ?{$_.name -eq $this.SubGroup}
            $AfterStep = $addGroup.step | ?{$_.Name -eq $this.AddAfter}
        }
        else {
            $addGroup = $group
            $AfterStep = $group.step | ?{$_.Name -eq $this.AddAfter}
        }

        if ($step) {
            # Change existing step or group
            if ($this.Disable -ne "") {
                $step.disable = $this.Disable
            }
            if ($this.NewName -ne "") {
                $step.Name = $this.NewName
            }
            if ($this.SelectionProfile -ne "") {
                $step.defaultVarList.variable.'#text' = $this.SelectionProfile
            }
        }
        else {
            # Create new step or group
            if ($this.Type -eq "Group") {
                $newStep = $TS.CreateElement("group")
                $newStep.SetAttribute("expand", "true")
            }
            else {
                $newStep = $TS.CreateElement("step")
            }

            # Set common attributes
            $newStep.SetAttribute("name", $this.Name)
            if ($this.Disable -ne "") {
                $newStep.SetAttribute("disable", $this.Disable)
            }
            else {
                $newStep.SetAttribute("disable", "false")
            }
            $newStep.SetAttribute("continueOnError", "false")
            $newStep.SetAttribute("description", "")

            # Create new step
            switch ($this.Type) {
                "Install Roles and Features" {
                    $this.InstallRolesAndFeatures($TS, $newStep)
                }
                "Install Application" {
                    $this.AddApplication($TS, $newStep)
                }
                "Run Command Line" {
                    $this.RunCommandLine($TS, $newStep)
                }
                "Restart Computer" {
                    $this.RestartComputer($TS, $newStep)
                }
            }

            # Insert new step into TS
            if ($AfterStep) {
                $AddGroup.InsertAfter($newStep, $AfterStep) | Out-Null
            }
            else {
                $AddGroup.AppendChild($newStep) | Out-Null
            }
        }

        $TS.Save($this.TSFile)
    }

    [bool] Test()
    {
        $TS = $this.LoadTaskSequence()
        $present = $false

        $group = $TS.sequence.group | ?{$_.Name -eq $this.GroupName}
        if ($this.Type -eq "Group") {
            $step = $group.group | ?{$_.Name -eq $this.Name}
        }
        else {
            $step = $group.step | ?{$_.Name -eq $this.Name}
        }

        if (!$this.AddAfter) {
            if ($step) {
                if ($this.Disable -ne "") {
                    $present = ($step.disable -eq $this.Disable)
                }
                if ($this.SelectionProfile -ne "") {
                    $present = ($step.defaultVarList.variable.'#text' -eq $this.SelectionProfile)
                }
            }
            else {
                if ($this.NewName -ne "") {
                    # For rename "Custom Tasks" group only
                    $present = ( ($group.group | ?{$_.Name -eq $this.NewName}) -ne $null )
                }
                elseif ($this.SubGroup) {
                    $addGroup = $group.group | ?{$_.name -eq $this.SubGroup}
                    $present = ( ($addGroup.step | ?{$_.Name -eq $this.Name}) -ne $null )
                }
            }
        }
        else {
            if ($this.Type -eq "Group") {
                $present = ( ($group.group | ?{$_.Name -eq $this.Name}) -ne $null )
            }
            else {
                $AddGroup = $group
                if ($this.SubGroup) {
                    $AddGroup = $group.group | ?{$_.name -eq $this.SubGroup}
                }
                $present = ( ($addGroup.step | ?{$_.Name -eq $this.Name}) -ne $null )
            }
        }

        return $present
    }

    [cMDTBuildTaskSequenceCustomize] Get()
    {
        return $this
    }

    [xml] LoadTaskSequence()
    {
        $tsPath = $this.TSFile
        $xml = [xml](Get-Content $tsPath)
        return $xml
    }

    [void] InstallRolesAndFeatures($TS, $Step)
    {
        $OSIndex = @{
            "Windows 7"       = 4
            "Windows 8.1"     = 10
            "Windows 2012 R2" = 11
            "Windows 10"      = 13
        }

        $Step.SetAttribute("successCodeList", "0 3010")
        $Step.SetAttribute("type", "BDD_InstallRoles")
        $Step.SetAttribute("runIn", "WinPEandFullOS")
                        
        $varList = $TS.CreateElement("defaultVarList")
        $varName = $TS.CreateElement("variable")
        $varName.SetAttribute("name", "OSRoleIndex")
        $varName.SetAttribute("property", "OSRoleIndex")
        $varName.AppendChild($TS.CreateTextNode($OSIndex.$($this.OSName))) | Out-Null
        $varList.AppendChild($varName) | Out-Null

        $varName = $TS.CreateElement("variable")
        $varName.SetAttribute("name", "OSRoles")
        $varName.SetAttribute("property", "OSRoles")
        $varList.AppendChild($varName) | Out-Null

        $varName = $TS.CreateElement("variable")
        $varName.SetAttribute("name", "OSRoleServices")
        $varName.SetAttribute("property", "OSRoleServices")
        $varList.AppendChild($varName) | Out-Null

        $varName = $TS.CreateElement("variable")
        $varName.SetAttribute("name", "OSFeatures")
        $varName.SetAttribute("property", "OSFeatures")
        $varName.AppendChild($TS.CreateTextNode($this.OSFeatures)) | Out-Null
        $varList.AppendChild($varName) | Out-Null

        $action = $TS.CreateElement("action")
        $action.AppendChild($TS.CreateTextNode('cscript.exe "%SCRIPTROOT%\ZTIOSRole.wsf"')) | Out-Null

        $Step.AppendChild($varList) | Out-Null
        $Step.AppendChild($action) | Out-Null
    }

    [void] AddApplication($TS, $Step)
    {
        $Step.SetAttribute("successCodeList", "0 3010")
        $Step.SetAttribute("type", "BDD_InstallApplication")
        $Step.SetAttribute("runIn", "WinPEandFullOS")
                    
        $varList = $TS.CreateElement("defaultVarList")
        $varName = $TS.CreateElement("variable")
        $varName.SetAttribute("name", "ApplicationGUID")
        $varName.SetAttribute("property", "ApplicationGUID")

        # Get Application GUID
        Import-MicrosoftDeploymentToolkitModule
        New-PSDrive -Name $this.PSDriveName -PSProvider "MDTProvider" -Root $this.PSDrivePath -Verbose:$false | Out-Null
        $App = Get-ChildItem -Path "$($this.PSDriveName):\Applications" -Recurse | ?{ $_.Name -eq  $this.Name }

        $varName.AppendChild($TS.CreateTextNode($($App.guid))) | Out-Null
        $varList.AppendChild($varName) | Out-Null
                        
        $varName = $TS.CreateElement("variable")
        $varName.SetAttribute("name", "ApplicationSuccessCodes")
        $varName.SetAttribute("property", "ApplicationSuccessCodes")
        $varName.AppendChild($TS.CreateTextNode("0 3010")) | Out-Null
        $varList.AppendChild($varName) | Out-Null

        $action = $TS.CreateElement("action")
        $action.AppendChild($TS.CreateTextNode('cscript.exe "%SCRIPTROOT%\ZTIApplications.wsf"')) | Out-Null

        $Step.AppendChild($varList) | Out-Null
        $Step.AppendChild($action) | Out-Null
    }

    [void] RunCommandLine($TS, $Step)
    {
        $Step.SetAttribute("startIn", "")
        $Step.SetAttribute("successCodeList", "0 3010")
        $Step.SetAttribute("type", "SMS_TaskSequence_RunCommandLineAction")
        $Step.SetAttribute("runIn", "WinPEandFullOS")

        $varList = $TS.CreateElement("defaultVarList")
        $varName = $TS.CreateElement("variable")
        $varName.SetAttribute("name", "PackageID")
        $varName.SetAttribute("property", "PackageID")
        $varList.AppendChild($varName) | Out-Null

        $varName = $TS.CreateElement("variable")
        $varName.SetAttribute("name", "RunAsUser")
        $varName.SetAttribute("property", "RunAsUser")
        $varName.AppendChild($TS.CreateTextNode("false")) | Out-Null
        $varList.AppendChild($varName) | Out-Null

        $varName = $TS.CreateElement("variable")
        $varName.SetAttribute("name", "SMSTSRunCommandLineUserName")
        $varName.SetAttribute("property", "SMSTSRunCommandLineUserName")
        $varList.AppendChild($varName) | Out-Null

        $varName = $TS.CreateElement("variable")
        $varName.SetAttribute("name", "SMSTSRunCommandLineUserPassword")
        $varName.SetAttribute("property", "SMSTSRunCommandLineUserPassword")
        $varList.AppendChild($varName) | Out-Null

        $varName = $TS.CreateElement("variable")
        $varName.SetAttribute("name", "LoadProfile")
        $varName.SetAttribute("property", "LoadProfile")
        $varName.AppendChild($TS.CreateTextNode("false")) | Out-Null
        $varList.AppendChild($varName) | Out-Null

        $action = $TS.CreateElement("action")
        $action.AppendChild($TS.CreateTextNode($this.Command)) | Out-Null

        $Step.AppendChild($varList) | Out-Null
        $Step.AppendChild($action) | Out-Null
    }

    [void] RestartComputer($TS, $Step)
    {
        $Step.SetAttribute("successCodeList", "0 3010")
        $Step.SetAttribute("type", "SMS_TaskSequence_RebootAction")
        $Step.SetAttribute("runIn", "WinPEandFullOS")

        $varList = $TS.CreateElement("defaultVarList")
        $varName = $TS.CreateElement("variable")
        $varName.SetAttribute("name", "Message")
        $varName.SetAttribute("property", "Message")
        $varList.AppendChild($varName) | Out-Null

        $varName = $TS.CreateElement("variable")
        $varName.SetAttribute("name", "MessageTimeout")
        $varName.SetAttribute("property", "MessageTimeout")
        $varName.AppendChild($TS.CreateTextNode("60")) | Out-Null
        $varList.AppendChild($varName) | Out-Null

        $varName = $TS.CreateElement("variable")
        $varName.SetAttribute("name", "Target")
        $varName.SetAttribute("property", "Target")
        $varList.AppendChild($varName) | Out-Null

        $action = $TS.CreateElement("action")
        $action.AppendChild($TS.CreateTextNode("smsboot.exe /target:WinPE")) | Out-Null

        $Step.AppendChild($varList) | Out-Null
        $Step.AppendChild($action) | Out-Null
    }
}

[DscResource()]
class cMDTBuildUpdateBootImage
{
    [DscProperty(Key)]
    [string]$Version

    [DscProperty(Key)]
    [string]$PSDeploymentShare

    [DscProperty(Mandatory)]
    [string]$PSDrivePath

    [DscProperty()]
    [string]$ExtraDirectory

    [DscProperty()]
    [string]$BackgroundFile

    [DscProperty()]
    [string]$LiteTouchWIMDescription
      
    [void] Set()
    {
        $this.UpdateBootImage()
    }

    [bool] Test()
    {
        Return ($this.VerifyVersion())
    }

    [cMDTBuildUpdateBootImage] Get()
    {
        return $this
    }

    [bool] VerifyVersion()
    {
        [bool]$match = $false

        if ((Get-Content -Path "$($this.PSDrivePath)\Boot\CurrentBootImage.version" -ErrorAction Ignore) -eq $this.Version) {
            $match = $true
        }
        return $match
    }

    [void] UpdateBootImage()
    {
        Import-MicrosoftDeploymentToolkitModule
        New-PSDrive -Name $this.PSDeploymentShare -PSProvider "MDTProvider" -Root $this.PSDrivePath -Verbose:$false

        If ([string]::IsNullOrEmpty($($this.ExtraDirectory))) {
            Set-ItemProperty "$($this.PSDeploymentShare):" -Name Boot.x64.ExtraDirectory -Value ""
            Set-ItemProperty "$($this.PSDeploymentShare):" -Name Boot.x86.ExtraDirectory -Value ""
        }
        ElseIf (Invoke-TestPath -Path "$($this.PSDrivePath)\$($this.ExtraDirectory)") {
            Set-ItemProperty "$($this.PSDeploymentShare):" -Name Boot.x64.ExtraDirectory -Value "$($this.PSDrivePath)\$($this.ExtraDirectory)"                        
            Set-ItemProperty "$($this.PSDeploymentShare):" -Name Boot.x86.ExtraDirectory -Value "$($this.PSDrivePath)\$($this.ExtraDirectory)"                       
        }

        If ([string]::IsNullOrEmpty($($this.BackgroundFile))) {
            Set-ItemProperty "$($this.PSDeploymentShare):" -Name Boot.x64.BackgroundFile -Value ""
            Set-ItemProperty "$($this.PSDeploymentShare):" -Name Boot.x86.BackgroundFile -Value ""
        }
        ElseIf (Invoke-TestPath -Path "$($this.PSDrivePath)\$($this.BackgroundFile)") {
             Set-ItemProperty "$($this.PSDeploymentShare):" -Name Boot.x64.BackgroundFile -Value "$($this.PSDrivePath)\$($this.BackgroundFile)"
             Set-ItemProperty "$($this.PSDeploymentShare):" -Name Boot.x86.BackgroundFile -Value "$($this.PSDrivePath)\$($this.BackgroundFile)"
        }
        Else {
             Set-ItemProperty "$($this.PSDeploymentShare):" -Name Boot.x64.BackgroundFile -Value $this.BackgroundFile
             Set-ItemProperty "$($this.PSDeploymentShare):" -Name Boot.x86.BackgroundFile -Value $this.BackgroundFile
        }

        If ($this.LiteTouchWIMDescription) {
            Set-ItemProperty "$($this.PSDeploymentShare):" -Name Boot.x64.LiteTouchWIMDescription -Value "$($this.LiteTouchWIMDescription) x64 $($this.Version)"
            Set-ItemProperty "$($this.PSDeploymentShare):" -Name Boot.x86.LiteTouchWIMDescription -Value "$($this.LiteTouchWIMDescription) x86 $($this.Version)"
            Set-ItemProperty "$($this.PSDeploymentShare):" -Name Boot.x64.LiteTouchISOName -Value "$($this.LiteTouchWIMDescription)_x64.iso".Replace(' ','_')
            Set-ItemProperty "$($this.PSDeploymentShare):" -Name Boot.x86.LiteTouchISOName -Value "$($this.LiteTouchWIMDescription)_x86.iso".Replace(' ','_')
        }

        Set-ItemProperty "$($this.PSDeploymentShare):" -Name Boot.x64.SelectionProfile -Value "Nothing"
        Set-ItemProperty "$($this.PSDeploymentShare):" -Name Boot.x86.SelectionProfile -Value "Nothing"

        Set-ItemProperty "$($this.PSDeploymentShare):" -Name Boot.x64.GenerateLiteTouchISO -Value $false
        Set-ItemProperty "$($this.PSDeploymentShare):" -Name Boot.x86.GenerateLiteTouchISO -Value $true

        #The Update-MDTDeploymentShare command crashes WMI when run from inside DSC. This section is a work around.

        <# Old style is hard
        $aPSDeploymentShare = $this.PSDeploymentShare
        $aDeploymentSharePath = $this.DeploymentSharePath
        $aForce = $this.Force
        $aCompress = $this.Compress
        $jobArgs = @($aPSDeploymentShare,$aDeploymentSharePath,$aForce,$aCompress)
 
        $job = Start-Job -Name UpdateMDTDeploymentShare -Scriptblock {
            Import-Module "$env:ProgramFiles\Microsoft Deployment Toolkit\Bin\MicrosoftDeploymentToolkit.psd1" -ErrorAction Stop -Verbose:$false
            New-PSDrive -Name $args[0] -PSProvider "MDTProvider" -Root $args[1] -Verbose:$false
            Update-MDTDeploymentShare -Path "$($args[0]):" -Force:$args[2] -Compress:$args[3]
        } -ArgumentList $jobArgs
 
        $job | Wait-Job -Timeout 900
        $timedOutJobs = Get-Job -Name UpdateMDTDeploymentShare | Where-Object {$_.State -eq 'Running'} | Stop-Job -PassThru
 
        If ($timedOutJobs) {
            Write-Error "Update-MDTDeploymentShare job exceeded timeout limit of 900 seconds and was aborted"
        }
        Else {
            Set-Content -Path "$($this.DeploymentSharePath)\Boot\CurrentBootImage.version" -Value "$($this.Version)"
        }
        #>


        workflow Update-DeploymentShare {
            [CmdletBinding()]
            param (
                [string]$PSDeploymentShare,
                [string]$PSDrivePath
            )
            InlineScript {
                Import-MicrosoftDeploymentToolkitModule
                New-PSDrive -Name $Using:PSDeploymentShare -PSProvider "MDTProvider" -Root $Using:PSDrivePath -Verbose:$false
                Update-MDTDeploymentShare -Path "$($Using:PSDeploymentShare):" -Force:$true -Compress:$true
            }
        }
        Update-DeploymentShare $this.PSDeploymentShare $this.PSDrivePath
        Set-Content -Path "$($this.PSDrivePath)\Boot\CurrentBootImage.version" -Value "$($this.Version)"
    }
}

Function Import-MicrosoftDeploymentToolkitModule
{
    If ( -Not (Get-Module MicrosoftDeploymentToolkit) ) {
        Import-Module "$env:ProgramFiles\Microsoft Deployment Toolkit\Bin\MicrosoftDeploymentToolkit.psd1" -ErrorAction Stop -Global -Verbose:$False
    }
}

Function Invoke-ExpandArchive
{
    [CmdletBinding()]
    [OutputType([bool])]
    param(
        [Parameter(Mandatory=$True)]
        [ValidateNotNullorEmpty()]
        [string]$Source,
        [Parameter(Mandatory=$True)]
        [ValidateNotNullorEmpty()]
        [string]$Target
    )

    [bool]$Verbosity
    If ($PSBoundParameters.Verbose) { $Verbosity = $True }
    Else { $Verbosity = $False }

    Write-Verbose "Expanding archive $($Source) to $($Target)"
    Expand-Archive $Source -DestinationPath $Target -Force -Verbose:$Verbosity
}

Function Invoke-RemovePath
{
    [CmdletBinding()]
    [OutputType([bool])]
    param(
        [Parameter(Mandatory=$True)]
        [ValidateNotNullorEmpty()]
        [string]$Path,
        [Parameter()]
        [string]$PSDriveName,
        [Parameter()]
        [string]$PSDrivePath
    )

    [bool]$Verbosity
    If ($PSBoundParameters.Verbose) { $Verbosity = $True }
    Else { $Verbosity = $False }

    if (($PSDrivePath) -and ($PSDriveName)) {
        Import-MicrosoftDeploymentToolkitModule
        New-PSDrive -Name $PSDriveName -PSProvider "MDTProvider" -Root $PSDrivePath -Verbose:$False | `
        Remove-Item -Path "$($Path)" -Force -Verbose:$Verbosity
    }
    else {
        Remove-Item -Path "$($Path)" -Force -Verbose:$Verbosity
    }
}

Function Invoke-TestPath
{
    [CmdletBinding()]
    [OutputType([bool])]
    param(
        [Parameter(Mandatory=$True)]
        [ValidateNotNullorEmpty()]
        [string]$Path,
        [Parameter()]
        [string]$PSDriveName,
        [Parameter()]
        [string]$PSDrivePath
    )

    [bool]$present = $false

    if (($PSDrivePath) -and ($PSDriveName)) {
        Import-MicrosoftDeploymentToolkitModule
        if (New-PSDrive -Name $PSDriveName -PSProvider "MDTProvider" -Root $PSDrivePath -Verbose:$false | `
            Test-Path -Path "$($Path)" -ErrorAction Ignore) {
            $present = $true
        }        
    }
    else {
        if (Test-Path -Path "$($Path)" -ErrorAction Ignore) {
            $present = $true
        }
    }
    return $present
}