13

我在这个答案中看到了这个Get-NextFreeDrive函数,我想知道是否有更有效的方法来做到这一点。似乎链接答案中的函数会继续遍历所有字母,即使它已经找到了一个空闲的驱动器号。

4

11 回答 11

28

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

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

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

ls function:[d-z]: -n | ?{ !(test-path $_) } | random
于 2012-09-19T04:23:46.407 回答
5

我的两分钱:

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 
于 2012-09-19T07:18:12.370 回答
4

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

  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
        }
    }
    
于 2014-05-14T11:52:16.757 回答
1
$taken = Get-WmiObject Win32_LogicalDisk | Select -expand DeviceID
$letter = 65..90 | ForEach-Object{ [char]$_ + ":" }
(Compare-Object -ReferenceObject $letter -DifferenceObject $taken)[1].InputObject

Just for fun to shave an extra line of code (lol). If you wanted to be cloppy as heck you could skip instantiating variables and just pipe those directly into -Ref and -Diff directly, probably ought to be slapped for doing that though. :)

Selects [1] to avoid getting the A: drive just in case that might complicate matters.

于 2013-08-21T14:41:01.783 回答
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'

于 2015-03-31T16:09:05.753 回答
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 获取已在使用的字母数组
  • 接下来使用比较运算符 -notcontains 生成一个未使用的字母数组
  • 最后输出一个字母。
于 2013-05-02T20:40:01.923 回答
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) + ":"
于 2017-02-09T18:10:51.140 回答
1

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

我做了这个来排除阵列中的任何本地驱动器:

"$([char[]]([char]'D'..[char]'Z')|Where-Object {((Get-WmiObject -Class Win32_LogicalDisk).DeviceID).replace(':','') -notcontains $_ }|Select-Object -first 1):"

它将返回第一个可用的字母。如果您更喜欢最后一个可用的字母,只需更改Select-Object -first 1Select-Object -last 1

于 2017-08-09T08:39:26.233 回答
0

I found out that Test-Path evaluates my empty CD-Drive as False, here is another alternative that will compare every letter in the alphabeth until it finds one that doesn't exist in filesystem, then returns that drive as output.

$DriveLetter = [int][char]'C'
WHILE((Get-PSDrive -PSProvider filesystem).Name -contains [char]$DriveLetter){$DriveLetter++}
Write-Host "$([char]$Driveletter):"
于 2015-03-05T21:46:35.477 回答
0

只需添加一个适用于远程驱动器号的驱动器 $computer 将是输入,$driveletter 将包含远程计算机上的下一个可用驱动器

67..90 | foreach {if(((GWmi win32_logicaldisk -computer $computer -Property DeviceID).deviceID).Substring(0,1) -notcontains [char]$_){$driveLetter = [char]$_; break}}

也许可以缩短它,但在那个长度上,它清楚地看到发生了什么

于 2017-05-08T11:36:14.167 回答
0

这似乎有点像“我也是”的答案,但我注意到所有其他答案都使用-containsor-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
于 2019-06-02T18:29:53.030 回答