Tag Archives: WindowsTitle

Dynamic PowerShell Version in Windows Terminal Tabs Part II

Maybe no one noticed. Or, maybe they did and just didn’t say anything. As you’ll see, I’ve written a quick fix to a post I wrote last week.

I shouldn’t have, but back in Part I, I put reliance on my prompt function for the Windows Terminal tab titles. This means that I have to ensure that I never change my prompt function. If I do, it’s very possible that adding the version of PowerShell to the tab titles will break. This isn’t good. That dependence, while it works just fine now, could become a problem in time.

Knowing that, let’s remove it. Let’s get the version in the Windows Terminal tab titles from something other than my prompt. Let’s put it where it belongs, on the version itself — on the $PSVersionTable automatic variable. My prompt Itself uses that, so why shouldn’t this Windows Terminal tab title code, too? This makes much more sense than coupling the tab titles with my prompt function.

$Host.UI.RawUI.WindowTitle = "$($Host.UI.RawUI.WindowTitle) $($PSVersionTable.PSVersion.ToString())"

The tabs look exactly like they did before, but now my prompt function doesn’t play into the versions making their way to the tabs at all. Altering the prompt doesn’t matter now, or now, at any time in the future.

Dynamic PowerShell Version in Windows Terminal Tabs

There’s a Part II to this post now, be sure to read it after you’ve read this post.

I find myself inside the Window Terminal’s JSON Settings file each time I update the version of PowerShell on my system. That includes non-preview and preview versions of PowerShell. Well, as of today, that’s changed. Previously I would install an updated version, jump into the JSON Settings file, and modify the Name and TabTitle properties of the corresponding profile. I’ve long wanted the version number on the Tab and so I was hard coding the values. No longer.

Let’s take a look at my prompt function. It’s mostly the default one, with some slight changes. Here’s the prompt code from my $PROFILE. Preview version or not, they both use the same $PROFILE script; therefore, they use the same prompt function.

Function Prompt {
    "$("[PS$($PSVersionTable.PSVersion.ToString())][$($executionContext.SessionState.Path.CurrentLocation)]" * ($nestedPromptLevel + 1)) ";
    # .Link
    # https://go.microsoft.com/fwlink/?LinkID=225750
    # .ExternalHelp System.Management.Automation.dll-help.xml
} # End Function: Prompt.

Here’s how the prompt renders in both the non-preview and preview versions of PowerShell.



What I do, and you’ll see it momentarily is extract the version number — “7.1.3” and “7.2.0-preview.4” from the above prompts and write them to the WindowTitle along with what was already there (the word “PowerShell”). The below code is beneath the Prompt function in my $PROFILE script.

$Prompt = prompt
$Host.UI.RawUI.WindowTitle = "$($Host.UI.RawUI.WindowTitle) $(($Prompt.Split('][').TrimStart('[PS')[0]))"

First, it captures the prompt into a variable called Prompt. Then it manipulates the contents of the variable until we only have what we want. This first thing it does consists of splitting the prompt string at the back-to-back closing and opening square brackets: “][“. In the case of the non-preview prompt, this leaves me with two strings: [PS7.1.3 and C:\]. Next, it trims off the [PS from the start of the first of the two strings. As you can tell, we only have an interest in our first string — the value in the zero index: [0]. Once’s the parsing is complete, our value is appended to the existing value in the WindowTitle property and it is all written back to the WindowTitle property.

It’s from here forward that the title includes not just the word “PowerShell,” but also the version. That’s it. A little extra work now to remove all the work from later on.

There’s a Part II to this post now, be sure to read it.

Script Sharing – Functions and Code from My Profile

Over the last couple of years, my profile ($PROFILE) has filled up with a bunch of little functions that I use to help shave seconds off my day. I’ve shared a few in other posts, but here’s a few more that I’ve yet to share, that might be interesting. As a forewarning, in many of these, I understand that there may be a better way to do things.

This first one uses Google to show me the definition of a word. It isn’t written to return results to the Windows PowerShell console, but instead will launch the definition in a web browser. It was good enough at the time, and still is on a occasion (when I don’t actually know what a word means ;)) .

Set-Alias -Name lookup -Value Get-Definition
Function Get-Definition {
    Param (
        [Parameter(Mandatory = $true)]
        [string]$Word
    )
        Start-Process "https://www.google.com/?gws_rd=ssl#q=define:$Word"
}

Here’s an example I just used today, when I read Don Jones’ post about Jeffrey Snover’s promotion to Technical Fellow: http://donjones.com/2015/09/02/congratulations-jsnover-a-well-earned-honor.

Functions and Code from my Profile ($PROFILE)01

And, because why not, here’s a photo of Jeffrey Snover and me. For those of you new to PowerShell, I’m on the right; Snover, PowerShell’s inventor, is on the left. Thanks to PowerShell.org and Will for the photo.

Me and Snover (front)

This next inclusion isn’t a function, but has turned out to be quite helpful. I recently posted it on Twitter. By entering the alias “snip” into the console, I’m able to quickly open the snipping tool. In fact, I just used the alias to grab the screen capture, for the Get-Definition function, above.

Set-Alias -Name snip -Value "$env:SystemRoot\system32\SnippingTool.exe"

Here’s a screen capture of the Snipping Tool program.

Functions-and-Code-from-my-Profile-PROFILE02

This next one is also not a function, but extremely helpful, and likely to be some of the oldest code in my profile. This, while quite small, saves me all the time. Here’s how it works: When the PowerShell console opens, it checks the title bar — the WindowsTitle — for any left or right square brackets: this [, or this ]. If it doesn’t find them, it then modifies the WindowsTitle to include my computer’s name inside square brackets. It is extremely handy to be able to quickly verify that I’m typing in to the console on my machine and not inside a console on a RDP session. Yes, I still RDP for some things, and yes, I will also, at times, open a PowerShell console inside the RDP session (as strange as that may be).

# Set Console Window Title
If (-not($Host.UI.RawUI.WindowTitle -like "*`[*`]*")) {
    $Host.UI.RawUI.WindowTitle += " [$($env:COMPUTERNAME)]"
}

Since I’ll occasionally take and upload screen captures (see the first example, above), I wanted a quick way to remove my edited WindowsTitle, so it didn’t show my computer’s name. That gave way to this micro function to return the WindowsTitle to its default (yes, it’s hard coded) — my console is always elevated (however, the log on to my computer is not). I suppose what I should do, is assign the default text, when the console is first opened, and before the WindowsTitle is changed, into a variable for later use in this function.

# Set Default Console Window Title
Function Set-WindowTitleDefault {
    $Host.UI.RawUI.WindowTitle = 'Administrator: Windows PowerShell'
}

The last function I’ll share today is called Get-PSRemotingSession and it allows me to see if anyone is actively using PowerShell Remoting on a specific computer, or computers. It’s basically a wrapper function for Get-WSManInstance (without having to remember the required parameters).

Function Get-PSRemotingSession([string[]]$ComputerName) {
    Foreach ($C in $ComputerName) {
        Get-WSManInstance -ComputerName $C -ResourceURI Shell -Enumerate | Select-Object -Property Owner,ClientIP
    }
}

That’s all I’ve got for today. I hope that some of these might have been helpful enough to incorporate into your profile. If there’s things you can’t live without in your profile, that you want to share, then comment below, or share them on Twitter.

Update: The last function I introduced, Get-PSRemotingSession, has been updated. Only returning the Owner and ClientIP was fine when I only ran it against a single computer. The problem, when I ran it against multiple computers, is that I didn’t know the name of the computer that had the remote session — it wasn’t included in the output. Therefore, I updated the function, as seen below, so that it’ll indicate the computer name. It can’t get the computer name as part of what’s returned from Get-WSManInstance (without resolving the ClientIP), but it can based on which computer it’s checking to begin with (the value in $C). Here’s the updated version:

Function Get-PSRemotingSession([string[]]$ComputerName) {
    Foreach ($C in $ComputerName) {
        Get-WSManInstance -ComputerName $C -ResourceURI Shell -Enumerate | Select-Object -Property @{N='ComputerName';E={$C}},Owner,ClientIP
    }
}