Switch-Prompt.ps1


<#PSScriptInfo
 
.VERSION 1.1.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 a minimal PowerShell prompt, the standard PowerShell prompt, as well as a Linux, and LinuxCustom prompt.
 
#>
 

Param()


Function Switch-Prompt {
<#
.SYNOPSIS
    This advanced function can switch between a minimal PowerShell prompt, the standard PowerShell prompt, as well as a Linux, and LinuxCustom prompt.
.PARAMETER Type
    The Type parameter can accept four parameter values: Minimal, Standard, Linux, and LinuxCustom. These indicate which included type of prompt to use.
.PARAMETER FullPath
    The FullPath parameter is a dynamic parameter that is available when either Linux or the LinuxCustom prompt are used as the value for the Type parameter. This parameter ensures the path to the current directory includes the drive letter and full path.
.PARAMETER Version
    The Version parameter is a dynamic parameter that is available when either Linux or the LinuxCustom prompt 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 C:\Program Files\7-Zip\Lang> Switch-Prompt -Type Minimal
    PS>
    This example switches to a minimal PowerShell 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. The FullPath and Version parameters can be used together, or independently.
.EXAMPLE
    PS > Switch-Prompt -Type LinuxCustom -FullPath
    [fake_user@fake_computer c/Program Files/7-Zip/Lang]$
    This example switches to the custom Linux PowerShell prompt and included the fullpath. As the UserName and ComputerName parameters were not included, it defaults to fake_user as the UserName and fake_computer as the ComputerName.
.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 parameters.
    Last Edit: 03/29/2019 [1.0.0], 04/10/2019 [1.1.0]
    Version: 1.1.0
#>

    Param(
        [Parameter()]
        [ValidateSet('Minimal','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 'Minimal') {
                    'PS> '

                } ElseIf ($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.