In a blog post on November 16th 2015 Microsoft announced PowerShell support in Visual Studio Code. And as it befits the “new” Microsoft, this PowerShell extension for Visual Studio Code (VSC) was placed on GitHub.
VSC offers features that are currently not present in the PowerShell ISE, one of the more important ones for now being Git support. And another, not negligible feature, VSC is a free product. On the VMware{code} powercli Slack channel, which you should check out, the new editor was discussed briefly.
With the 0.6.0 release of PowerShell for VS@Code, a couple of important new features were introduced. For the PowerCLI users, the addition of a VSC specific ‘profile‘, makes editing your PowerCLI scripts in VSC a lot easier. Want to try it out, read on!
Setting up VSC for PowerCLI
PowerCLI, at the time of writing, still consists of a number of PSSnapins and Modules. In my Universal PowerCLI Loader post, I introduced a generic function, named Enable-PowerCLI, that will, for each official PowerCLI release, make sure that all PSSnapins and Modules (from v6.* onwards) are loaded. We will use this function to set up PowerCLI in our VSC.
The VSC profile is stored in a file called “%UserProfile%\Documents\WindowsPowerShell\Microsoft.VSCode_profile.ps1“.
In that file I store my Enable-PowerCLI function, and at the end of the file I call the function.
Since the PowerShell for VS@Code 0.6.1 release, the execution of the profile.ps1 is set to true by default. You can skip the following paragraph.
In the 0.6.0 release, the execution of the profile was not set by default. You could enable this via the <File><Preferences><User Settings> menu entry. In the editor the default settings and your personal settings.json file are opened. In your settings.json file, enter the line “powershell.enableProfileLoading”: true, this will make sure the profile.ps1 is executed the next time you open VSC.
Now restart your VSC, and lo and behold, all PowerCLI cmdlets are known and available under Intellisense.
Snippets
In VSC there is a snippet feature, which allows you to define a code block that can be called by using a shortname in the editor. This is a handy way to have your PowerCLI code templates available at all times, no need to learn by hearth or “feeling lucky” in the search engine of your choice.
A snippet is packaged in a JSON file. The snippets file for PowerShell is “%appdata%\Code\User\snippets\powershell.json”. In that file you have one or more snippets of code.
The following is a short example of template code for the Get-Stat cmdlet for VMs.
In the snippets folder in the powershell.json file we add the definition for the PCLIStatVM snippet.
We can now call the snippet by just entering the name.
When we hit <Enter>, while the entry is selected, the code will be inserted in our current document.
The syntax of a VSC snippet is documented in the online VSC documentation.
PowerShell Editor Services
The PowerShell Editor Services offer a common extensibility model which allows one to write extension code in PowerShell. In theΒ 0.6.0 release this is now made available through the $psEditor object and the Register-EditorCommand cmdlet. More information can be found in the, also newly introduced, PowerShell Editor Services documentation.
As an example of the use of the Register-EditorCommand I created the following example. It adds a command to the VSC that allows me to open a browser with the pages I normally use as reference and help when I work with PowerCLI. Add the following code to your profile.ps1 file.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$pclihelp = { $browser = 'chrome.exe' $pclisites = 'https://communities.vmware.com/community/vmtn/automationtools/powercli/content?filterID=contentstatus[published]~objecttype~objecttype[thread]', 'https://www.vmware.com/support/developer/PowerCLI/PowerCLI63R1/html/index.html', 'https://pubs.vmware.com/vsphere-60/topic/com.vmware.wssdk.apiref.doc/right-pane.html', 'https://blogs.vmware.com/PowerCLI', 'https://lucd.info' Start-Process $browser $pclisites } Register-EditorCommand ` -Name "PowerCLI.HelpSites" ` -DisplayName "PowerCLI Help Sites" ` -ScriptBlock $pclihelp |
In the VSC you can now use this new command as the following short video will show.
A second example will actually allow you to act on selected text in the editor. With the EditorContext object you can actually what the user has selected, and take action accordingly. In this trivial example it takes the PowerCLI cmdlet that was selected, and open the online Help page for that cmdlet. Note that there is no checking implemented whatsoever, if you select something else than a PowerCLI cmdlet, the browser will go to an invalid page.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$pclicmdhelp = { param([Microsoft.PowerShell.EditorServices.Extensions.EditorContext]$context) $cmdlet = $context.CurrentFile.GetText($context.SelectedRange) $browser = 'chrome.exe' $cmdhelp = "https://www.vmware.com/support/developer/PowerCLI/PowerCLI63R1/html/$($cmdlet).html" Start-Process $browser $cmdhelp } Register-EditorCommand ` -Name "PowerCLI.HelpCmdlet" ` -DisplayName "PowerCLI Cmdlet Help" ` -ScriptBlock $pclicmdhelp |
And a short video that shows how this works.
- Select the PowerCLI cmdlet
- Press <F1>
- Type ‘ps ad’ and the fuzzy search will bring you to the additional commands menu
- Select the PowerCLI Cmdlet Help
In this third example, I show how you can interrogate the AST and also how you can send feedback to the user. This command counts the different cmdlets and variables that are present in the file. And displays the result in the Output area.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
$pscountcmdlet = { param([Microsoft.PowerShell.EditorServices.Extensions.EditorContext]$context) $cmdArr = @() $varArr = @() foreach($token in $context.CurrentFile.Tokens){ switch($token.GetType().Name){ 'StringLiteralToken'{ if($token.TokenFlags -eq 'CommandName'){ $cmdArr += $token.Value } } 'VariableToken'{ $varArr += $token.Name } } } $cmdArr = $cmdArr | Sort-Object -Unique $varArr = $varArr | Sort-Object -Unique Write-Output "You used $($cmdArr.Count) different cmdlets" Write-Output "`t$($cmdArr -join '|')" Write-Output "You used $($varArr.Count) different variables" Write-Output "`t$($varArr -join '|')" } Register-EditorCommand ` -Name "PowerShell.CountCmdletVar" ` -DisplayName "Count Cmdlets/Variables" ` -ScriptBlock $pscountcmdlet |
And a short video to demonstrate.
At the end of this post, you can download a sample VSC profile.ps1, it contains the PowerCLI Universal Loader function and the Register-EditorCommand example.
I’m currently still exploring all the possibilities of the the VS@Code andΒ PowerShell for VS@Code. There is a whole lot more to discover, and I intend to keep this post updated with new discoveries and additional features that will come in future releases.
If you want to play with VSC and the PowerShell feature, there are a couple of excellent blog posts from Keith Hill, that will help you get started.
Getting Started with Visual Studio Code for Use with PowerShell
Debugging PowerShell Script with Visual Studio Code
And there is of course the extensive, online VSC documentation.
Enjoy!
vlaneo
Hi Luc,
I wondering if you know, where can I find the Microsoft.VSCode_profile.ps1 in a Mac or if there is another way to activate powercli in vsc for Mac ?
Matt
Do you have a way of making this function work with 6.5 R1? I haven’t been able to get all the modules working correctly, most notably VMware.VimAutomation.Core
LazyPowerCLI
function Enable-VSCodePowerCLI
{
#Load 6.5 modules
(Get-Module VMware*).name | ?{$_ -notmatch ‘Common$|SDK$|Cloud$’} | %{Import-Module -Name $_ -Verbose:$false}
#Run initialization script
.’C:\Program Files (x86)\VMware\Infrastructure\PowerCLI\Scripts\Initialize-PowerCLIEnvironment.ps1′
}
Enable-VSCodePowerCLI
$pclihelp = {
$browser = ‘chrome.exe’
$pclisites = ‘https://communities.vmware.com/community/vmtn/automationtools/powercli/content?filterID=contentstatus[published]~objecttype~objecttype[thread]’,
‘https://www.vmware.com/support/developer/PowerCLI/PowerCLI65R1/html/index.html’,
‘https://pubs.vmware.com/vsphere-65/index.jsp?topic=%2Fcom.vmware.wssdk.apiref.doc%2Fright-pane.html’,
‘https://blogs.vmware.com/PowerCLI’,
‘https://www.LazyPowerCLI.com’
Start-Process $browser $pclisites
}
Register-EditorCommand
-SuppressOutput
-Name “PowerCLI.HelpSites”
-DisplayName "PowerCLI Help Sites"
-ScriptBlock $pclihelp
$pclicmdhelp = {
param([Microsoft.PowerShell.EditorServices.Extensions.EditorContext]$context)
$cmdlet = $context.CurrentFile.GetText($context.SelectedRange)
$browser = ‘chrome.exe’
$cmdhelp = “https://www.vmware.com/support/developer/PowerCLI/PowerCLI65R1/html/$($cmdlet).html”
Start-Process $browser $cmdhelp
}
Register-EditorCommand
-SuppressOutput
-Name “PowerCLI.HelpCmdlet”
-DisplayName "PowerCLI Cmdlet Help"
-ScriptBlock $pclicmdhelp
$pscountcmdlet = {
param([Microsoft.PowerShell.EditorServices.Extensions.EditorContext]$context)
$cmdArr = @()
$varArr = @()
foreach($token in $context.CurrentFile.Tokens){
switch($token.GetType().Name){
‘StringLiteralToken'{
if($token.TokenFlags -eq ‘CommandName’){
$cmdArr += $token.Value
}
}
‘VariableToken'{
$varArr += $token.Name
}
}
}
$cmdArr = $cmdArr | Sort-Object -Unique
$varArr = $varArr | Sort-Object -Unique
Write-Output “You used $($cmdArr.Count) different cmdlets”
Write-Output “
t$($cmdArr -join '|')"
t$($varArr -join ‘|’)”Write-Output "You used $($varArr.Count) different variables"
Write-Output "
}
Register-EditorCommand
-Name "PowerShell.CountCmdletVar"
-DisplayName “Count Cmdlets/Variables” `
-ScriptBlock $pscountcmdlet
Keith Hill
@jfrmilner
Just remember that for 0.6.0 you have to enable profile loading via your user preferences like so: “powershell.enableProfileLoading”: true In a future release, this feature may be enabled by default but we wanted to get some stick time with it before automatically turning it on.
LucD
Thanks for the info Keith.
I mentioned that as well, got me until David told me π
And btw, you and David are doing a hell of job here.
Looking already forward to the next release with new goodies!
jfrmilner
Support for user and system-wide profiles has now been added! – https://github.com/PowerShell/vscode-powershell/blob/master/CHANGELOG.md#060
LucD
Indeed it has.
Trying to get it to work through the VSC profile.
Richard Diphoorn
Hi Luc! This is a great feature. Actually at PowerShell Conference Europe we got a great demonstration from David Wilson about how to extend VSCode. But he showed also demo’s for Sublime Text. But remember, he’s the only one who maintains and develops the code for this, so we need to give him the time.
LucD
Thanks.
There is community effort involved as well (Keith Hill, Doug Finke…). Unfortunately I’m no Dev π
David messaged me that the next release will have profile support, then this trick isn’t needed anymore π