I cut my teeth with PowerShell ISE and still have fond memories of it. But VS Code now rules my world – and that’s ok. Moving forward is progress.
But one of the annoyances I’ve had since moving my PowerShell coding from the ISE to VS Code is the lack of the original snippets. In truth the PowerShell snippets that ship with VS Code are (generally) vastly superior and I use them all the time. But there are two (IMO) that are sorely lacking.
Cmdlet (advanced function) – complete
The replacement for the “cmdlet” snippet in VS Code is… well, it’s ok.

It provides the minimum requirements, but I’m always trying to remember what options I have in the parameter block. It makes me long for the days of the ISE snippet which included (nearly) every possible option.

That began this journey to convert my two most-used ISE-based snippets to those for VS Code.
First, I’ve got to get to the powershell.json file that I’m supposed to edit. Thankfully, it’s accessible via File, Preferences, Snippets and then typing ‘powershell’ in the search. Viola, a new empty PowerShell snipped JSON file.
The format of the JSON file was relatively easy. It’s a series of named objects with prefix, body, and description elements. The name of the object, the prefix, and the description were relatively easy (once I decided on my own standard), but the body, was less easy.
All snippets within VS Code support focus elements via the $ character, having them in the body was more difficult than anticipated.
What I ended up doing was a simple process that took way longer than it should. I’m going to lay out the steps in case anyone needs to follow them.
- Insert the wanted Snippet in PowerShell ISE.
- Copy the contents to VS Code and use the “Format Document” option from the command palette.
(This is optional, but I felt like it matched modern formatting better) - Wrap the snippet in single quote here-string delimiters (
@'and'@), remembering to put the delimiters on a blank line before and at the end. - We need to split the block into lines, so use the
-splitoperator. - Then we need to parse though each line replacing a single dollar sign with a double-dollar sign.
- Then we format the results as a JSON.
- Lastly (because I’m lazy, I use the
Set-Clipboardto send results to my clipboard.
The whole “script” for my converter looks like this:
@'
<#
.Synopsis
Short description
.DESCRIPTION
Long description
.EXAMPLE
Example of how to use this cmdlet
.EXAMPLE
Another example of how to use this cmdlet
.INPUTS
Inputs to this cmdlet (if any)
.OUTPUTS
Output from this cmdlet (if any)
.NOTES
General notes
.COMPONENT
The component this cmdlet belongs to
.ROLE
The role this cmdlet belongs to
.FUNCTIONALITY
The functionality that best describes this cmdlet
#>
function Verb-Noun
{
[CmdletBinding(DefaultParameterSetName='Parameter Set 1',
SupportsShouldProcess=$true,
PositionalBinding=$false,
HelpUri = 'http://www.microsoft.com/',
ConfirmImpact='Medium')]
[Alias()]
[OutputType([String])]
Param
(
# Param1 help description
[Parameter(Mandatory=$true,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true,
ValueFromRemainingArguments=$false,
Position=0,
ParameterSetName='Parameter Set 1')]
[ValidateNotNull()]
[ValidateNotNullOrEmpty()]
[ValidateCount(0,5)]
[ValidateSet("sun", "moon", "earth")]
[Alias("p1")]
$Param1,
# Param2 help description
[Parameter(ParameterSetName='Parameter Set 1')]
[AllowNull()]
[AllowEmptyCollection()]
[AllowEmptyString()]
[ValidateScript({$true})]
[ValidateRange(0,5)]
[int]
$Param2,
# Param3 help description
[Parameter(ParameterSetName='Another Parameter Set')]
[ValidatePattern("[a-z]*")]
[ValidateLength(0,15)]
[String]
$Param3
)
Begin
{
}
Process
{
if ($pscmdlet.ShouldProcess("Target", "Operation"))
{
}
}
End
{
}
}
'@ -split "`n" | ForEach-Object { $_.Replace('$', '$$') } | ConvertTo-Json | Set-Clipboard
And the contents of my clipboard afterwards…
[
"<#\r",
".Synopsis\r",
" Short description\r",
".DESCRIPTION\r",
" Long description\r",
".EXAMPLE\r",
" Example of how to use this cmdlet\r",
".EXAMPLE\r",
" Another example of how to use this cmdlet\r",
".INPUTS\r",
" Inputs to this cmdlet (if any)\r",
".OUTPUTS\r",
" Output from this cmdlet (if any)\r",
".NOTES\r",
" General notes\r",
".COMPONENT\r",
" The component this cmdlet belongs to\r",
".ROLE\r",
" The role this cmdlet belongs to\r",
".FUNCTIONALITY\r",
" The functionality that best describes this cmdlet\r",
"#>\r",
"function Verb-Noun\r",
"{\r",
" [CmdletBinding(DefaultParameterSetName='Parameter Set 1', \r",
" SupportsShouldProcess=$$true, \r",
" PositionalBinding=$$false,\r",
" HelpUri = 'http://www.microsoft.com/',\r",
" ConfirmImpact='Medium')]\r",
" [Alias()]\r",
" [OutputType([String])]\r",
" Param\r",
" (\r",
" # Param1 help description\r",
" [Parameter(Mandatory=$$true, \r",
" ValueFromPipeline=$$true,\r",
" ValueFromPipelineByPropertyName=$$true, \r",
" ValueFromRemainingArguments=$$false, \r",
" Position=0,\r",
" ParameterSetName='Parameter Set 1')]\r",
" [ValidateNotNull()]\r",
" [ValidateNotNullOrEmpty()]\r",
" [ValidateCount(0,5)]\r",
" [ValidateSet(\"sun\", \"moon\", \"earth\")]\r",
" [Alias(\"p1\")] \r",
" $$Param1,\r",
"\r",
" # Param2 help description\r",
" [Parameter(ParameterSetName='Parameter Set 1')]\r",
" [AllowNull()]\r",
" [AllowEmptyCollection()]\r",
" [AllowEmptyString()]\r",
" [ValidateScript({$$true})]\r",
" [ValidateRange(0,5)]\r",
" [int]\r",
" $$Param2,\r",
"\r",
" # Param3 help description\r",
" [Parameter(ParameterSetName='Another Parameter Set')]\r",
" [ValidatePattern(\"[a-z]*\")]\r",
" [ValidateLength(0,15)]\r",
" [String]\r",
" $$Param3\r",
" )\r",
"\r",
" Begin\r",
" {\r",
" }\r",
" Process\r",
" {\r",
" if ($$pscmdlet.ShouldProcess(\"Target\", \"Operation\"))\r",
" {\r",
" }\r",
" }\r",
" End\r",
" {\r",
" }\r",
"}"
]

And that’s the body element defined. Then it’s just adding the other two elements, choosing a name, and it’s available in my console as I type.
Since I only wanted the simple class and the complete cmdlet snippets, I did them by hand. If anyone’s interested in this, you can view the contents of my complete PowerShell JSON file.