Changing CDrom drive letter on Windows 2012

One of my colleague asked the other day how he could change the CDrom drive letter on Windows 2012 core edition.
I noticed recently that we were not the only ones complaining about that, see http://mssecbyben.wordpress.com/2012/06/14/howto-install-a-new-domain-on-server-2012-core/

Of course, old ways of doing it are still working. I mean that you can do it using diskpart.exe (the command line disk management utility) or using mountvol.exe.
But these two utility have some limitations in automation especially when you’ve more than one CD drive on the computer.

As we were on Windows 2012, I immediately started to look for the new promising powershell cmdlets that aim to replace the diskpart utility. I was a little bit disappointed when I saw that you actually couldn’t change easily the CDrom drive letter :-(

So I start using WMI as I was 100% sure that we could differentiate volume types. All I needed was to find the appropriate method to change the letter. WMI was the best approach as it could also easily target remote computers.

Then I realized that I needed to find out what letters were available. I recalled the nice brainteaser Shay Levy proposed on January where we should find unsused drive letters. http://www.powershellmagazine.com/2012/01/12/find-an-unused-drive-letter As bright as the 2 winning solutions are, they both have a huge drawback as they run only locally and are not using WMI. Fortunately, @Makovec proposed a WMI based solution that perfectly meets my requirements.

Here is the new function for this purpose:

Function Set-CDRomLetter             
{            
    [CmdletBinding()]            
    param(            
     [Parameter(Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]            
     [Alias("CN","__SERVER","IPAddress")]            
     [string[]]$ComputerName=$Env:Computername,            
            
        [parameter()]            
        [Alias('RunAs')]            
        [System.Management.Automation.Credential()]$Credential = [System.Management.Automation.PSCredential]::Empty,            
            
        [Parameter(ParameterSetName='Any', Mandatory=$false, Position=1)]            
        [System.Management.Automation.SwitchParameter]${NextAvailableLetter},            
            
        [Parameter(ParameterSetName='This', Mandatory=$false, Position=1)]            
        [ValidatePattern('^[A-Za-z]$')]            
        [System.String]${SetDriveLetter}            
    )            
            
    Begin            
    {            
        $usercontext = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()            
        $IsAdmin = $usercontext.IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")                               
            
        if (-not($IsAdmin))            
        {            
            Write-Warning "Must run powerShell as Administrator to perform these actions"            
            return            
        }             
            
        # Prepare HT            
        $wmiHT = @{            
            Class = "Win32_Volume"            
            ErrorAction = "Stop"            
            Filter = 'DriveType = 5'            
        }      


#Supplied Alternate Credentials?            
        If ($PSBoundParameters['Credential']) {            
            $wmiHT.credential = $Credential            
        }

}
Process
{
$ComputerName | ForEach-Object -Process {
$Computer = $_
If ($Computer -eq $Env:Computername)
{
$wmiHT.remove('Credential')
} Else {
$wmiHT += @{Computername = $Computer}
}

try
{
$CDRomAr = Get-WmiObject @wmiHT
} catch {
Write-Warning -Message "Failed to query Win32_Volume on computer $Computer"

}
if ($CDRomAr)
{
$CDRomAr | ForEach-Object -Process {
$CDobj = $_
$wmiHT.remove('Filter')
$wmiHT.remove('Class')
$wmiHT += @{ Class = "win32_LogicalDisk" }
try
{
$AllLetters = Get-WmiObject @wmiHT
} catch {
Write-Warning -Message "Failed to query all volumes letters on computer $Computer"
return
}
if ($AllLetters)
{
$NextLetters = ([char[]](68..90)| Where-Object -FilterScript {
($AllLetters | ForEach-Object -Process {
($_.deviceid)[0]
}) -notcontains $_
})
if ($NextLetters)
{
Write-Verbose -Message "Next letter available being calculated is $($NextLetters[0])"
# Set-it
switch ($PsCmdlet.ParameterSetName)
{
Any {
# Pick-up the next one
try
{
Set-WmiInstance -InputObject $CDobj -Arguments @{DriveLetter = "$($NextLetters[0]):" } | Out-Null
Write-Verbose -Message "CDRom letter on computer $Computer set to next available letter $($NextLetters[0]):" -Verbose
} catch {
Write-Warning -Message "Failed to set the CDrom letter on computer $Computer"
}
}
This {
# Ensure that the drive letter chosen is available
if ((-join $NextLetters) -match $SetDriveLetter)
{
try
{
Set-WmiInstance -InputObject $CDobj -Arguments @{DriveLetter = "$($SetDriveLetter):" } | Out-Null
Write-Verbose -Message "CDRom letter on computer $Computer set to $($SetDriveLetter):" -Verbose
} catch {
Write-Warning -Message "Failed to set the CDrom letter on computer $Computer"
}
} else {
Write-Warning -Message "Chosen drive letter isn't available on computer $Computer"
}
}
} # end of switch

} else {
Write-Warning -Message "Failed to get the next available letter"
}
}
}
} else {
Write-Verbose -Message "CDRom not present on computer $Computer" -Verbose
}
}
}
End {}

} # end of function

About these ads

3 thoughts on “Changing CDrom drive letter on Windows 2012

  1. Sorry this is far to complicated!

    list volume
    select volume 1 ,2,3,4,5 what ever your DCROM Drive ist…
    remove letter=D “for exmple”
    assign letter=L “for exmple”

    Have a nice day!
    :-)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s