Switch-Prompt.ps1


<#PSScriptInfo
 
.VERSION 1.0.0
 
.GUID 9582674c-0024-41d0-a3a3-393d8bf440f6
 
.AUTHOR tommymaynard
 
.COMPANYNAME
 
.COPYRIGHT
 
.TAGS Prompt
 
.LICENSEURI
 
.PROJECTURI
 
.ICONURI
 
.EXTERNALMODULEDEPENDENCIES
 
.REQUIREDSCRIPTS
 
.EXTERNALSCRIPTDEPENDENCIES
 
.RELEASENOTES
 
 
.PRIVATEDATA
 
#>


<#
 
.DESCRIPTION
 This advanced function can switch between the standard PowerShell prompt, as well as a Linux and LinuxCustom prompt.
 
#>
 

Param()


Function Switch-Prompt {
<#
.SYNOPSIS
    This advanced function can switch between the standard PowerShell prompt, as well as a Linux and LinuxCustom prompt.
.PARAMETER Type
    The Type parameter can accept three parameter values: Standard, Linux, and LinuxCustom. These indicate which included prompt to use.
.PARAMETER FullPath
    The FullPath parameter is a dynamic parameter that is available when either Linux or LinuxCustom are used as the value for the Type parameter. This parameter ensures the path to the current directory is full, to include the drive letter and full path.
.PARAMETER Version
    The Version parameter is a dynamic parameter that is available when either Linux or LinuxCustom are used as the value for the Type parameter. This parameter ensures the version of PowerShell is indicated between the closing square bracket of either Linux prompt and the dollar sign ($) or hash symbol (#).
.PARAMETER UserName
    The UserName parameter is a dynamic parameter that is only available when LinuxCustom is used as the value for the Type parameter. This parameter allows a user to choose what username to display within the prompt.
.PARAMETER ComputerName
    The ComputerName parameter is a dynamic parameter that is only available when LinuxCustom is used as the value for the Type parameter. This parameter allows a user to choose what computer name to display within the prompt.
.EXAMPLE
    PS > Switch-Prompt -Type Standard
    PS C:\Program Files\7-Zip\Lang>
    This example switches to the standard PowerShell prompt. It can also be invoked without the parameter and parameter value and have the same results.
.EXAMPLE
    PS > Switch-Prompt -Type Linux
    [tommymaynard@tmlaptop Lang]$
    This example switches to the Linux PowerShell prompt.
.EXAMPLE
    PS > Switch-Prompt -Type Linux -FullPath -Version
    [tommymaynard@tmlaptop c/Program Files/7-Zip/Lang]5.1.1$
    This example switches to the Linux PowerShell prompt and includes the full path and version.
.EXAMPLE
    PS > Switch-Prompt -Type LinuxCustom -UserName tm -ComputerName srvx -Version
    [tm@srvx Lang]5.1.1$
    This example switches to the custom Linux PowerShell prompt and includes the version. Additionally, it includes a custom username and computer name.
.NOTES
    Name: Switch-Prompt
    Author: Tommy Maynard
    Comments: This function creates two, or four, dynamic parameters depending on whether Linux or LinuxCustom is used as the value for the Type parameter. These may include FullPath, Version, UserName, and ComputerName. These will not show up using Get-Help; therefore, it is recommended to view the script's contents to learn more about these parameter.
    Last Edit: 03/29/2019 [1.0.0]
    Version: 1.0.0
#>

    Param(
        [Parameter()]
        [ValidateSet('Standard','Linux','LinuxCustom')]
        [string]$Type = 'Standard'
    )

    DynamicParam {
        $SingleAttribute = New-Object System.Management.Automation.ParameterAttribute
        $AttributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
        $AttributeCollection.Add($SingleAttribute)
        $ParamDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
        Switch ($PSBoundParameters) {
            {$_['Type'] -eq 'LinuxCustom'} {
                $UserParameter = New-Object System.Management.Automation.RuntimeDefinedParameter('UserName',[string],$AttributeCollection)
                $UserParameter.Value = 'fake_user'
                $ParamDictionary.Add('UserName',$UserParameter)
                $ComputerParameter = New-Object System.Management.Automation.RuntimeDefinedParameter('ComputerName',[string],$AttributeCollection)
                $ComputerParameter.Value = 'fake_computer'
                $ParamDictionary.Add('ComputerName',$ComputerParameter)
            } # End Action.
            {$_['Type'] -eq 'Linux' -or $_['Type'] -eq 'LinuxCustom'} {
                $FullPathParameter = New-Object System.Management.Automation.RuntimeDefinedParameter('FullPath',[switch],$AttributeCollection)
                $ParamDictionary.Add('FullPath',$FullPathParameter)
                $VersionParameter = New-Object System.Management.Automation.RuntimeDefinedParameter('Version',[switch],$AttributeCollection)
                $ParamDictionary.Add('Version',$VersionParameter)
            } # End Action.
        } # End Switch.
        return $ParamDictionary
    } # End DynamicParam.

    Begin {
        #region Remove default parameters.
        $PSDefaultParameterValues.Remove('prompt:type')
        $PSDefaultParameterValues.Remove('prompt:username')
        $PSDefaultParameterValues.Remove('prompt:computername')
        $PSDefaultParameterValues.Remove('prompt:fullpath')
        $PSDefaultParameterValues.Remove('prompt:version')
        #endregion.
    } # End Begin.

    Process {
        #region Add relavant default parameters.
        $PSDefaultParameterValues.Add('prompt:type',$Type)

        If ($PSBoundParameters['Type'] -eq 'LinuxCustom') {
            $PSDefaultParameterValues.Add('prompt:username',$ParamDictionary.UserName.Value)
            $PSDefaultParameterValues.Add('prompt:computername',$ParamDictionary.ComputerName.Value)
        } # End If.
        
        If ($PSBoundParameters['FullPath'] -eq $true) {
            $PSDefaultParameterValues.Add('prompt:fullpath',$true)
        } Else {
            $PSDefaultParameterValues.Add('prompt:fullpath',$false)
        } # End If-Else.

        If ($PSBoundParameters['Version'] -eq $true) {
            $PSDefaultParameterValues.Add('prompt:version',$true)
        } Else {
            $PSDefaultParameterValues.Add('prompt:version',$false)
        } # End If-Else.
        #endregion.
    } # End Process.

    End {
        #region Create prompt.
        Function Global:Prompt {
            Param (
            )

            Begin {
            } # End Begin.

            Process {
                #region Set PSDrive Home.
                (Get-PSProvider -PSProvider FileSystem).Home = $env:USERPROFILE
                #endregion.

                #region Determine Admin/Root and set symbol.
                If ($PSVersionTable.Platform -eq 'Unix') {
                    If ((id -u) -eq 0) {
                        $Symbol = '#'
                    } Else {
                        $Symbol = '$'
                    } # End If-Else.
                } ElseIf ($PSVersionTable.PSVersion.Major -le 5 -or $PSVersionTable.Platform -eq 'Win32NT') {
                    If ([bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).Groups -match 'S-1-5-32-544')) {
                        $Symbol = '#'
                    } Else {
                        $Symbol = '$'
                    } # End If-Else.
                } # End If-ElseIf-Else.
                #endregion.

                #region Write Path to Location as /.../...
                If ($PWD.Path -eq $env:USERPROFILE) {
                    $Location = '/~'
                } ElseIf ($PWD.Path -like "*$env:USERPROFILE*") {
                    $Location = "/$($PWD.Path -replace ($env:USERPROFILE -replace '\\','\\'),'~' -replace '\\','/')"
                } Else {
                    $Location = "$(($PWD.Path -replace '\\','/' -split ':')[-1])"
                } # End If-ElseIf.
                #endregion.

                #region Determine file system location.
                $Location = "$((Get-Location).Drive.Name.ToLower())$Location"
                #endregion.

                #region Shorten path.
                If (-Not($PSDefaultParameterValues['prompt:fullpath'])) {
                    $Location = ($Location -split '/')[-1]
                    # Fix path if too short.
                    If ($Location.Length -eq 0) {
                        $Location = '/'
                    } # End If.
                } # End If.
                #endregion.

                #region Determine host for WindowTitle.
                Switch ($Host.Name) {
                    'ConsoleHost' {$HostName = 'consolehost'; break}
                    'Windows PowerShell ISE Host' {$HostName = 'ise'; break}
                    'Visual Studio Code Host' {$HostName = 'vscode'; break}
                    default {$HostName = $Host.Name.ToLower()}
                } # End Switch.
                #endregion.

                #region Determine PowerShell version.
                If ($PSDefaultParameterValues['prompt:version']) {
                    If ($PSVersionTable.PSVersion.Major -le 5) {
                        $PSVer = "$($PSVersionTable.PSVersion.Major).$($PSVersionTable.PSVersion.Minor).$($PSVersionTable.PSVersion.Build)"
                    } ElseIf ($PSVersionTable.PSVersion.Major -ge 6) {
                        $PSVer = "$($PSVersionTable.PSVersion.Major).$($PSVersionTable.PSVersion.Minor).$($PSVersionTable.PSVersion.Patch)"
                    } # End If-ElseIf.
                    $PSVer = $PSVer.Substring(0,5)
                } Else {
                    $PSVer = $null
                } # End If-Else.
                #endregion.

                #region Determine if in the debugger.
                If (Test-Path -Path Variable:/PSDebugContext) {
                    $DebugStart = '[DBG]: '
                    $DebugEnd = ']'
                } # End If.
                #endregion.

                #region Determine Real vs. Fake prompt.
                If ($PSDefaultParameterValues['prompt:type'] -eq 'Standard') {
                    "PS $($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1)) "

                } ElseIf ($PSDefaultParameterValues['prompt:type'] -eq 'Linux') {
                    # Actual prompt and title.
                    $UserComputer = "$($env:USERNAME.ToLower())@$($env:COMPUTERNAME.ToLower())" 
                    $Host.UI.RawUI.WindowTitle = "$HostName $PSver`: $DebugStart[$UserComputer $Location]$DebugEnd$Symbol"
                    "$DebugStart[$UserComputer $Location]$DebugEnd$PSVer$Symbol "

                } ElseIf ($PSDefaultParameterValues['prompt:type'] -eq 'LinuxCustom') {
                    # Alternate prompt and title.
                    $UserName = $PSDefaultParameterValues['prompt:username']
                    $ComputerName = $PSDefaultParameterValues['prompt:computername']
                    $UserComputer = "$UserName@$ComputerName"
                    $Host.UI.RawUI.WindowTitle = "$HostName $PSver`: [$UserComputer $Location]$Symbol"
                    "$DebugStart[$UserComputer $Location]$DebugEnd$PSVer$Symbol "
                } # End If-ElseIf-ElseIf.
                #endregion.
            } # End Process.

            End {
            } # End End.
        } # End Function: prompt.
        #endregion.
    } # End End.
} # End Function: Switch-Prompt.