Getting a free drive letter

At PowerShell Magazine, we ran a brain teaser contest to find out the shortest answer to your question. Check this:

http://www.powershellmagazine.com/2012/01/12/find-an-unused-drive-letter/

There are several answers but here is my fav one:

ls function:[d-z]: -n | ?{ !(test-path $_) } | random

I like this way, for the following reasons:

  1. It doesn't require WMI, just regular powershell cmdlets
  2. It is very clear and easy to read
  3. It easily allows you to exclude specific driveletters
  4. It easily allows you to order the driveletters in any order you would like
  5. It finds the first non used driveletter and maps it, and then it is finished.

    $share="\\Server\Share"
    $drvlist=(Get-PSDrive -PSProvider filesystem).Name
    Foreach ($drvletter in "DEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray()) {
        If ($drvlist -notcontains $drvletter) {
            $drv=New-PSDrive -PSProvider filesystem -Name $drvletter -Root $share
            break
        }
    }
    

My two cents:

get-wmiobject win32_logicaldisk | select -expand DeviceID -Last 1 | 
% { [char]([int][char]$_[0]  + 1) + $_[1] }

Range of valid [CHAR] is 68..90, adding a check if [char]$_[0] -gt 90 avoid unexpected results. In case some unit is a mapped network drive it return always the major successive, ex.:

c: system drive
d: cd/dvd
r: network mapped drive

the command return s: and not e: as [string]

This give the first free drive letter ( a little ugly.. someone can do it better IMO):

$l = get-wmiobject win32_logicaldisk | select -expand DeviceID  | % { $_[0] }
$s = [int][char]$l[0]
foreach ( $let in $l )
{
    if ([int][char]$let -ne $s)
    {
        $ret = [char]$s +":"
        break
    }

    $s+=1    
}
$ret 

Here's what I came up with. I need the last available drive letter from A to Z.

$AllLetters = 65..90 | ForEach-Object {[char]$_ + ":"}
$UsedLetters = get-wmiobject win32_logicaldisk | select -expand deviceid
$FreeLetters = $AllLetters | Where-Object {$UsedLetters -notcontains $_}
$FreeLetters | select-object -last 1
  • This gets an array of letters A..Z
  • Then gets an array of the letters already in use from WMI
  • Next produces an array of letters not in use using the comparison operator -notcontains
  • Finally outputs a single letter.

Tags:

Powershell