2012-09-19 12 views
9

Ho visto la funzione Get-NextFreeDrive in this answer e mi chiedevo se esistesse un modo più efficiente per farlo. Sembra che la funzione nella risposta collegata continui a passare attraverso tutte le lettere anche se ha già trovato una lettera di unità libera.Ottenere una lettera di unità gratuita

risposta

17

Alla rivista PowerShell, abbiamo organizzato una gara di rompicapo per trovare la risposta più breve alla tua domanda. Controllare questo:

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

Non ci sono più risposte, ma qui è la mia preferita uno:

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

Questo ottiene solo una lettera di unità disponibile a caso, non la prima disponibile. – Nick

+2

@Nick: che può essere corretto sostituendo 'random' con' select -First 1' – Rynant

+0

Grazie a @Rynant. Sì, ho appena mostrato il mio modo preferito per farlo. – ravikanth

4

I miei due centesimi:

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

Gamma di validità [CHAR] è 68..90, l'aggiunta di un controllare se [char]$_[0] -gt 90 evitare risultati imprevisti. Nel caso qualche unità è un'unità di rete mappata esso restituisce sempre maggiore successivo, es .:

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

il ritorno comando s: e non e: come [stringa]

Questo dà la prima lettera dell'unità libera (un po 'brutto .. qualcuno può farlo meglio 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 
1

Ecco cosa mi è venuto in mente. Ho bisogno l'ultima lettera disponibile da A 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 
  • Questo ottiene una matrice di lettere A..z
  • Poi ottiene una matrice di lettere già in uso da WMI
  • Successivo produce una serie di lettere non in uso utilizzando l'operatore di confronto -notcontains
  • Infine, emette una singola lettera.
1
$taken = Get-WmiObject Win32_LogicalDisk | Select -expand DeviceID 
$letter = 65..90 | ForEach-Object{ [char]$_ + ":" } 
(Compare-Object -ReferenceObject $letter -DifferenceObject $taken)[1].InputObject 

Solo per divertimento radere una riga aggiuntiva di codice (lol). Se si volesse essere cloppy come diamine, si potrebbe saltare le variabili di istanziazione e semplicemente reindirizzare direttamente quelle direttamente in -Ref e -Diff, ma probabilmente bisognerebbe essere schiaffeggiate per farlo. :)

Seleziona [1] per evitare di ottenere l'unità A: nel caso in cui ciò potrebbe complicare le cose.

3

mi piace questo modo, per i seguenti motivi:

  1. Non necessita di WMI, cmdlet di PowerShell solo regolari
  2. E 'molto chiaro e di facile lettura
  3. Esso consente facilmente escludere lettere di unità specifiche
  4. esso permette facilmente di ordinare le lettere di unità in qualsiasi ordine si desidera
  5. essa trova il primo non utilizzato driveletter e la mappa, e allora è fin mentata.

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

ho scoperto che Test-Path valuta il mio vuoto CD-Drive come falso, qui è un'altra alternativa che metterà a confronto ogni lettera nella alphabeth fino a trovarne uno che non esiste nel file system, quindi restituisce quell'unità come uscita.

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

Ho dovuto scrivere una funzione che funziona con Powershell V2.0. La seguente funzione restituisce la lettera successiva disponibile, è anche possibile ottenere una lettera escludere come parametro:

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

Diciamo che il vostro OS-Report di auto-lettere C:, E:, F: e G: come viene utilizzato .

Esecuzione: $ Prima = AvailableDriveLetter, si tradurrà in $ Prima contenente 'D'

Esecuzione: $ Sec = AvailableDriveLetter -ExcludedLetter $ Prima, si tradurrà in $ Sec contenente 'h'

1

un altro modo ...

$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) + ":" 
0

solo intenzione di aggiungere quello che funziona per le lettere di unità remote $ computer sarà l'inp ut e $ driveletter conterrà successiva unità disponibile sul computer remoto

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

potrebbe essere in grado di abbreviare tale ma in quel tratto la sua chiara per vedere che cosa sta succedendo

1

ho trovato al mio costo che il risposta attualmente accettata (funzione ls: [dz]: -n | ? {! (percorso test $ _)} | casuale) può effettivamente restituire cose come le unità CD.

Ho fatto questo per escludere eventuali unità locali dalla matrice:

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

ritornerà la prima lettera disponibile. Se preferisci l'ultima lettera disponibile cambia semplicemente Select-Object -first 1 a Select-Object -last 1

Problemi correlati