Earlier this week I shared my techniques for creating a Windows Terminal profile that would open a remote PowerShell session. But with PowerShell 7, I can also connect to non-Windows machines using SSH. So why not extend my code to allow connecting to a Linux box? Before you try anything that I'm going to share, make sure you can manually create and enter a PSSession to your Linux target using SSH. If you can do that, then you can create a Windows Terminal profile.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
The Connection Script
I modified my existing script to create the remoting session. Because I'll have to invoke pwsh instead of powershell, I could have created a second script with the proper parameters. But then I'd have to scripts to maintain. So instead, I modified my wtpsremote.ps1 script and used parameter sets.
I've updated the script to also include verbose messages which help when troubleshooting. And better error handling.
#requires -version 5.1
<#
.Synopsis
Create a remote PowerShell session
.Description
This script is intended to be called from a Windows Terminal profile to create
a PowerShell remoting session. If you are using the ssh parameter set, you
will need to invoke this script with pwsh.
.Link
New-PSSession
.Link
Enter-PSSession
#>
[cmdletbinding(DefaultParameterSetName = "Computer")]
Param(
[Parameter(Position = 0, Mandatory, HelpMessage = "Specify remote computer name",ParameterSetName="Computer")]
[ValidateNotNullOrEmpty()]
[string]$Computername,
[Parameter(ParameterSetName="Computer")]
[pscredential]$Credential,
[Parameter( HelpMessage = "A profile script to run in the remote session")]
[ValidateScript( {Test-Path $_})]
[string]$RemoteProfile,
[Parameter(HelpMessage = "Specify a remote endpoint other than the default Microsoft.powershell")]
[string]$ConfigurationName,
[Parameter(HelpMessage = "Specify an alternate port number")]
[int32]$Port,
[Parameter(ParameterSetName="Computer")]
[switch]$UseSSL,
[Parameter(Position = 0, Mandatory,ParameterSetName = "ssh")]
[ValidateNotNullorEmpty()]
[string]$Hostname,
[Parameter(ParameterSetName = "ssh")]
[string]$Username,
[Parameter(ParameterSetName = "ssh")]
[string]$Subsystem,
[Parameter(ParameterSetName = "ssh")]
[string]$KeyFilePath
)
Write-Verbose "Starting $($MyInvocation.MyCommand)"
Write-Verbose "Using parameter set $($pscmdlet.parametersetname)"
if ($PSCmdlet.ParameterSetName -eq "ssh") {
Write-Verbose "adding SSHTransport parameter"
[void]($PSBoundParameters.add("SSHTransport",$True))
}
#remove this this parameter if specified since it can't be used to create a new PSSession
if ($PSBoundParameters.ContainsKey("RemoteProfile")) {
Write-Verbose "Removing RemoteProfile bound parameter"
[void]($PSBoundParameters.Remove("RemoteProfile"))
}
#Create a new remoting session splatting the parameters passed to this script
Try {
Write-Verbose "Using these parameters to create the PSSession"
$PSBoundParameters | Out-String | Write-Verbose
$remote = New-PSSession @PSBoundParameters -errorAction Stop
$remote | Out-String | Write-Verbose
}
Catch {
Write-Verbose "Failed to create remoting session"
Throw $_
}
#run the remote profile script
if ($RemoteProfile) {
Write-Verbose "Running remote profile script $RemoteProfile"
Invoke-Command -Session $remote -FilePath $RemoteProfile -HideComputerName |
Select-Object -property * -ExcludeProperty runspaceID
}
#open the pssession
Write-Verbose "Entering session"
Enter-PSSession -session $remote
$msg = @"
-------------------------------------------------------------------------------------
| Reminder: |
| Remove the `$remote pssession after you exit and before you close the profile tab. |
| |
| PS C:\> `$remote | Remove-PSSession |
| PS C:\> exit |
-------------------------------------------------------------------------------------
"@
#you may need to adjust colors based on your profile settings
Write-host $msg -ForegroundColor Magenta -BackgroundColor Gray
The Windows Terminal Profile
With this script I can create a Windows Terminal profile for my Linux session.
{
"acrylicOpacity": 0.8,
"closeOnExit": true,
"colorScheme": "Campbell",
"commandline": "C:\\Program Files\\PowerShell\\7-preview\\preview\\pwsh-preview.cmd -nologo -noprofile -noexit -file c:\\scripts\\wtpsremote.ps1 -hostname fred-company-com -username jeff -remoteprofile c:\\scripts\\lxprofile.ps1",
"cursorColor": "#FFFFFF",
"cursorShape": "underscore",
"fontFace": "Cascadia Code",
"fontSize": 14,
"guid": "{5668446e-620a-448f-874b-db766831b2ab}",
"historySize": 9001,
"icon": "ms-appx:///ProfileIcons/{574e775e-4f2a-5b96-ac1e-a2962a402336}.png",
"name": "Fred",
"padding": "0, 0, 0, 0",
"snapOnInput": true,
"startingDirectory": "C:\\",
"tabTitle": "PSRemote: Fred",
"backgroundImage": "C:\\users\\jeff\\Pictures\\smoking-penguin.jpg",
"backgroundImageAlignment": "center",
"backgroundImageStretchMode": "none",
"backgroundImageOpacity": 0.3,
"useAcrylic": true
}
Eventually, I will update this profile to use the final path to pwsh.
The Linux Profile Script
I'm still offering the option to run a remote profile script. It is still a PSSession after all. This is the script file I use for my Linux connections.
# this is for Linux based computers
$os = $PSVersionTable.OS
$lsb = lsb_release -d
$osver = ($lsb -split ":")[1].Trim()
$elevated = "N/A"
$user = [System.Environment]::UserName
$computer = [System.Environment]::MachineName
#object properties will be displayed in the order they are listed here
[pscustomObject]@{
User = $user
Elevated = $elevated
Computername = $computer
OperatingSystem = $os
OSVersion = $osver
PSVersion = $PSVersionTable.PSVersion.ToString()
Edition = $PSVersionTable.PSEdition
PSHost = $host.Name
WSMan = $PSVersionTable.WSManStackVersion.ToString()
ExecutionPolicy = (Get-ExecutionPolicy)
Culture = [System.Globalization.CultureInfo]::CurrentCulture.NativeName
}
$initiated = Get-Date
$remotePrompt = {
#display the session runtime without the milliseconds
$ts = ((Get-Date) - $initiated).ToString().split(".")[0]
Write-Host ">$ts< " -ForegroundColor yellow -nonewline "PS $($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1)) ";
}
Set-Item -Path function:\prompt -Value $remotePrompt -Force
I'm using the same prompt concept to show how long the session has been running. Here's the end result
At this point, I can use Windows Terminal for all of my PowerShell remoting needs and have everything I need in one place. I hope you'll let me know what you think of these updates.
1 thought on “Cross Platform PowerShell Profiles with Windows Terminal”
Comments are closed.