PowerShell Function to Determine Available Drive Letters
I've recently been working on some file server drive migrations. One of the steps I needed to perform was to change the drive letter of a current drive to a different available drive letter so I decided to write a PowerShell function to accomplish the task of determining what drive letters are available.
The Get-MrAvailableDriveLetter
function shown in the following code example will run on systems
with PowerShell version 2.0 or higher (I tested it all the way down to version 1.0, but that was a
no go).
1#Requires -Version 2.0
2function Get-MrAvailableDriveLetter {
3
4<#
5.SYNOPSIS
6 Returns one or more available drive letters.
7
8.DESCRIPTION
9 Get-MrAvailableDriveLetter is an advanced PowerShell function that returns one or more available
10 drive letters depending on the specified parameters.
11
12.PARAMETER ExcludeDriveLetter
13 Drive letter(s) to exclude regardless if they're available or not. The default excludes drive letters
14 A-F and Z.
15
16.PARAMETER Random
17 Return one or more available drive letters at random instead of the next available drive letter.
18
19.PARAMETER All
20 Return all available drive letters. The default is to only return the first available drive letter.
21
22.EXAMPLE
23 Get-MrAvailableDriveLetter
24
25.EXAMPLE
26 Get-MrAvailableDriveLetter -ExcludeDriveLetter A-C
27
28.EXAMPLE
29 Get-MrAvailableDriveLetter -Random
30
31.EXAMPLE
32 Get-MrAvailableDriveLetter -All
33
34.EXAMPLE
35 Get-MrAvailableDriveLetter -ExcludeDriveLetter A-C, M, Q, T, W-Z -All
36
37.EXAMPLE
38 Get-MrAvailableDriveLetter -Random -All
39
40.EXAMPLE
41 Get-MrAvailableDriveLetter -ExcludeDriveLetter $null -Random -All
42
43.INPUTS
44 None
45
46.OUTPUTS
47 String
48
49.NOTES
50 Author: Mike F Robbins
51 Website: http://mikefrobbins.com
52 Twitter: @mikefrobbins
53#>
54
55 [CmdletBinding()]
56 param (
57 [string[]]$ExcludeDriveLetter = ('A-F', 'Z'),
58
59 [switch]$Random,
60
61 [switch]$All
62 )
63
64 $Drives = Get-ChildItem -Path Function:[a-z]: -Name
65
66 if ($ExcludeDriveLetter) {
67 $Drives = $Drives -notmatch "[$($ExcludeDriveLetter -join ',')]"
68 }
69
70 if ($Random) {
71 $Drives = $Drives | Get-Random -Count $Drives.Count
72 }
73
74 if (-not($All)) {
75
76 foreach ($Drive in $Drives) {
77 if (-not(Test-Path -Path $Drive)){
78 return $Drive
79 }
80 }
81
82 }
83 else {
84 Write-Output $Drives | Where-Object {-not(Test-Path -Path $_)}
85 }
86
87}
It contains a requires statement and comment based help as all well written functions that you plan to share should:
1#Requires -Version 2.0
2function Get-MrAvailableDriveLetter {
3
4<#
5.SYNOPSIS
6 Returns one or more available drive letters.
7
8.DESCRIPTION
9 Get-MrAvailableDriveLetter is an advanced PowerShell function that returns one or more available
10 drive letters depending on the specified parameters.
11
12.PARAMETER ExcludeDriveLetter
13 Drive letter(s) to exclude regardless if they're available or not. The default excludes drive letters
14 A-F and Z.
15
16.PARAMETER Random
17 Return one or more available drive letters at random instead of the next available drive letter.
18
19.PARAMETER All
20 Return all available drive letters. The default is to only return the first available drive letter.
21
22.EXAMPLE
23 Get-MrAvailableDriveLetter
24
25.EXAMPLE
26 Get-MrAvailableDriveLetter -ExcludeDriveLetter A-C
27
28.EXAMPLE
29 Get-MrAvailableDriveLetter -Random
30
31.EXAMPLE
32 Get-MrAvailableDriveLetter -All
33
34.EXAMPLE
35 Get-MrAvailableDriveLetter -ExcludeDriveLetter A-C, M, Q, T, W-Z -All
36
37.EXAMPLE
38 Get-MrAvailableDriveLetter -Random -All
39
40.EXAMPLE
41 Get-MrAvailableDriveLetter -ExcludeDriveLetter $null -Random -All
42
43.INPUTS
44 None
45
46.OUTPUTS
47 String
48
49.NOTES
50 Author: Mike F Robbins
51 Website: http://mikefrobbins.com
52 Twitter: @mikefrobbins
53#>
Drive letters can be excluded via parameter input and by default A-F and Z are excluded. This can be
negated by specifying $null or an empty string for the ExcludeDriveLetter
parameter:
1[CmdletBinding()]
2param (
3 [string[]]$ExcludeDriveLetter = ('A-F', 'Z'),
By default only the first available drive letter is returned and it can be randomized by specifying
the Random
parameter:
1 [switch]$Random,
All available drive letters can be returned by specifying the All
parameter and they can also be
returned in random order with the Random
parameter:
1 [switch]$All
2)
The drive letters themselves are obtained from the Function PSDrive:
1$Drives = Get-ChildItem -Path Function:[a-z]: -Name
The excluded drive letters are converted to a regular expression to minimize the amount of code that had to be written to exclude multiple drive letters and/or ranges of drive letters:
1if ($ExcludeDriveLetter) {
2 $Drives = $Drives -notmatch "[$($ExcludeDriveLetter -join ',')]"
3}
If the Random parameter is specified, all of the available drive letters are randomized once the exclusions are removed. This allows a single line of code to be used regardless if a single or all results are desired to be returned in randomized order:
1if ($Random) {
2 $Drives = $Drives | Get-Random -Count $Drives.Count
3}
Unless the All
parameter is specified, the Return keyword is used to terminate execution once an
available drive letter is found and tested to not be in use. Read more about the PowerShell Return
keyword in
a previous blog article that I've written.
1if (-not($All)) {
2
3 foreach ($Drive in $Drives) {
4 if (-not(Test-Path -Path $Drive)){
5 return $Drive
6 }
7 }
8
9}
If the All
parameter is specified, all drive letters are tested and returned if they are not in
use. This seemed to be the most efficient way to accomplish this task without testing all of them
early on only to return a single result by default:
1else {
2 Write-Output $Drives | Where-Object {-not(Test-Path -Path $_)}
3}
The function itself is simple to use:
The Get-MrAvailableDriveLetter
function shown in this blog article can be downloaded from
my PowerShell repository on GitHub.
µ