What's In a Name
“What’s in a name? That which we call a rose/ By any other name would smell as sweet.” - Romeo and Juliet
I’m sure you are familiar with Shakespeare’s immortal words. Juliet is telling Romeo that she loves him for who he is, not what he is called. Although, if Juliet knew how things would turn out, I’m sure she wouldn't have complained if Romeo’s name was something other than “Montague.” In PowerShell, names are just as important, especially if you understand how the story, your PowerShell expression, will turn out. Whether running a PowerShell command or creating a PowerShell module, names matter. Let’s look at this concept in more detail.
Consistency
One of the reasons that PowerShell is (relatively) easy to use is that it has a consistent naming pattern. You all know that PowerShell commands follow a Verb-Noun naming convention. The Verb comes from a list of standard .NET verbs which you can see by running Get-Verb
. I like that the cmdlet has been improved in PowerShell 7.
You can easily limit your search for the correct verb.
Although Microsoft advises that `Get-Verb` is potentially incomplete. You should reference https://docs.microsoft.com/powershell/scripting/developer/cmdlet/approved-verbs-for-windows-powershell-commands?view=powershell-7.2 for a complete list of verbs as well as guidance on how to use them best. Microsoft’s information is as good as anything I could write, so I encourage you to take some time to read it.
When you are creating functions, you should use an appropriate verb. I realize this can be a challenge at times. Find the best verb you can for the official command name. You can always define an alias.
Let’s say you write a function to compress an event log file to a zip file for a support tech to run. The tech may not have much PowerShell experience and think about running a “compress” command. They might be thinking “zip.” Fine. Give them an alias.
You can also create short aliases using the recommended abbreviation. Or, create an alias that mimics a command-line tool name.
Set-Alias ziplog Compress-EventLog
Be careful when going this route. Yes, your command may be easier to run from the user’s perspective, but there are dangers. You need to ensure that your alias doesn’t conflict with native commands. In PowerShell 7 on non-Windows platforms, Microsoft removed aliases like ps, ls, and sort because they conflict with native Linux commands. If you run ps in a Linux PowerShell session, you are running the native ps command, not Get-Process
. Although you could still use the gps
alias.
The recommended best practice is always to use a standard verb in your command. If the name isn’t user-friendly, then define an appropriate alias. Even if the alias follows the Verb-Noun naming convention as I did earlier with Zip-EventLog
.
Here’s an undocumented PowerShell feature that you might find handy at the console. You can run many of the ‘Get’ cmdlets without specifying the verb.
This doesn’t work for all ‘Get’ commands should only be used in interactive PowerShell sessions.
Noun Naming
The Noun portion of your command can be a bit trickier. It should be the single form of the thing you are working with. However, PowerShell has been around since 2006, and thousands of commands have been created, touching probably everything you can think to manage. Ideally, you need your command name to be unique. Fortunately, you have several options.
The first approach is to incorporate some sort of prefix with the noun. This could be your initials, an organizational reference, or something generic.
Get-jhProcess
Stop-myJob
Set-CorpADUser
Remove-ContosoWebSite
The noun should not contain numbers or characters. Commands like these will work but deviate from accepted PowerShell practices.
Get-Service2
Initialize-Server-Backup
The whole point of this process is to avoid naming collisions. Often, you can anticipate collisions based on experience. For example, if you have a custom command to get an Active Directory user object, you don’t want to call it Get-ADUser
because that will conflict with the ActiveDirectory RSAT module. The challenge is that you cannot know what collisions might happen in the future.
You decide to use the name Get-ADSUser
. This works fine until the day your company begins using a third-party tool that includes PowerShell commands with names that collide with your function. At this point, you have a few options. When you import the new module, you can tell PowerShell to insert a temporary prefix that references the vendor name.
import-module ADSuperTools -Prefix abc
Now you would run Get-abcADSUser
. This is not a permanent change. You would need to remember to import the module with the prefix.
Another option would be to import your module with a prefix. Assuming your command is packaged in a module, you can define a default prefix in the manifest.
DefaultCommandPrefix = 'Corp'
This prefix is automatically applied when the module is imported.
The functions in the module use the normal name like Set-ADSUser
. The prefix is added when the module is imported. If you need to change the default prefix, all you need to do is update the manifest. Users can override your default with their prefixes.
Import-Module ADSTools -prefix xyz
As a last resort, you can run a command with its fully qualified name. Say you have the Hyper-V module installed and another toolset that also has a command called Get-VM
. You can run the Hyper-V command by including the module name.
hyper-v\Get-VM FCX-3455
Parameter Naming
Equally important in PowerShell is how parameters are named. There is still a naming convention, although it is a bit looser than the Verb-Noun convention. The problem with legacy command line tools was that you were never sure what parameter name to use. Was it Computername
, or System
, or MachineName
? You were constantly reading the help. In PowerShell, we have a set of widely accepted parameter names. If the command has a parameter to indicate a remote computer, the parameter name should be Computername
. A reference to a file or folder should be Path
. Although you will also see FilePath
which is probably a more precise choice if the parameter value is a file. Here are some other standard parameter names I think you should stick with:
Credential
Count
Session
AsJob
Passthru
Filter
You should avoid re-inventing the wheel. Don’t create a command with a SystemName
parameter when Computername
is used everywhere else. This makes your command less discoverable. A command with a poor parameter name won’t be found.
Get-Command -ParameterName Computername
But an argument can be made for an alternate parameter name when it comes to usability. I would still encourage you to use Computername
as the “official” parameter name. But there is nothing wrong with defining a parameter alias.
[Parameter(ValueFromPipelineByPropertyName)]
[alias("cn","systemname")]
[string[]]$Computername
Perhaps the user running your command is more comfortable using SystemName
. Or you expect your command to accept pipelined data, and you’d like to make it easy to use. Based on user feedback, they typically will import data from an externally created CSV file that uses “CN” as a heading for the computer name. Using the parameter definition above, this becomes an easy process.
Import-CSV sysdata.csv | Get-SystemStatus
The imported object will have a property called CN
. PowerShell will bind this value to the Computername
parameter using the cn
alias. I use parameter aliases often for this very purpose.
The Name Name
Many PowerShell commands have a parameter to get something or do something to a thing base on its identity. Typically this parameter has a name of Name
. If your command has a clear name, the Name
parameter should be clear.
Get-VMStatusUpdate -name FTX-JH32
I’m highly confident that the Name
parameter refers to a virtual machine. Note that I wouldn’t use Computername
. That parameter would be reserved for the Hyper-V server name.
What about this?
Export-ClusterQuorum -name abc123
What is the Name
parameter? Is it referring to the cluster name? The name to be used in the export? Something that references the quorum? You would absolutely want to document your command and its parameters clearly. But I would also recommend using meaningful parameter names.
Export-ClusterQuorum -ExportName abc123 -ClusterName CLS-34-X
Based on how the command will be used, you might still create a parameter alias of Name
.
Despite Juliet’s protestations, sometimes it does matter what you call something.
Summary
I’m trying to keep these articles from becoming overwhelming, so I’ll pause for now. I have much more to say on this topic, so keep your eyes open for Part 2. In the meantime, I’d love to hear about your naming challenges or problems. You can leave a comment on Substack or email me at behind@jdhitsolutions.com.
This article was offered to free subscribers as a sample of the content paid subscribers enjoy. I hope you’ll consider joining them.