cMoveCDRom.psm1

[DscResource()]
class cMoveCDRom
{
    <#
        This property is the name of the system - its not used for anything
        other than they key.
    #>

    [DscProperty(Key)]
    [string]$Name

    [DscProperty(Mandatory)]
    [string]$CDRomDriveLetter

    <#
        This method is equivalent of the Get-TargetResource script function.
        The implementation should use the keys to find appropriate resources.
        This method returns an instance of this class with the updated key
         properties.
    #>

    [cMoveCDRom] Get()
    {
        $this.Name = $Env:COMPUTERNAME
        #This is the default PartitionType
        $CurCDRomLetter = $this.GetCDROMDriveLetter()
        if ($CurCDRomLetter -eq $null) {
            $this.CDRomDriveLetter = "";            
        } else {
            $this.CDRomDriveLetter = $this.GetCDROMDriveLetter()
        }
        return $this
    }

    <#
        This method is equivalent of the Test-TargetResource script function.
        It should return True or False, showing whether the resource
        is in a desired state.
    #>

    [bool] Test()
    {
        try {
            Write-Verbose "cMoveCDRom:Test - Start"
            $TestResult = $false
            
            $this.CDRomDriveLetter = $this.ValidateDriveLetter($this.CDRomDriveLetter)
            $CurCDRomLetter = $this.GetCDROMDriveLetter()
            if ($CurCDRomLetter -eq $null -or $CurCDRomLetter -eq "") {
                Write-Verbose ("cMoveCDRom:Test - No CDRom - nothing to do.")
                $TestResult = $True
            } else {
                Write-Verbose ("cMoveCDRom:Test - CDRom Currently '" + $CurCDRomLetter + "'")
                Write-Verbose ("cMoveCDRom:Test - CDRom Desired State '" + $this.CDRomDriveLetter + "'")
    
                If ($this.CDRomDriveLetter -eq $CurCDRomLetter) {
                    $TestResult = $True
                }
            }

            return $TestResult
        } finally {
            Write-Verbose "cMoveCDRom:Test - End"
        }
    }

    <#
        This method is equivalent of the Set-TargetResource script function.
        It sets the resource to the desired state.
    #>

    [void] Set()
    {
        try {
            Write-Verbose "cMoveCDRom:Set - Start"

            $this.CDRomDriveLetter = $this.ValidateDriveLetter($this.CDRomDriveLetter)
            $CurCDRomLetter = $this.GetCDROMDriveLetter()
            $CDRom = Get-WmiObject -Class Win32_Volume -Filter "DriveLetter='$CurCDRomLetter'" -ErrorAction Stop
            Write-Verbose ("cMoveCDRom:Set - Changing CDRom from '" + $CurCDRomLetter + "' to '" + $this.CDRomDriveLetter + "'")
            Set-WmiInstance -InputObject $CDRom -Arguments @{DriveLetter=$this.CDRomDriveLetter} -ErrorAction Stop | Out-Null            
        } finally {
            Write-Verbose "cMoveCDRom:Set - End"
        }
    }

    <#
        Helper method to get the CDRom Drive letter
    #>

    [string] GetCDROMDriveLetter()
    {
        $DriveLetter = $null
        $CDROM = Get-WmiObject -Class Win32_cdromdrive
        if ($CDROM -ne $null) {
            $DriveLetter = $CDROM.drive
        } else {
            $DriveLetter = ""
        }
        return $DriveLetter
    }


    <#
        Validates drive letter
    #>

    [string] ValidateDriveLetter([string] $DriveLetter) 
    {
        Write-Debug ("ValidateDriveLetter - Start - '$DriveLetter'")
        try {
            #WMI always requires format X:
            If ($DriveLetter -match "^[a-z]$" ) {
                $DriveLetter = $DriveLetter.ToUpper() + ":"
            } elseif ($DriveLetter -match "^[a-z]:$" ) {
                $DriveLetter = $DriveLetter.ToUpper()
            } else {
                throw "CDRomDriveLetter must in the form [A-Z] or [A-Z]: i.e. 'T' or 'T:' "
            }
            return $DriveLetter  
        } finally {
            Write-Debug ("ValidateDriveLetter - End")
        }        
    }
}