Here we go again. I just rescued another draft post, fixed it up enough to share, and published it. Again, this was one of those posts that just never made it past my drafts for one reason or another. I think I figured out what I wasn’t doing correctly, so I’m ready to hand it off.
Never know when I’m going to get inspired to write. Well, I just did and I’m not even sure how it started. All of sudden, I began thinking about ways in which to mess with someone using PowerShell. Perhaps it’s that April Fool’s Day just passed. It’s actually coming, this post is so overdue. I thought to myself, can I get the ConsoleHost to clear each time something is entered? Yeah, of course I can: the prompt function. Been here, done that, just not with such cruel, and obnoxious intentions.
Now to figure it out, for you (and next April Fool’s Day, perhaps). The idea is not to completely modify the prompt function, so as to tip off the user. Instead, the idea is to get their prompt — customized or not — and stuff a Clear-Host command to the end of it. That’s right, every time they enter a command and the prompt is redrawn, it’ll clear the host. Ha! Let’s do this. Yeah, let’s.
How you’re going to get on to your friend’s computer to do this, is up to you. That’s not what I’m here for, just remember your buddy is going to need to spend at least some time in the PowerShell console. Your click-next admin buddies aren’t going to see (or appreciate) this prompt function.
First, we need to get the content that makes up their prompt. It doesn’t matter if it’s been customized or not. Here’s the full command to do that. This command will assign the prompt’s ScriptBlock property to the $CurrentPrompt variable. Additionally, it will pass the value to the ToString() method.
PS MyPrompt > $CurrentPrompt = (Get-Command -Name prompt).ScriptBlock.ToString()
Let’s take a look at the contents of the $CurrentPrompt variable. If you didn’t notice already, you’ll be able to tell that I started with a custom prompt.
PS MyPrompt > $CurrentPrompt 'PS MyPrompt > '
Next, we’ll create a $NewPrompt variable. Notice that this code includes the $CurrentPrompt variable we created in the first step. This is how we can ensure the prompt has the same look, whether it’s been customized or not. The difference now, is that we’ve added a Clear-Host command inside there. So mean. And Awesome.
PS MyPrompt > $NewPrompt = "$($CurrentPrompt)Clear-Host"
This final command will overwrite the current prompt function with our modification.
Set-Content -Path Function:\prompt -Value $NewPrompt
In closing, I want to provide the full code I used for testing. This contains four different clean prompts, as well as the code we saw above to make the modifications. The first prompt is the one I use on a daily basis and discussed several times around here — it’s my Linux lookalike prompt. Anyway, this will give you some test code to copy to your system and play with. Have fun, then torture your coworkers, but I didn’t say that.
Function Prompt { (Get-PSProvider -PSProvider FileSystem).Home = $env:USERPROFILE # Determine if Admin and set Symbol variable. If ([bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).Groups -match 'S-1-5-32-544')) { $Symbol = '#' } Else { $Symbol = '$' } # Write Path to Location Variable 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])" } # 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 {} } # Determine PowerShell version. $PSVer = "$($PSVersionTable.PSVersion.Major).$($PSVersionTable.PSVersion.Minor)" # Create and write Prompt; Write WindowTitle. $UserComputer = "$($env:USERNAME.ToLower())@$($env:COMPUTERNAME.ToLower())" $Location = "$((Get-Location).Drive.Name.ToLower())$Location" # Check if in the debugger. If (Test-Path -Path Variable:/PSDebugContext) { $DebugStart = '[DBG]: ' $DebugEnd = ']' } # Actual prompt and title. $Host.UI.RawUI.WindowTitle = "$HostName $PSver`: $DebugStart[$UserComputer $Location]$DebugEnd$Symbol" "$DebugStart[$UserComputer $Location]$DebugEnd$PSVer$Symbol " } Function prompt { "PS $($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1)) " } Function prompt { 'PS > ' } Function prompt { 'PS MyPrompt > ' } Get-ChildItem # Verify no Clear-Host command included. $CurrentPrompt = (Get-Command -Name prompt).ScriptBlock.ToString() $CurrentPrompt $NewPrompt = "$($CurrentPrompt)Clear-Host" Set-Content -Path Function:\prompt -Value $NewPrompt Get-ChildItem # Verify Clear-Host command included.