Share via


Create Your Own ISE Add on Using Visual Studio

WPF Controller in Visual Studio

Summary

Windows PowerShell discussion with System Administrators and Developers:
Feedback: ISE has no good Add-On's. Many use ISE Steroids which is an excellent add-on for PowerShell ISE. We do have script browser and analyzer now.

Discussion

Comparing ISE with Visual Studio is not fair! Why do you want to do that? WMF 5.0 and it's features are far better than earlier versions. So, indeed PowerShell ISE is also grown up. We don't have commands to meet all our needs in Windows PowerShell so we create a function, Proxy Functions, Workflow, Class or modules for various needs. Similarly, we can create our own add on for ISE. Let us see a quick demo of it using Visual Studio 2013.

Procedure

We can easily create this using with the available VSIX if not you can opt for WPF Control Library and create a add-on as required by adding Microsoft.PowerShell.GPowerShell. In this article we will make our job easy by using VSIX – Click to download.
Read the documentation and install the VSIX as required. Now, we will create a simple CustomAddon which will insert a code or some string into the current ISE file. Open Visual Studio 2013 and choose Visual C# and select PowerShell ISE Add-on for VS2013. Name it as required! In this case we have named it CustomAddOn as shown below.

Now open up the UserControl1.xaml.cs code – Just double click it and the below will be the default code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.PowerShell.Host.ISE;

namespace CustomAddOn
{
    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class UserControl1 : IAddOnToolHostObject
    {
        public UserControl1()
        {
            InitializeComponent();
        }

     public ObjectModelRoot HostObject
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }
    }
}

Okay, we have the pseudo code – let’s do some modification and test the ISE add-on to insert a code or some string in ISE. To do that first we need to comment the below lines and just add get and set like shown below

public ObjectModelRoot HostObject
        {
            //get
            //{
            //    throw new NotImplementedException();
            //}
            //set
            //{
            //    throw new NotImplementedException();
            //}
            get;
            set;
        }

Now, it’s time for us to add the controls and code as required. For, testing let us add a button and trigger an event which inserts code or string in ISE current file. So, we have added a button in XAML file and the code looks like below

<UserControl x:Class="CustomAddOn.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Button Content="Insert Code" HorizontalAlignment="Left" Margin="32,57,0,0" VerticalAlignment="Top" Width="215" RenderTransformOrigin="-0.846,-0.893" Name="code" Click="click_insert"/>

    </Grid>
</UserControl>

Just make a note – we have made the name of the button as code and created a click event but haven’t done any code for event firing. So, to do that we will jump back to CS file and code as given below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.PowerShell.Host.ISE;

namespace CustomAddOn
{
    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class UserControl1 : IAddOnToolHostObject
    {
        public UserControl1()
        {
            InitializeComponent();
        }

        private void click_insert(object sender , RoutedEventArgs e)
        {
            HostObject.CurrentFile.Editor.InsertText("Get-Service");
        }

        public ObjectModelRoot HostObject
        {
            //get
            //{
            //    throw new NotImplementedException();
            //}
            //set
            //{
            //    throw new NotImplementedException();
            //}
            get;
            set;
        }
    }
}

Right-click on the CustomAddon in solution explorer and build your solution. Then spin up your PowerShell ISE and execute the below piece of code:
Sample Output
https://dlqfjq.dm2301.livefilestore.com/y3pTdvMY_Vqfd-4ZRIp4xcloTP_erOuzdRHIuinjDL00DvhUjHPmGqZmlf2peKNPty8v1ew8pwx48tOynkedyNG9R-3dxHP-DMoqr31dZLp47ZP4uSJkkvwFbOkCwmsxg276Bulai-vHrhN2LK1Z4N7QEJDOV21qWwrsrnETgc4TRM/2.jpg?psid=1

PowerShell One Liner
https://dlqfjq.dm2301.livefilestore.com/y3pmYw5ZI7fbvnfFdCRmClBFkKAuvuwiO-N-ZxAP5aZkWMYPeGBXcN3_xz78QbAws9fX_OB8TNHR2B75g0c69aAeY92WfPdTAVDX7HNB3VYxKFjJnsyK7UEgq-nFMK9QbfhgYY5RLhdsVW6n2rJqqNFiSkn2NMkQWUV8aT-gRnB1qY/3.jpg?psid=1

Below is the sample code - Importing our custom solution file and adding in ISE - Enjoy PowerShell!

Import-Module C:\Temp\CustomAddOn\CustomAddOn\bin\Debug\CustomAddOn.dll
$psISE.CurrentPowerShellTab.VerticalAddOnTools.Add("CustomAddOn" , [CustomAddOn.UserControl1] , $true)