A couple of suggestions. First try to use parameter validation, particularly ValidateScript.
function Set-Drive {
[CmdletBinding()]
param(
[ValidateScript({ !(Test-Path $_ )})]
[string]$NewDriveLetter="Y:\"
)
begin{}
process{
"Run command"
}
end{}
}
Set-Drive C:
Output:
Set-Drive : Cannot validate argument on parameter 'NewDriveLetter'. The " !(Test-Path $_ )" validation script for the argument with value "C:" did not return a result of True. Determine why the
validation script failed, and then try the command again.
At line:15 char:11
+ Set-Drive C:
+ ~~
+ CategoryInfo : InvalidData: (:) [Set-Drive], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Set-Drive
So, validate did occur, but the error message is a bit cryptic stating that what you validated wasn’t true, so an error was thrown. Let’s add a bit more logic into the parameter:
function Set-Drive {
[CmdletBinding()]
param(
[ValidateScript({IF (-NOT (Test-Path $_)) {$true}else{ Throw "$($_) already exists, choose another drive"}})]
[string]$NewDriveLetter="Y:\"
)
begin{}
process{
"Run command"
}
end{}
}
Set-Drive Y:
Output:
Set-Drive : Cannot validate argument on parameter 'NewDriveLetter'. C: already exists, choose another drive
At line:31 char:11
+ Set-Drive C:
+ ~~
+ CategoryInfo : InvalidData: (:) [Set-Drive], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Set-Drive
Now we get a more useful custom error for troubleshooting. Your code would now work just like the try\catch around WMI:
PS C:\Windows\System32\WindowsPowerShell\v1.0> try{Set-Drive -NewDriveLetter C: -ErrorAction Stop}catch{$_.Exception.Message}
Cannot validate argument on parameter 'NewDriveLetter'. C: already exists, choose another drive
Second item, you are not validating that someone is actually providing what you want. You want a letter with no colon or backslash, what would happen if someone passed E:. How is a user supposed to know what you want?
[attachment file=“Set-Drive.txt”]
Output:
try{Set-Drive -NewDriveLetter A -ErrorAction Stop}catch{$_.Exception.Message}
Cannot validate argument on parameter 'NewDriveLetter'. The argument "A" does not match the "(?# Must be a letter D-Z )^[d-zD-Z]" pattern. Supply an argument that matches "(?# Must be a letter D-Z )^[d-
zD-Z]" and try the command again.
try{Set-Drive -NewDriveLetter A: -ErrorAction Stop}catch{$_.Exception.Message}
Cannot validate argument on parameter 'NewDriveLetter'. The character length of the 2 argument is too long. Shorten the character length of the argument so it is fewer than or equal to "1" characters, a
nd then try the command again.
try{Set-Drive -NewDriveLetter D -ErrorAction Stop}catch{$_.Exception.Message}
Cannot validate argument on parameter 'NewDriveLetter'. D:\ already exists, choose another drive
try{Set-Drive -NewDriveLetter E -ErrorAction Stop}catch{$_.Exception.Message}
Run command
try{Set-Drive -NewDriveLetter E:\ -ErrorAction Stop}catch{$_.Exception.Message}
Cannot validate argument on parameter 'NewDriveLetter'. The character length of the 3 argument is too long. Shorten the character length of the argument so it is fewer than or equal to "1" characters, a
nd then try the command again.
#Now we can get help on the function with Get-Help
PS C:\Windows\System32\WindowsPowerShell\v1.0> Get-Help Set-Drive -Detailed
NAME
Set-Drive
SYNOPSIS
Sets a new driver letter
SYNTAX
Set-Drive [-NewDriveLetter] []
DESCRIPTION
Sets a new driver letter using WMI Class ....
PARAMETERS
-NewDriveLetter
The letter of the drive with no colon or backslash (e.g. G)
This cmdlet supports the common parameters: Verbose, Debug,
ErrorAction, ErrorVariable, WarningAction, WarningVariable,
OutBuffer, PipelineVariable, and OutVariable. For more information, see
about_CommonParameters (http://go.microsoft.com/fwlink/?LinkID=113216).
-------------------------- EXAMPLE 1 --------------------------
C:\PS>Set-Drive -NewDriveLetter E
Set the new drive letter to E
REMARKS
To see the examples, type: "get-help Set-Drive -examples".
For more information, type: "get-help Set-Drive -detailed".
For technical information, type: "get-help Set-Drive -full".
#Or
PS C:\Windows\System32\WindowsPowerShell\v1.0> Set-Drive
cmdlet Set-Drive at command pipeline position 1
Supply values for the following parameters:
(Type !? for Help.)
NewDriveLetter: !?
Provide a drive letter from D to Z with no colon or backslash
NewDriveLetter:
Now, after you have done all this work to validate your parameters meet all of the criteria, does the WMI method already do all of this? What happens if you pass a blank value, a letter being used already, etc? Does the error tell you what is wrong? All I’m saying is you might be doing more work than is required and should test the method and see if it returns the proper errors before you do any validation in your script. Make sure you declare [CmdletBinding()] when using Write-Verbose or it will not work and set the parameter as Mandatory if it’s required for the function to work.
function Set-Drive {
[CmdletBinding()]
param(
[string]$NewDriveLetter
)
begin{}
process{
try{
#WMI Method
}
catch {
#any errors would be caught here that were handled by the
#WMI method developer. If the method tells you the drive is already used,
#do you need handle it before then method is called? You can catch the error,
#log it and just do Throw $_ to throw the WMI error message to the calling logic
}
}
end{}
}
Edit: Forum is stripping XML comments out of the content, adding as attachment