我在this answer中看到了Get-NextFreeDrive
函数,我想知道是否有更有效的方法来执行此操作。即使已经找到一个免费的驱动器号,链接的答案中的函数似乎仍然会遍历所有字母。
答案 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)
我喜欢这种方式,原因如下:
它找到第一个未使用的驱动器并映射它,然后它就完成了。
$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
答案 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