获得免费的驱动器号

时间:2012-09-19 03:09:02

标签: powershell

我在this answer中看到了Get-NextFreeDrive函数,我想知道是否有更有效的方法来执行此操作。即使已经找到一个免费的驱动器号,链接的答案中的函数似乎仍然会遍历所有字母。

10 个答案:

答案 0 :(得分:21)

在PowerShell杂志上,我们举办了一场脑筋急转弯竞赛,以找出问题的最短答案。检查一下:

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

有几个答案,但这里是我最喜欢的答案:

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

答案 1 :(得分:4)

我的两分钱:

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

有效[CHAR]的范围是68..90,如果[char]$_[0] -gt 90可以避免意外结果,请添加一项检查。 如果某个单元是映射的网络驱动器,它总是返回主要的连续,例如:

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

命令返回s:而不是e:为[string]

这给了第一个免费的驱动器号(有点难看......有人可以做得更好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 

答案 2 :(得分:3)

我喜欢这种方式,原因如下:

  1. 它不需要WMI,只需要常规的PowerShell cmdlet
  2. 非常清晰易读
  3. 它可以轻松地排除特定的驱动器
  4. 您可以轻松地按照您想要的任何顺序订购驱动器
  5. 它找到第一个未使用的驱动器并映射它,然后它就完成了。

    $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
        }
    }
    

答案 3 :(得分:1)

这就是我想出的。我需要从A到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
  • 这会得到一个字母数组A..Z
  • 然后从WMI
  • 获取已使用的字母数组
  • Next使用比较运算符-notcontains
  • 生成一个未使用的字母数组
  • 最后输出一个字母。

答案 4 :(得分:1)

$taken = Get-WmiObject Win32_LogicalDisk | Select -expand DeviceID
$letter = 65..90 | ForEach-Object{ [char]$_ + ":" }
(Compare-Object -ReferenceObject $letter -DifferenceObject $taken)[1].InputObject

只是为了刮胡子额外的代码行(lol)。如果你想要变得粗鲁,你可以跳过实例化变量并直接将它们直接传递到-Ref和-Diff中,但是可能应该为此做好准备。 :)

选择[1]以避免获取A:驱动器以防万一可能使问题复杂化。

答案 5 :(得分:1)

我必须编写一个与Powershell V2.0一起使用的函数。 以下函数将返回下一个可用字母,它还可以将排除字母作为参数:

Function AvailableDriveLetter ()
{
param ([char]$ExcludedLetter)
$Letter = [int][char]'C'
$i = @()
#getting all the used Drive letters reported by the Operating System
$(Get-PSDrive -PSProvider filesystem) | %{$i += $_.name}
#Adding the excluded letter
$i+=$ExcludedLetter
while($i -contains $([char]$Letter)){$Letter++}
Return $([char]$Letter)
}

让我们说你的操作系统报告驱动器字母C:,E:,F:和G:正在使用。

正在运行: $ First = AvailableDriveLetter ,将导致$ First包含' D'

正在运行: $ Sec = AvailableDriveLetter -ExcludedLetter $ First ,将导致$ Sec包含' H'

答案 6 :(得分:1)

另一种方式......

$DriveList = Get-PSDrive -PSProvider filesystem | foreach({($_.Root).Replace(":\","")})
$AllDrives = [char[]]([int][char]'E'..[int][char]'Z')
$NextDriveLetter = ($AllDrives | Where-Object { $DriveList -notcontains $_ } | Select-Object -First 1) + ":"

答案 7 :(得分:1)

我发现自己的成本是当前接受的答案(ls function:[dz]:-n |?{!(test-path $ _)} | random)确实可以返回的东西像CD驱动器。

我已经将这个驱动器从阵列中排除了任何本地驱动器:

job2

它将返回第一个可用的字母。如果您不喜欢上一封可用的信件,只需将"$([char[]]([char]'D'..[char]'Z')|Where-Object {((Get-WmiObject -Class Win32_LogicalDisk).DeviceID).replace(':','') -notcontains $_ }|Select-Object -first 1):" 更改为Select-Object -first 1

即可

答案 8 :(得分:0)

我发现Test-Path将我的空CD-Drive评估为False,这是另一种替代方法,它将比较alphabeth中的每个字母,直到找到文件系统中不存在的字母,然后将该驱动器作为输出返回。

$DriveLetter = [int][char]'C'
WHILE((Get-PSDrive -PSProvider filesystem).Name -contains [char]$DriveLetter){$DriveLetter++}
Write-Host "$([char]$Driveletter):"

答案 9 :(得分:0)

这似乎有点像“我也是”答案,但是我注意到所有其他答案都使用-contains-notcontains,而我只是不喜欢那些解决方案。因此,这可能不是很有效,但是我更喜欢它。这段代码(对我而言)的目的是找到可用于创建驱动器映射的第一个驱动器。

$FreeDrive=Get-PSDrive -PSProvider FileSystem | Select-Object -ExpandProperty Name | Where-Object { ($_ -ne "A") -and ($_ -ne "B") -and ($_ -ne "C") } | ForEach-Object { [System.Convert]::ToByte([System.Convert]::ToChar($_)) }
$FreeDrive=@($FreeDrive)
if (($FreeDrive.Count -eq 1) -and ($FreeDrive[0] -ne "Z")) { $FreeDrive=[System.Convert]::ToChar($FreeDrive[0]+1) }
$j=0
while ((($FreeDrive[$j]+1) -eq $FreeDrive[$j+1]) -and ($j -lt ($FreeDrive.Count-1))) { $j++ }
$FreeDrive=[System.Convert]::ToChar($FreeDrive[$j]+1)
$FreeDrive