Find an unused drive letter

Your task is to write the shortest code to find one of the unused drive letters (excluding a,b and c). PowerShell’s default aliases are allowed. You have one week.  Answers should be posted as a comment to this brain teaser. That’s it.


The winner gets a copy of  the “VMware vSphere PowerCLI Reference” from Sybex!

We’ll post clues over the next couple days, stay tuned.

Good Luck!

 

[UPDATE] 1/23/2012

We have a winner: P!
Your code was 36 characters long:

for($j=67;gdr($d=[char]++$j)2>0){}$d

This is the breakdown of our solution (47 characters):

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

We took a different approach (though more lengthy) to get a list of available by listing the default A-Z functions and using the Name switch to get the names only.
We then tested if a drive with the incoming drive letter name was available, if so, it was written back to the pipeline.
Finally, we used the Get-Random cmdlet to choose for us an available letter. As you can see we called Get-Random by its verb only. You may suspect that ‘random’ is an alias for that command but it isn’t. We used a known trick to shorten Get-Random – when PowerShell cannot resolve a command it tries to resolve it again by prepending the Get verb.

We hope you had fun and that you enjoyed participating and was able to learn a thing or two. See you in the next brain teaser.
We also would like to thanks our sponsors, Sybex, for giving away the book for the Winner.

 

About the author: Shay Levy

Shay Levy is a Co-founder and editor of the PowerShell Magazine. He is a multiple-year recipient of the Microsoft MVP award, and a Microsoft Certified Trainer (MCT). Shay often covers PowerShell related topics on his blog and you can also follow him on Twitter at @ShayLevy

Related Posts

36 Comments

  1. seems to work just fine for me… good job!

    PS C:UsersJeffrey> [char[]](68..90)|?{!(gdr $_ -ea 0)}FGHIJKLMNOPQRSTUVWXYZPS C:UsersJeffrey>

  2. Get-PSDrive is not showing hidden drives (for example the one for AppV client), so had to use WMI. Running XP, so can’t use Win32_Volume:

    ([char[]](68..90)|?{@(gwmi win32_LogicalDisk|%{($_.deviceid)[0]}) -notcontains $_})[0]

    BTW – I like the idea of short contests (not necessary with prizes). But please – not on Friday when I am busy in the office :))

  3. Hey all

    Thanks for participating, you rock! A few comments and clarifications:

    1. Your answer should not generate an error.

    2. You need to output just one drive letter (with or without a colon).

    3. @jrich, the following is 40 char long, not 38 (and if you’re out of letters it may fail):  
    ([char[]](68..90)|?{!(gdr $_ -ea 0)})[0]

    4. @makovec, initially we didn’t think about AppV drives so we can’t change the requirements now 🙂

    5. Our one-liner answer is 47 characters  long.

    6. Keep’em coming!

  4. Other ideas:

    ([char[]](68..90)|?{@(mountvol|Select-string “[A-Z]:\”|%{$_.toString().Trim()[0]}) -notcontains $_})[0]
    ([char[]](68..90)|?{@([system.io.DriveInfo]::GetDrives()|%{($_.Name)[0]}) -notcontains $_})[0]
    ([char[]](68..90)|?{@([io.Directory]::GetLogicalDrives()|%{($_)[0]}) -notcontains $_})[0]
    ([char[]](68..90)|?{@([io.DriveInfo]::GetDrives()|%{($_.Name)[0]}) -notcontains $_})[0]
    ([char[]](68..90)|?{@(wmic logicaldisk get name|%{($_)[0]}) -notcontains $_})[0]
    net use ((((net use * \DCsysvol) -split “`n”)[0]).substring(6,1)+”:”) /d
    # based on: http://powershell.com/cs/blogs/tips/archive/2009/10/21/find-next-available-drive-letter.aspx
    (68..90|%{“$([char]$_):”}|?{([IO.DriveInfo]$_).DriveType -eq ‘noRootdirectory’})[0]
    [char]([int][char](gdr -PS FileSystem)[-1].Name+1)

  5. # 37 chars:
    for($j=67;gdr($d=[char]++$j)2>$e){}$d

    # pipeline approach, 38 chars:
    ([char[]](68..90)|?{!(gdr $_)})[0]2>$e

  6. IMO gdr can lead to wrong results… prefer WMI/ .NET solutions. I just created ‘E’ drive that points to my registry and most of scripts here show F as first available letter. 😉 Solutions that assume that first available = next in alphabet after last used fail miserably, because I have virtual cd ‘Z’ 😉
    My 2 attempts (I admit, I was using Emim’s ideas a lot:
    ([char[]](68..90)|?{!((gwmi cim_logicaldisk)-match”=.$_”)})[0]
    ([char[]](68..90)|?{!([io.driveinfo]::GetDrives()-match$_)})[0]

    This code is awful to read (kill me for using -match in such a way, I deserve it ;)).
    And most likely has other flaws that in turn I missed. :>

    1. Unless otherwise indicated, brainteasers – and their solutions – should be set in a common and leveled field, i.e. a non-profile powershell session. Having said that, I don’t think many systems would have ‘Z’ logical drive by default

Comments are closed.

%d bloggers like this: