<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Caroline Chiari]]></title><description><![CDATA[Caroline Chiari]]></description><link>https://blog.carolinechiari.com</link><generator>RSS for Node</generator><lastBuildDate>Tue, 05 May 2026 16:52:46 GMT</lastBuildDate><atom:link href="https://blog.carolinechiari.com/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[A better PowerShell Console Menu]]></title><description><![CDATA[I was looking to add a console-based menu to give the users of my scripts choices.
I have worked with PowerShell for years, and most of the time, I needed to give users a choice; I either added it as an argument when running the script or used the cl...]]></description><link>https://blog.carolinechiari.com/a-better-powershell-console-menu</link><guid isPermaLink="true">https://blog.carolinechiari.com/a-better-powershell-console-menu</guid><category><![CDATA[Powershell]]></category><category><![CDATA[Script]]></category><category><![CDATA[menu]]></category><dc:creator><![CDATA[Caroline Chiari]]></dc:creator><pubDate>Fri, 26 Aug 2022 20:50:32 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1661546957036/juP2Tpm33.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I was looking to add a console-based menu to give the users of my scripts choices.
I have worked with PowerShell for years, and most of the time, I needed to give users a choice; I either added it as an argument when running the script or used the classic "enter 1 for option A, 2 for option B" model. I've never liked either option, but they were good enough at the time.</p>
<p>So, I did like anyone would have done, and I googled how to create a PowerShell menu. I found very few examples of people creating interactive menus, but there were no tutorials, just code to download. So I took on the challenge of creating an interactive PowerShell menu from scratch and sharing the process with you.</p>
<h2 id="heading-design-considerations">Design Considerations</h2>
<p>Like any good engineering project, let's start with a design doc to keep in mind when creating the script.</p>
<ul>
<li>Users shouldn't have to edit the code for the menu (requires input).</li>
<li>Users should select the options using the up and down keyboard arrows and press enter to select the desired option.</li>
<li>When selecting a value, the menu should highlight the selected option line.</li>
<li>The menu should return the selected value.</li>
<li>The menu should not clear the console.</li>
</ul>
<h2 id="heading-pseudocode">Pseudocode</h2>
<p>I usually do this part in my head, but since it is an important part of the process, I figured I would highlight it:</p>
<ol>
<li>Get the options from the user</li>
<li>Set the current selection to the first item in the list of options</li>
<li>Print all the lines in the console</li>
<li>Wait for Arrow Up or Arrow Down or Enter Keys to be pressed<ul>
<li>if Arrow up is pressed, store the new selected option position (current selection - 1)</li>
<li>if Arrow Down is pressed, store the new selected option position (current selection + 1)</li>
</ul>
</li>
<li>Return the selected option</li>
<li>If the selection is out of bound, set it to the proper position (0 or # of options - 1)</li>
<li>Go back to #3</li>
</ol>
<h2 id="heading-the-code">The code</h2>
<pre><code class="lang-PowerShell">&lt;#
    .SYNOPSIS
        Displays a selection menu and returns the selected item

    .DESCRIPTION
        Takes a list of menu items, displays the items, and returns the user's selection.
        Items can be selected using the up and down arrow and the enter key.

    .PARAMETER MenuItems
        List of menu items to display

    .PARAMETER MenuPrompt
        Menu prompt to display to the user.

    .EXAMPLE
        PS C:\&gt; Get-MenuSelection -MenuItems $value1 -MenuPrompt 'Value2'

    .NOTES
        Additional information about the function.
#&gt;
function Get-MenuSelection {
    [CmdletBinding()]
    [OutputType([string])]
    param
    (
        [Parameter(Mandatory = $true)]
        [ValidateNotNullOrEmpty()]
        [String[]]$MenuItems,
        [Parameter(Mandatory = $true)]
        [String]$MenuPrompt
    )
    # store initial cursor position
    $cursorPosition = $host.UI.RawUI.CursorPosition
    $pos = 0 # current item selection

    #==============
    # 1. Draw menu
    #==============
    function Write-Menu {
        param (
            [int]$selectedItemIndex
        )
        # reset the cursor position
        $Host.UI.RawUI.CursorPosition = $cursorPosition
        # Padding the menu prompt to center it
        $prompt = $MenuPrompt
        $maxLineLength = ($MenuItems | Measure-Object -Property Length -Maximum).Maximum + 4
        while ($prompt.Length -lt $maxLineLength + 4) {
            $prompt = " $prompt "
        }
        Write-Host $prompt -ForegroundColor Green
        # Write the menu lines
        for ($i = 0; $i -lt $MenuItems.Count; $i++) {
            $line = "    $($MenuItems[$i])" + (" " * ($maxLineLength - $MenuItems[$i].Length))
            if ($selectedItemIndex -eq $i) {
                Write-Host $line -ForegroundColor Blue -BackgroundColor Gray
            }
            else {
                Write-Host $line
            }
        }
    }

    Write-Menu -selectedItemIndex $pos
    $key = $null
    while ($key -ne 13) {
        #============================
        # 2. Read the keyboard input
        #============================
        $press = $host.ui.rawui.readkey("NoEcho,IncludeKeyDown")
        $key = $press.virtualkeycode
        if ($key -eq 38) {
            $pos--
        }
        if ($key -eq 40) {
            $pos++
        }
        #handle out of bound selection cases
        if ($pos -lt 0) { $pos = 0 }
        if ($pos -eq $MenuItems.count) { $pos = $MenuItems.count - 1 }

        #==============
        # 1. Draw menu
        #==============
        Write-Menu -selectedItemIndex $pos
    }

    return $MenuItems[$pos]
}
</code></pre>
<p>The key to this code is <code>$host.UI.RawUI.CursorPosition</code> this property allows you to read or move the cursor in the console to the desired location. It is basically the same idea as <code>Clear-Host</code>, except <code>Clear-Host</code> resets it to the 0,0 position.</p>
]]></content:encoded></item><item><title><![CDATA[What's in my PowerShell profile again?]]></title><description><![CDATA[I know I'm not the only one who encountered this issue before: You write some helper functions in your PowerShell profile, but can't remember what there are. So you have to go back in your profile to see what's in there.
I've been trying to find a so...]]></description><link>https://blog.carolinechiari.com/whats-in-my-powershell-profile-again</link><guid isPermaLink="true">https://blog.carolinechiari.com/whats-in-my-powershell-profile-again</guid><category><![CDATA[Script]]></category><category><![CDATA[Powershell]]></category><dc:creator><![CDATA[Caroline Chiari]]></dc:creator><pubDate>Sat, 19 Feb 2022 01:19:16 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1645235455535/09lQIha6b.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I know I'm not the only one who encountered this issue before: You write some helper functions in your PowerShell profile, but can't remember what there are. So you have to go back in your profile to see what's in there.</p>
<p>I've been trying to find a solution to this problem for quite a while. My first thought was to use <code>Get-Command</code>, but that does not give you whether or not a command comes from the profile.</p>
<p>My second try was to add a tag in the function definition, use <code>Get-Command</code> to parse the function definitions for that tag.</p>
<p>Bu then, I had an epiphany, and wrote this little piece of code:</p>
<pre><code class="lang-PowerShell">Write-Host "Available Profile Functions:" -ForegroundColor Green
$profileData = Get-Content $profile
$profileData += Get-Content $profile.AllUsersAllHosts -ErrorAction SilentlyContinue
$profileData += Get-Content $profile.AllUsersCurrentHost -ErrorAction SilentlyContinue
$profileData -match "^function" `
| ForEach-Object { $_.split(" ")[1] } `
| Sort-Object -Unique `
| ForEach-Object { Write-Host "`t$_" -ForegroundColor Green }
</code></pre>
<p>So what does this do?</p>
<p>The basic idea is as follows:</p>
<ol>
<li>Get the contents of the $profile files that could be loaded in the current host.</li>
<li>Get all the lines that start with the keyword <code>function</code></li>
<li>Split the line and only keep the function name</li>
<li>Keep only the unique names</li>
<li>Print the functions at the start of the console session</li>
</ol>
<p>I hope this will help you use your PowerShell profile more efficiently.</p>
]]></content:encoded></item></channel></rss>