Tag Archives: parameter

Get PowerShell Parameter Aliases

magnifying-glass During a recent PowerShell training class we naturally covered aliases. An alias is simply an alternate name, often something that is shorter to type, or maybe even more meaningful. There are aliases for commands, properties and parameters. Discovering aliases for commands is pretty easy with Get-Alias. Property aliases are discoverable using Get-Member. But, discovering parameter aliases is a bit more difficult. The information is there, but doesn’t surface very well. It would be terrific if help showed parameter aliases but it rarely does. So here are some ways you might find parameter aliases.

One way is to use Get-Help.

But you need to use Get-Help. If you use the Help function it won’t work. In the command I filtered out parameters that didn’t have aliases. You can also pipe Get-Command to Get-Help.

But for some reason, this doesn’t always work. There are aliases for Get-Service, but these same commands fail to show it.

I know there are aliases because Get-Command shows me, although it takes a little work to extract this information.

Plus I can verify at the prompt:

Since it appears I can always get the information from Get-Command, I wrote a function called Get-ParameterAlias.

The function can take a command name or you can pipe something from Get-Command.

Because parameter information from Get-Command includes common parameters such as -ErrorAction, I’ve skipped those by default, unless you use the -IncludeCommon parameter.

Now it is easy to discover parameter aliases for say a module.

get-parameteralias

Knowing parameter aliases can make you more efficient in the console. But remember, when committing PowerShell to a script use the full parameter name as some of these aliases can be a bit cryptic.

As always, I hope you’ll let me know what you think.

Rename Hashtable Key Revised

Last week I posted an advanced PowerShell function to rename a hashtable key. As usual, the more I worked with it the more I realized it was missing something – namely the ability the take a pipelined object. My original version assumed you had saved the hashtable to a variable. But as I was working with ConvertTo-Hashtable I realized the shortcoming. The solution was to modify Rename-Hashtable so that it could accept a hashtable as a piped value.

I won’t go through the function again. You can read the original post to learn more about how it works. Let’s look at what changed. Because I wanted to retain the option to also specify a variable name, I created two parameters sets. One for the piped object and one for the variable name.


[cmdletbinding(SupportsShouldProcess=$True,DefaultParameterSetName="Pipeline")]

Param(
[parameter(Position=0,Mandatory=$True,
HelpMessage="Enter the name of your hash table variable without the `$",
ParameterSetName="Name")]
[ValidateNotNullorEmpty()]
[string]$Name,
[parameter(Position=0,Mandatory=$True,
ValueFromPipeline=$True,ParameterSetName="Pipeline")]
[ValidateNotNullorEmpty()]
[object]$InputObject,
[parameter(position=1,Mandatory=$True,
HelpMessage="Enter the existing key name you want to rename")]
[ValidateNotNullorEmpty()]
[string]$Key,
[parameter(position=2,Mandatory=$True,
HelpMessage="Enter the NEW key name")]
[ValidateNotNullorEmpty()]
[string]$NewKey,
[switch]$Passthru,
[ValidateSet("Global","Local","Script","Private",0,1,2,3)]
[ValidateNotNullOrEmpty()]
[string]$Scope="Global"
)

I defined parameter sets called Pipeline and Name and made the former the default in the cmdletbinding attribute. Because the remaining parameters would be in both parameter sets I didn’t specify one. When looking at the function’s help you can see the result.

rename-hashtable-paramsets

Because I’m taking input from the pipeline, I needed to add a Process scriptblock. Within the scriptblock, if an object has been piped in, I turn on the passthru variable and create a temporary copy of the piped in hashtable.


Process {
#validate Key and NewKey are not the same
if ($key -eq $NewKey) {
Write-Warning "The values you specified for -Key and -NewKey appear to be the same. Names are NOT case-sensitive"
Return
}

Try {
#validate variable is a hash table
if ($InputObject) {
$name="tmpInputHash"
Set-Variable -Name $name -Scope $scope -value $InputObject
$Passthru=$True
}
...

The rest of the code worked just fine and there was no reason to change it. All I needed to do was transform the -Inputobject value into the -Name value since I already had code that used $Name. Sometimes you need separate code blocks but in this case I didn’t. Once the transformation is complete, the rest of the function runs as originally designed. With this version I can now run commands like this:


PS C:\> $h = get-service spooler -computer Serenity | convertto-hashtable -NoEmpty -Exclude CanStop,CanPauseAndcontinue | rename-hashtable -key machinename -new computername
PS C:\> $h

Name Value
---- -----
computername Serenity
Name spooler
ServiceName spooler
RequiredServices {RPCSS, http}
DependentServices {Fax}
ServiceType Win32OwnProcess, InteractiveProcess
Status Running
ServicesDependedOn {RPCSS, http}
ServiceHandle SafeServiceHandle
DisplayName Print Spooler

Download Rename-Hashtable2 and give it a go.

PowerShell Scripting with [ValidateCount]

Here’s another parameter validation attribute you might want to use in your PowerShell scripting and functions. If your parameter can take an array of values, you might want to limit that array to a certain size. For example, your parameter can take an array of computer names but you don’t want to process more than 5 for some reason. This is where [ValidateCount()] comes in to play.

This attribute takes two values, the minimum number of accepted parameter values and the maximum.


[ValidateCount(1,10)]
[string[]]$Computername

If used, this would mean I would need at least one computername but no more than 10. You could also set both values the same if you wanted an exact number:


[ValidateCount(2,2)]
[int[]]$Numbers

Now, I’d have to pass exactly 2 numbers as parameter values. Let’s look at a more complete example.


#requires -version 2.0

Param (
[Parameter(Position=0,Mandatory=$True)]
[ValidateCount(1,5)]
[string[]]$Name
)

Foreach ($item in $name) {

#display the name in a random color
Write-Host $item -ForegroundColor ([system.consoleColor]::GetValues("system.consolecolor") | get-random)

}

This simple script writes each name in a random color, assuming I pass no more than 5 names.

If I exceed that count, PowerShell will throw a tantrum (I mean exception).

When you use this validation test, be sure your parameter is set to accept an array of values, e.g. [string[]]. If you’d like to try out my sample code feel free to download Demo-ValidateCount.

PowerShell Scripting with [ValidateLength]

In continuing the exploration of parameter validation attributes, today we’ll look at [ValidateLength()]. You can use this attribute in your PowerShell scripting to validate that a parameter value is at least a certain length and no more and a certain length. In other words, it has to be just right. Here’s what it looks like:


[ValidateLength(2,10)]
[string]$Fooby

In this example any value for -Fooby must be at least 2 characters long and no more than 10. Anything outside of that range and PowerShell will raise an exception. You have to supply both values in the validation attribute. An alternative would be to use [ValidateScript()].


[ValidateScript({ $_.Length -ge 5})]
[string]$Name

Now, any value for -Name must be at least 5 characters and there is no upper limit. Here’s a more complete example.


#requires -version 2.0

[cmdletbinding(SupportsShouldProcess=$True)]

Param (
[Parameter(Position=0,Mandatory=$True,HelpMessage="Enter name between 5 and 15 characters")]
[ValidateLength(5,15)]
[string]$Name,
[Parameter(Position=1,Mandatory=$True,HelpMessage="Enter password between 7 and 64 characters")]
[ValidateLength(7,64)]
[ValidatePattern({^\S+$})]
[string]$Password,
[string]$Computername=$env:computername,
[switch]$Passthru
)

Write-Host "Creating $name with password of $Password on $computername" -ForegroundColor Green
[ADSI]$Server="WinNT://$computername"
$User=$server.Create("User",$Name)

if ($pscmdlet.ShouldProcess($User.Path)) {
Write-Host "Committing new account changes" -ForegroundColor Green

<# #uncomment the next lines if you really, really want to do this $User.SetInfo() Write-Host "Setting password" -ForegroundColor Green $User.SetPassword($Password) If ($passthru) { Write-Output $User } #>
}

This script will create a local user account. I’m asking that the user name be between 5 and 15 characters and that the password be between 7 and 64 characters. I’ve also added a second validation check on the password using [ValidatePattern()] to verify it doesn’t contain any spaces.

The exception message you see with [ValidateLength()] depends on where you fall short.


PS S:\> .\Demo-ValidateLength.ps1 Jeff Password123
C:\scripts\Demo-ValidateLength.ps1 : Cannot validate argument on parameter 'Nam
e'. The number of characters (4) in the argument is too small. Specify an argum
ent whose length is greater than or equal to "5" and then try the command again
.
At line:1 char:26
+ .\Demo-ValidateLength.ps1 <<<< Jeff Password123 + CategoryInfo : InvalidData: (:) [Demo-ValidateLength.ps1], Para meterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationError,Demo-ValidateLe ngth.ps1 PS S:\> .\Demo-ValidateLength.ps1 JeffJeffJeffJeff Password123
C:\scripts\Demo-ValidateLength.ps1 : Cannot validate argument on parameter 'Nam
e'. The argument length of 16 is too long. Shorten the length of the argument t
o less than or equal to "15" and then try the command again.
At line:1 char:26
+ .\Demo-ValidateLength.ps1 <<<< JeffJeffJeffJeff Password123 + CategoryInfo : InvalidData: (:) [Demo-ValidateLength.ps1], Para meterBindingValidationException + FullyQualifiedErrorId : ParameterArgumentValidationError,Demo-ValidateLe ngth.ps1

If you'd like, you can download Demo-ValidateLength and try it out for yourself.

PowerShell Scripting with [ValidateSet]

Today we’ll continue our exploration of the parameter validation attributes you can use in you PowerShell scripting. We’ve already looked at [ValidateRange] and [ValidateScript]. Another attribute you are likely to use is [ValidateSet()]. You can use this to verify that the parameter value belongs to a pre-defined set.

To use, specify a comma separated list of possible values.

If the person running the script specifies something other than “Apple”, “Banana”, or “Cherry” as a value for -Fruit, PowerShell will throw an exception and the script will fail to run. And in case you were wondering, this is not case-sensitive.

If you are going to use this attribute, I recommend providing documentation either in comment based help and/or as part of a help message so the user knows what values to expect. The PowerShell help system doesn’t automatically detect this attribute and use it in syntax display as you might have seen with other cmdlets.

Here’s a more practical example.

The script will get recent events from a specified log on a specified computer and export the results. My script will only export from a short list of logs which I’m validating.

If an invalid value is detected PowerShell will complain.

The error message displays the expected values, but the better approach might be to include them in a help message, especially if the parameter is mandatory. For example, this script will export results based on -Export.

If you’d like to try out my demo script, you can download Demo-ValidateSet.