functions/Set-PSPrompt.ps1
function Set-PSPrompt { <# .synopsis The function that creates the desired prompt function. .description It has to build a command out of the component pieces as it will be executed everytime a command is executed and therefore cant make use of any parameterisation .parameter WhatIf [<SwitchParameter>] If this switch is enabled, no actions are performed but informational messages will be displayed that explain what would happen if the command were to run. .parameter Confirm [<SwitchParameter>] If this switch is enabled, you will be prompted for confirmation before executing any operations that change state. .example Set-PSPrompt This will start the process to configure your custom PowerShell prompt #> [CmdletBinding(SupportsShouldProcess = $true, DefaultParameterSetName = 'Custom')] Param( # [parameter(parametersetname = "default")][switch]$AddToProfile, # [parameter(parametersetname = "default")][switch]$Admin, # [parameter(parametersetname = "default")][switch]$Battery, # switch to reset to console prompt back to original state [parameter(ParameterSetName = "Reset") ][switch]$Reset ) $PSPromptData = [ordered]@{ } New-Variable -Name WorkingFolder -Value "$env:APPDATA\PSPrompt" -Option Constant $ConfigFile = "PSPrompt*.config" # TODO:: remove this line to set correct config file # create working folder for module if its not there if (!(Test-Path $WorkingFolder)) { $null = New-Item -Path $WorkingFolder -ItemType Directory } #region preserve the original prompt so that it can be reset if so desired Write-Verbose "Preserving original prompt" $Date = Get-Date -Format 'yyMMdd-HHmmss' $filename = "$WorkingFolder\prompt_$date.ps1" $function:prompt | Out-File -FilePath $filename Write-Verbose "Existing prompt written out to $filename." #endregion #region code route options: # 1 gather user preferences from a static json file if it exists # 2 user overrides the json option at (?) and wants to add/remove features # 3 user wants to revert to their original prompt, prior to installing PSPrompt # 4 user selection of prompt features at first execution #region Option A - Reset to original prompt # need to show options for reset and allow for selection # need to put test for $Reset ahead of other steps to avoid choosing something else before being reset # get-item "$WorkingFolder\prompt_*.ps1" # $OldPrompt = if ($Reset) { $ProfileCUAHPath = $profile.CurrentUserAllHosts # $ProfileCUCHPath = $profile.CurrentUserCurrentHost # unused at the moment - may look at different psprompt in different profiles oneday ##$ProfileCUAH = Get-Content $ProfileCUAHPath -Raw ##$ProfileCUCH = Get-Content $ProfileCUCHPath -Raw if (($ProfileCUAHPath).Length -gt 0) { # code $profile.CurrentUserCurrentHost $p = @() $p = get-content $ProfileCUAHPath if (($profile.CurrentUserAllHosts).Length -gt 0) { ## think this isnt needed here $p = get-content $profile.CurrentUserAllHosts if ($p.IndexOf("##PSPROMPTSTART##")) { Write-Verbose "PSPROMPT content found in CurrentUserAllHosts" } } else { Write-Verbose "CurrentUserAllHosts profile is empty" } # locate start and end of psprompt content $Start = $a.IndexOf('##PSPROMPTSTART##') $End = $a.IndexOf('##PSPROMPTEND##') # identify content in profile before psprompt if ($start -ne 0) { $Before = $a[0..($Start - 1)].Clone() } else { $Before = $null } # identify content in profile after psprompt if ($End -ne ($a.Count - 1)) { $After = $a[($End + 1)..($a.Length)].Clone() } else { $After = $null } # put 'before' and 'after' content into the profile file $Before | Out-File -FilePath ($profile.CurrentUserAllHosts) $After | Out-File -FilePath ($profile.CurrentUserAllHosts) -append } return # no more processing in this script } #endregion Option A #region option 1 - there is config file we can load settings from # load the settings # handle multiple config files $ConfigFiles = get-item (join-path $WorkingFolder $configFile) if ($ConfigFiles.count -gt 1) { $i = 1 foreach ($File in $ConfigFiles) { Write-Host "$i - $File" $i++ } do { $LoadConfig = Read-Host "There are multiple config files - which do you want to implement?" Write-Host "Please select the number of the file you want to import, enter 'configure' to create a new prompt or press Ctrl + C to cancel." } until($LoadConfig -in ((1..$Configfiles.count), 'configure' ) ) ## TODO - need to work out how to go to configure from here. makes me wonder if this should be step 1 ... $PSPromptData = Import-Clixml $configFiles[$LoadConfig - 1] } elseif ($ConfigFiles.count -lt 1) { Write-Warning "No config files found. Need to do something here." } else { $PSPromptData = Import-Clixml $configFiles # confirm to user Write-Host "There is a config file that will enable the following PSPrompt features:`r`n" $PSPromptData while ($choice -notin ('yes', 'no')) { $choice = Read-Host -Prompt "Do you want to apply these settings? (Yes) or (No)." } if ($choice -eq 'yes') { if ($PSCmdlet.ShouldProcess("Console Prompt", "Customising being applied")) { Push-PSPrompt $PSPromptData } } elseif ($choice -eq 'no') { Write-Verbose "Removing PSPrompt config file." Remove-Item $ConfigFiles Write-Verbose "Removing MyPrompt.ps1 config file." Remove-Item -path (join-path -path (split-path -path $ConfigFiles -parent) -child "myprompt.ps1") Write-Verbose "PSPrompt config file removed." return } } Write-Verbose "Loading from (join-path $WorkingFolder $configFiles[$LoadConfig - 1])" $msg = ("WorkingFolder: {0}; ConfigFiles: {1}" -f $WorkingFolder, $ConfigFiles) Write-Verbose $msg # confirm to user #Write-Host "There a config file that will enable the following PSPrompt features:`r`n" #Write-Output $PSPromptData # #$msg = "Do you want to (e)nable these features or (c)onfigure different ones?" # #do { # $r = Read-Host -Prompt $msg #}while ($r -notin ('e', 'c')) # #if ($r -eq 'e') { # write-host "Loading custom fprompt from $Configfiles" # Push-PSPrompt #} #else { # Remove-Item $configFiles #} # TODO:: need to add check its OK - then move to (currently) line 230 ##Push-PSPrompt $PSPromptData #endregion option 1 #region option 2 - custom choice from command line #endregion option 2 # temporary check of file contents during development # start-process notepad "$WorkingFolder\PSPrompt.config" # hand over to function that reads in function sectors based on config file settings and invokes the prompt function #*#*#*# Push-PSPrompt $PSPromptData #region option 3 - reset #endregion option 3 #region option 4 That means we are at first usage of Set-Prompt so we need to collect user preference if (!(test-path (join-path $WorkingFolder $ConfigFile))) { Clear-Host $msg = @() $msg += "Welcome to PSPrompt. It looks like this is your first time using the prompt so you need to make some choices on how you want your prompt to look." $msg += "There are some choices coming up and you need to respond with (Y)es or (N)o to each. When you respond (Yes) that feature will be included in your prompt." $msg += "If you respond (N)o then the feature wont be applied." $msg += "If you want to change your mind at any time, run the command Set-Prompt -options and you will enter this menu again." $msg | ForEach-Object { Write-Host $_ start-sleep -Milliseconds 800 } #region Admin user $msg = $null $msg += "`r`n`r`nFirst of all, do you want a notification when you are running a PS session as an Administrator level account?" $msg += "`r`nLike this:" $msg | ForEach-Object { Write-Host $_ start-sleep -Milliseconds 800 } Write-Host -ForegroundColor "Black" -BackgroundColor "DarkRed" "[ADMIN]" $r = read-host -Prompt "(Y)es to have this in the prompt, (N)o to give it a miss." if ($r -eq "y") { $PSPromptData.Adminuser = $true } else { $PSPromptData.Adminuser = $false } # record selection into xml file $PSPromptData | Export-Clixml -Path "$WorkingFolder\PSPrompt.config" #endregion #region Battery Clear-Host $msg = $null $msg += "`r`n`r`nNext, do you work from a laptop? Do you want an indicator of your battery status while you are working on battery power?" $msg += "`r`nLike this:" $msg | ForEach-Object { Write-Host $_ start-sleep -Milliseconds 800 } $msg = ("[75%:60m]" ) Write-Host -Object $msg -BackgroundColor Green -ForegroundColor Black $r = read-host -Prompt "(Y)es to have this in the prompt, (N)o to give it a miss." if ($r -eq "y") { $PSPromptData.Battery = $true } else { $PSPromptData.Battery = $false } # record selection into xml file $PSPromptData | Export-Clixml -Path "$WorkingFolder\PSPrompt.config" #endregion #region Day and Date Clear-Host $msg = $null $msg += "`r`n`r`nNeed to keep your eye on the time? Add the day/date to your prompt?" $msg += "`r`nLike this:" $msg | ForEach-Object { Write-Host $_ start-sleep -Milliseconds 800 } $msg = "[{0}]" -f (Get-Date -Format "ddd HH:mm:ss") Write-Host $msg $r = read-host -Prompt "(Y)es to have this in the prompt, (N)o to give it a miss." if ($r -eq "y") { $PSPromptData.Day_and_date = $true } else { $PSPromptData.Day_and_date = $false } # record selection into xml file $PSPromptData | Export-Clixml -Path "$WorkingFolder\PSPrompt.config" #endregion #region UTC offset Clear-Host $msg = $null $msg += "`r`n`r`nIf you work across timezones then as your laptop updates to a different timezone we can have your timezone offset indicated in your prompt.`r`n Add the timezone offset to your prompt?" $msg += "`r`nLike this:" $msg | ForEach-Object { Write-Host $_ start-sleep -Milliseconds 800 } Write-Host "`r`n(GMT +1)" -ForegroundColor Green -NoNewline Write-Host "`tor`t" -ForegroundColor white -NoNewline Write-Host "(GMT -3) `r`n" -ForegroundColor Red $r = read-host -Prompt "(Y)es to have this in the prompt, (N)o to give it a miss." if ($r -eq "y") { $PSPromptData.UTC_offset = $true } else { $PSPromptData.UTC_offset = $false } # record selection into xml file $PSPromptData | Export-Clixml -Path "$WorkingFolder\PSPrompt.config" #endregion #region Fun function #endregion #region last command duration Clear-Host $msg = $null $msg += "`r`n`r`nEveryone likes to write fast executing scripts. Have the execution time of your last script shown right where you are focussed.`r`n Add the previous script duration to your prompt?" $msg += "`r`nLike this:" $msg | ForEach-Object { Write-Host $_ start-sleep -Milliseconds 800 } Write-Host "`r`n[56ms]" -ForegroundColor Green -NoNewline Write-Host "`tor`t" -ForegroundColor white -NoNewline Write-Host "[29s] `r`n" -ForegroundColor Red $r = read-host -Prompt "(Y)es to have this in the prompt, (N)o to give it a miss." if ($r -eq "y") { $PSPromptData.last_command = $true } else { $PSPromptData.last_command = $false } # record selection into xml file $PSPromptData | Export-Clixml -Path "$WorkingFolder\PSPrompt.config" #endregion #region Short Path Clear-Host $msg = $null $msg += "`r`n`r`nSometimes you get down a lot of folder levels and the prompt gets really wide.`r`n We can give you a shortened version of the path" $msg += "`r`nLike this:" $msg | ForEach-Object { Write-Host $_ start-sleep -Milliseconds 800 } Write-Host "`r`nC:\...\PowerShell\ProfileF~>" -NoNewline Write-Host "`tinstead of `t" -ForegroundColor white -NoNewline Write-Host "C:\Users\jonallen\OneDrive\Scripts\PowerShell\ProfileFunctions `r`n" $r = read-host -Prompt "(Y)es to have this in the prompt, (N)o to give it a miss." if ($r -eq "y") { $PSPromptData.shortpath = $true } else { $PSPromptData.shortpath = $false } # record selection into xml file $PSPromptData | Export-Clixml -Path "$WorkingFolder\PSPrompt.config" #endregion #region second line every Nth command Clear-Host $msg = $null $msg += @" There are some things that its good to keep your eye on but you don't need to see every time you run a command. So, we can show you some information every few commands (default is every 5 commands). Would you like a second line to occasionally give you info about your Git status or perhaps additional battery information? "@ $msg += "`r`nLike this:" $msg | ForEach-Object { Write-Host $_ start-sleep -Milliseconds 800 } Write-Host "git status: " -ForegroundColor White -BackgroundColor Black -NoNewline Write-Host "New[0] " -ForegroundColor Green -NoNewline Write-Host "Mod[7] " -ForegroundColor Cyan -NoNewline Write-Host "Del[1]" -ForegroundColor Red $r = read-host -Prompt "(Y)es to have this occasionally in your prompt, (N)o to give it a miss." if ($r -eq "y") { $PSPromptData.SecondLine = $true $PSPromptData.GitStatus = $true } else { $PSPromptData.GitStatus = $false } # record selection into xml file $PSPromptData | Export-Clixml -Path "$WorkingFolder\PSPrompt.config" #endregion #region Battery decline rate # still not sure on this so leaving code in Nth command.ps1 - JA 20190503 #endregion } #endregion (option 4) #endregion all options } |