Looks great! I'm going to rehash the things that @Mike Shepard said because he's absolutely right but he wrote them in a comment, so I'll expand on them a bit first, and add a few more.
Approved Verbs
PowerShell has a concept of approved verbs. You can see them by typing Get-Verb
at the prompt, but you should really look at the MSDN page on approved verbs for the rules and help with selecting appropriate verbs.
For your function I like the Split
or Expand
verbs, like Split-Object
or Expand-Property
.
Convert
might also be appropriate based on the description, but it doesn't quite sound right to me.
Comment Based Help
Not too much to say about this that isn't covered in about_Comment_Based_Help, but yeah it's definitely good to have. One of the things that I think is overlooked is the .LINK
keyword.
If you decide to publish this somewhere, you can use this to link to online documentation or examples or support.
Get-Help MyFunction -Online
will automatically open a browser window to the first .LINK
URL (you can have more than one listed).
Avoid Aliases
Not everyone agrees with this, but I do.
I love and use aliases all the time at the prompt, but when writing scripts, I use the full names of functions, cmdlets, parameters, etc. I truly think it makes things clearer and more readable.
In your script:
%
should be ForEach-Object
select
should be Select-Object
Tab completion makes it easier since you don't have to type all of the longer names.
CmdletBinding Attribute
This is minor, but you may want to use [CmdletBinding()]
for your function. Obviously, it's not necessary since your function works, but it's worth reading about_Functions_CmdletBindingAttribute to get an idea of what it does, what it can do with its options, and how it might change the way your function works.
Parameter Naming
Your -Properties
parameter should be named -Property
. It is convention in PowerShell to use singular names, even for things that may accept or return multiple objects.
Parameter Binding
The -Properties
and -ExpandProperty
parameters are both optional, but calling the function with one or both of them missing gives less than stellar results.
So the function should be updated either to gracefully handle situations where they are missing, or they should be made mandatory (like -InputObject
).
Select
Redundancy
$x | select $Properties | select *, @{Name="$ExpandProperty";Expression={$y}}
You could avoid doing 2 selects there by combining $Properties
and the hashtable used for $y
:
$x | select ($Properties + @{Name="$ExpandProperty";Expression={$y}})
Or you could pre-append them:
$props = $Properties + @{Name="$ExpandProperty";Expression={$y}}
$x | select $props
Semicolons
You use a semicolon after your simple assigns for some reason:
$x = $_ ;
$y = $_ ;
They do no harm, but typically they are used to separate multiple statements on a single line. If you really wanted to use them in concert with line breaks, at least be consistent and do it everywhere. But, yeah actually just don't use them.
Inconsistent Coding Style
This is only concerning the placement of braces. In the process
block you use C# style where the opening brace is on its own line, and in the rest you seem to use the style more common in PowerShell where the opening brace is on the same line as the preceding statement.
In some sense, this is a matter of opinion, but sometimes it makes a difference in the way the code executes, and for that reason, I always use the latter format (brace does not get its own line).
Either way you decide, be consistent.
Closing
All in all, great job!