Back to top

FREE eBook: The Most USEFUL PowerShell CmdLets and more…

Grab a copy!

How To Write Advanced Functions Or CmdLets With PowerShell (Fast)

How to write Advanced Functions or own CmdLets with PowerShell Fast
Approx Reading Time: 12 minutes

The best way to write fast your own PowerShell Advanced Function or CmdLet is to have a function template as a starting point which you will fill out afterward with your own code so you do not start from scratch with empty script pane.

This is exactly what we get with the New-Function Windows PowerShell ISE Add-on CmdLet that I will explain in this article.

Example Of PowerShell Advanced Function

Let me show you quickly one example of how to have a quick start on writing Advance Function or own CmdLet then I will explain to you how you can achieve the same level of efficiency so follow me and have fun exploring Advanced Functions and CmdLets worlds with warp speed.

If we run this code either by pressing F8 (Run Selection) or Ctrl + Alt + S (shortcut for running New-Function Add-on CmdLet)

New-Function -FunctionName "New-ImprovedFunction"

Here is the result that we get:

     <#
        .SYNOPSIS
        .DESCRIPTION
        .PARAMETER
        .EXAMPLE
        .INPUTS
        .OUTPUTS
        .NOTES
            FunctionName : New-ImprovedFunction
            Created by   : dekib
            Date Coded   : 10/07/2019 15:48:26
        .LINK
            
Home
#> Function New-ImprovedFunction { [CmdletBinding()] Param ( ) Begin { } Process { New-Function -FunctionName "New-ImprovedFunction" } End { } } #region Execution examples #endregion

I think it is amazing to get this amount of code just from one line of code, but how we got all that code, well continue reading to find out.

Buckle up, sit tight and…

“Give Me Warp Speed, Mr. Sulu”.

Star Track

Here you go, let’s have fun while learning this cool functionality.

What Did We Get?

Let’s just quickly review the sections of code that was generated by New-Function Add-on CmdLet:

  1. We got a comment-based help structure.
  2. We got a function declaration with the function name that we have provided as the value for parameter FunctionName.
  3. We got the CmdletBinding attribute.
  4. We got the “Param” construct statement so we can continue writing function input parameters within it.
  5. We got empty BEGIN and END blocks.
  6. We got selected code in the PROCESS block. In this case, we can delete that part and start writing our own code for “New-ImprovedFunction” function

Here is a visual representation of what we have just numbered in the list.

Result of New-Function Add-on

What Do We Need To Do Next?

Follow these easy steps to write own Advanced Function of CmdLet:

  • We can fill out Comment Based Help with info that explains our Advance Function of CmdLet. If you need just a comment-based help template here is another PowerShell ISE Add-on CmdLet New-CommentBlock with source code and explanation that provides the solution for you in an easy way.
  • We can define input parameters within the Param() construct. If you want to know more about PowerShell Parameters with some cool examples please read this article.
  • We can write our code within BEGIN PROCESS END blocks. To learn more about how these blocks work in PowerShell please read this article.
  • We can write example calls to our Function within region Execution examples
  • We can save this Function as a PowerShell script…
  • … or we can save this function as own CmdLet and organize in modules and load with PowerShell profile.

New-Function CmdLet Explained

We will look into the code of New-Function CmdLet but first, let me credit the person who wrote that function.

I would really like to thank Jeff Patton for writing a collection of functions in PSISELibrary.ps1 that you can download here.

I have changed it a little bit to tune to my needs but let’s move on to the function code and explanation.

If you want to follow me along while I describe the function please download the zip file with the source code from here.

New-Function CmdLet source code is located in …/Modules/09addons/ folder and is part of CmdLet libraries that I have written and named Efficiency Booster PowerShell Project with the intention to help us IT people in our day to day IT tasks.

Source code location of New-Function CmdLet

At the bottom of this article, there is the source code of the New-Function for those who don’t want to download the zip file. Jump to that location by clicking this link.

First, we have comment-based help which explains what New-Function is and gives you some examples of how to use it.

Here is a code snippet of the New-Function CmdLet comment-based help.

    <#
        .SYNOPSIS
            Create a new function
        .DESCRIPTION
            This function creates a new function that wraps the selected text 
             inside the Process section of the body of the function.
        .PARAMETER SelectedText
            Currently selected code that will become a function
        .PARAMETER InstallMenu
            Specifies if you want to install this as a PSIE add-on menu
        .PARAMETER FunctionName
            This is the name of the new function.
        .EXAMPLE
            New-Function -FunctionName "New-ImprovedFunction"
            
            Description
            -----------
            This example shows calling the function with the FunctionName 
            parameter
        .EXAMPLE
            New-Function -InstallMenu $true
            
            Description
            -----------
            Installs the function as a menu item.
        .NOTES
            FunctionName    : New-Function
            Created by      : Jeff Patton
            Date Coded      : 09/13/2011 13:37:24
            Modified by     : Dejan Mladenovic
            Date Modified   : 03/09/2019 05:12:10
            More info       : https://improvescripting.com/
        .LINK
             
How To Write Advanced Functions Or CmdLets With PowerShell (Fast)
https://gallery.technet.microsoft.com/scriptcenter/PSISELibraryps1-ec442972 #>

INFO: To learn more about how to write your own comment-based help for your own PowerShell Advanced Functions or CmdLets please read How To Write PowerShell Help (Step by Step).

Just after Function declaration we have [CmdletBinding()] attribute which allows the use of PowerShell common parameters (Debug (db), ErrorAction (ea), ErrorVariable (ev), Verbose (vb), etc) with this function.

Function New-Function  
{  
    [CmdletBinding()]


Within param() construct we have 3 input parameters for this function:

  •  $SelectedText (This parameter will copy the code that we have written in the current tab of PowerShell ISE Script Pane and it will write that copied code into the PROCESS block of the function that we create )
  • $InstallMenu (It is a switch parameter if true it will add New-Function to the Windows PowerShell ISE Add-on Menu Item if false it will create the new function with template code)
  • $FunctionName (is a string parameter which is the name of the function that we want to create, in our example we create a function with name “New-ImprovedFunction”)
    Param
        (
        $SelectedText = $psISE.CurrentFile.Editor.SelectedText,
        $InstallMenu,
        $FunctionName
        )


BEGIN block runs only once and do two things:

  1. Creates a variable that holds our function template code. Here is the right spot to change that template if you need additional customization.
  2. It adds New-Function as Add-on Menu Item in Windows PowerShell ISE. Runs only once when we load this CmdLet via PowerShell profile.
    Begin
    {
        $TemplateFunction = @(
        "    <#`r`n"
        "       .SYNOPSIS`r`n"
        "       .DESCRIPTION`r`n"
        "       .PARAMETER`r`n"
        "       .EXAMPLE`r`n"
        "       .INPUTS`r`n"
        "       .OUTPUTS`r`n"
        "       .NOTES`r`n"
        "           FunctionName : $FunctionName`r`n"
        "           Created by   : $($env:username)`r`n"
        "           Date Coded   : $(Get-Date)`r`n"
        "       .LINK`r`n"
        "           https://improvescripting.com/`r`n"
        "    #>`r`n"
        "Function $FunctionName`r`n"
        "{`r`n"
        "[CmdletBinding()]`r`n"
        "Param`r`n"
        "    (`r`n"
        "    )`r`n"
        "Begin`r`n"
        "{`r`n"
        "    }`r`n"
        "Process`r`n"
        "{`r`n"
        "$($SelectedText)`r`n"
        "    }`r`n"
        "End`r`n"
        "{`r`n"
        "    }`r`n"
        "}`r`n"
        "    #region Execution examples`r`n"
        "    #endregion`r`n")
        if ($InstallMenu)
        {
            Write-Verbose "Try to install the menu item, and error out if there's an issue."
            try
            {
                $psISE.CurrentPowerShellTab.AddOnsMenu.SubMenus.Add("New function",{New-Function},"Ctrl+Alt+S") | Out-Null
                }
            catch
            {
                Return $Error[0].Exception
                }
            }
        }


PROCESS block (This is the code responsible for all the magic happening) 

  • NOTE: When the $InstallMenu variable (input parameter) is True this piece of code is not run. We set the $InstallMenu input parameter to True only when we want this function to be added to PowerShell ISE Add-ons Menu.
  • Otherwise, the code will insert the Function Template code into the current Tab of the Script Panel.
    Process
    {
        if (!$InstallMenu)
        {
            Write-Verbose "Don't create a function if we're installing the menu"
            try
            {
                Write-Verbose "Create a new empty function, return an error if there's an issue."
                $psISE.CurrentFile.Editor.InsertText($TemplateFunction)
                }
            catch
            {
                Return $Error[0].Exception
                }
            }
        }


END block is empty

    End
    {
        }


Finally, in the Execution examples region, we run the New-Function with InstallMenu input parameter true in order to add this function to the Windows PowerShell ISE Add-on Menu as Menu Item.

#region Execution examples
New-Function -InstallMenu $true
#endregion

How To Add New-Function CmdLet As Add-on Menu Item Into PowerShell ISE

Here are the steps that I have followed in order to have New-Function as an Add-on Menu Item in PowerShell ISE: (You have all this already done if you have downloaded the zip file with the source code.)

  • have created 09addons folder where my Modules are and for me, that was this location C:\Users\$env:USERNAME\[My] Documents\WindowsPowerShell\Modules
09 addons module folder
  • have saved New-Function as PowerShell script (.ps1 file) in 09addons folder
New-Function PowerShell Script (.ps1) in 09addons folder
  • have created and saved the PowerShell Script Module file (.psm1) in 09addons with the same name as the folder (09addons.psm1)
PowerShell Script module file (09addons.psm1)
  • have customized 09addons.psm1 module file with this line of code in order to load New-Function CmdLet into 09addons module:
. $psScriptRoot\New-Function.ps1 
The link between Function New-Function and Module 09addons
  • have customized Profile file (Microsoft.PowerShellISE_profile.ps1) location for me: (C:\Users\$env:USERNAME\[My] Documents\WindowsPowerShell) with this line of code in order to Import 09addons Module:
Import-Module 09addons
The link between PowerShell Profile and Module

What Happens When You Start PowerShell ISE?

If you wonder why was necessary to do all the steps from the previous section here is an explanation of PowerShell Workflow when every session starts. Hopefully, this will help you better understand previous steps.

When we open Windows PowerShell ISE here are things that happen in the background even before we see the ISE window:

  • The new PowerShell session starts for the current user.
  • PowerShell profile files have been loaded into the session (one of them is Microsoft.PowerShellISE_profile.ps1 that we have just customized).
  • The profile file will import modules. In our example, it will load the 09addons module among the others.
  • When the modules are imported the code inside the Script module file (.psm1) is executed. In our example, New-Function.ps1 script file will be executed
  • When the script file is executed New-Function CmdLet function is loaded into the session. In our example this code will be executed:
    New-Function -InstallMenu $true
    … and that will add New-Function as Add-On Menu Item in Windows PowerShell ISE so we can use it as we need it.
  • Finally, our environment is customized and we see Windows PowerShell ISE application with Add-on New-Function added into our environment and we can start working on the coding.

I hope this explains the previous steps.

New-Function Add-on Menu Item in Windows PowerShell ISE

How To Use New-Function CmdLet

We have several ways to exploit this fabulous CmdLet.

IMPORTANT: We always open a new tab in order to get blank Script Pane in Windows PowerShell ISE so automatically generated template code is created there.

  1. We can press Ctrl + Alt + S and this will create an Advanced Function template for us without function name that we need to fill out and start writing our code.
  2. We can go to menu Add-ons and choose New-Function menu item in Windows PowerShell ISE and this will do the same thing as in the previous example (look the screenshot below)
  3. We can write the call to New-Function CmdLet with parameter FunctionName string value provided for the name of function like in the example at the start of this post.
New-Function -FunctionName "New-ImprovedFunction" 

Press F8 or Ctrl + Alt + S and this will create our function with that name and template so we can start writing our code.

New-Function in Windows PowerShell ISE Add-on menu

Enjoy your PowerShell coding in a more efficient way!

Useful PowerShell Functions Articles

Here are some useful articles and resources:

New-Function CmdLet Code

Here is the source code of the whole New-Function Add-on CmdLet. Enjoy!

    <#
        .SYNOPSIS
            Create a new function
        .DESCRIPTION
            This function creates a new function that wraps the selected text inside
            the Process section of the body of the function.
        .PARAMETER SelectedText
            Currently selected code that will become a function
        .PARAMETER InstallMenu
            Specifies if you want to install this as a PSIE add-on menu
        .PARAMETER FunctionName
            This is the name of the new function.
        .EXAMPLE
            New-Function -FunctionName "New-ImprovedFunction"
            
            Description
            -----------
            This example shows calling the function with the FunctionName parameter
        .EXAMPLE
            New-Function -InstallMenu $true
            
            Description
            -----------
            Installs the function as a menu item.
        .NOTES
            FunctionName    : New-Function
            Created by      : Jeff Patton
            Date Coded      : 09/13/2011 13:37:24
            Modified by     : Dejan Mladenovic
            Date Modified   : 03/09/2019 05:12:10
            More info       : https://improvescripting.com/
        .LINK
            
How To Write Advanced Functions Or CmdLets With PowerShell (Fast)
https://gallery.technet.microsoft.com/scriptcenter/PSISELibraryps1-ec442972 #> Function New-Function { [CmdletBinding()] Param ( $SelectedText = $psISE.CurrentFile.Editor.SelectedText, $InstallMenu, $FunctionName ) Begin { $TemplateFunction = @( " <#`r`n" " .SYNOPSIS`r`n" " .DESCRIPTION`r`n" " .PARAMETER`r`n" " .EXAMPLE`r`n" " .INPUTS`r`n" " .OUTPUTS`r`n" " .NOTES`r`n" " FunctionName : $FunctionName`r`n" " Created by : $($env:username)`r`n" " Date Coded : $(Get-Date)`r`n" " .LINK`r`n" " https://improvescripting.com/`r`n" " #>`r`n" "Function $FunctionName`r`n" "{`r`n" "[CmdletBinding()]`r`n" "Param`r`n" " (`r`n" " )`r`n" "Begin`r`n" "{`r`n" " }`r`n" "Process`r`n" "{`r`n" "$($SelectedText)`r`n" " }`r`n" "End`r`n" "{`r`n" " }`r`n" "}`r`n" " #region Execution examples`r`n" " #endregion`r`n") if ($InstallMenu) { Write-Verbose "Try to install the menu item, and error out if there's an issue." try { $psISE.CurrentPowerShellTab.AddOnsMenu.SubMenus.Add("New function",{New-Function},"Ctrl+Alt+S") | Out-Null } catch { Return $Error[0].Exception } } } Process { if (!$InstallMenu) { Write-Verbose "Don't create a function if we're installing the menu" try { Write-Verbose "Create a new empty function, return an error if there's an issue." $psISE.CurrentFile.Editor.InsertText($TemplateFunction) } catch { Return $Error[0].Exception } } } End { } } #region Execution examples New-Function -InstallMenu $true #endregion

Well done PowerShell Jedi you read the whole article!

About Dejan Mladenović

Hey Everyone! I hope that this article you read today has taken you from a place of frustration to a place of joy coding! Please let me know of anything you need for Windows PowerShell in the comments below that can help you achieve your goals!
I have 18+ years of experience in IT and you can check my Microsoft credentials. Transcript ID: 750479 and Access Code: DejanMladenovic
Credentials
About Me...

My Posts | Website

Dejan Mladenović

Hey Everyone! I hope that this article you read today has taken you from a place of frustration to a place of joy coding! Please let me know of anything you need for Windows PowerShell in the comments below that can help you achieve your goals! I have 18+ years of experience in IT and you can check my Microsoft credentials. Transcript ID: 750479 and Access Code: DejanMladenovic
Credentials About Me...

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Recent Content