PowerShell warnings with ASCII art

PowerShell Ascii Art Warning

I thought I would share a little fun I had with some scripts I’ve written. The situation was that the script I was running was going to do something, which if not done correctly, or at the wrong time, would have disastrous consequences in a production environment. I didn’t want to use the standard warning tools provided with PowerShell because I didn’t want people mindlessly clicking the OK button and creating a LOT more work than would be necessary. My thought was to have a giant error which would take up the entire screen it would force people to pay attention.

Searching the internet I found this site (http://www.patorjk.com/software/taag/) which had ASCII art for text in a large array of different styles. For my purposes I liked “ANSI Shadow” using the word ‘WARNING’ I felt it was striking enough. I copied the text and I had the first part of my script. To that, I add the Instructions for what I want them to do.

$Warning = @"                                                                       
██╗    ██╗ █████╗ ██████╗ ███╗   ██╗██╗███╗   ██╗ ██████╗                           
██║    ██║██╔══██╗██╔══██╗████╗  ██║██║████╗  ██║██╔════╝                           
██║ █╗ ██║███████║██████╔╝██╔██╗ ██║██║██╔██╗ ██║██║  ███╗                          
██║███╗██║██╔══██║██╔══██╗██║╚██╗██║██║██║╚██╗██║██║   ██║                          
╚███╔███╔╝██║  ██║██║  ██║██║ ╚████║██║██║ ╚████║╚██████╔╝                          
 ╚══╝╚══╝ ╚═╝  ╚═╝╚═╝  ╚═╝╚═╝  ╚═══╝╚═╝╚═╝  ╚═══╝ ╚═════╝                           
                                                                                    
You are about to delete all users in Contoso.com!                                   
                                                                                    
If you want to do this, you must type the following text EXACTLY  as it appears:    
                                                                                    
I WANT TO DELETE ALL USERS IN CONTOSO.COM                                                                                                                                        
"@

I want to write that out it bold RED with a BLACK  background so I break it up by new lines “`n” and Write-Host

$Warning -split "`n" | % {
  Write-Host -Foreground Red -Background Black $_ 
}

Next, I want the user to type an exact string to ensure they know what they are about to do. You can make this anything you want, but I like to keep in the idea of what is about to happen. Something like “I WANT TO DELETE ALL USERS IN CONTOSO.COM” If the user types this, they can’t say they didn’t know what they were doing.

To facilitate this, I use a while loop.

$ControlString = "I WANT TO DELETE ALL USERS IN CONTOSO.COM"

$string = [string]::Emtpy
While (-Not ($string -cmatch $ControlString))
{
    $string = read-host -prompt ":"

    if ($string -eq $ControlString -AND -not ($string -cmatch $ControlString))
    {
        Write-host -fore red -BackgroundColor black " (EXACTLY as it appears)"
    }
}

The ‘if’ statement is a friendly reminder that the reply needs to be in all capital letters. As long as they type it exactly as it appears, the script will go on. Otherwise it won’t go past this point.

Make things a bit more interesting…

Some of the characters in that original warning text are of a certain type. There are solid characters making up the majority of the letters and there is a collection of “boarder” characters. To identify these boarder characters I want to get the int equivalent for the char we see. To do this, I use the following syntax:

[int][char]'╝'

This identifies the character as type char and then converts it to its integer equivalent ([int]). This particular character gives us an integer value of 9565. Now I want to look at the other characters in that range. There are only so many “double-line boarder” characters so I choose all the characters between 9500 and 9600. To look at these characters and their values I run this:

9500..9600 | % {write-host $("{0}{1}" -f $_.Tostring().padright(5), $([char][int]$_))}

What I’m doing here is taking all the numbers between 9500 and 9600 and looping through them one at a time writing the number and the char equivalent using string formatting (-f). “{0}{1}” the 0 is the first entry after the ‘-f or the number passed in ($_) converted to a string (.ToString()) and padded to the right 5 characters. I need to convert the number to a string in order to gain access to the ‘padright()’ method (all this is just for neatness. I could have easily just used “{0} {1}” since all the numbers are 4 digits anyways). In the next index {1} I take the number, Identify it as an integer ([int]) then convert it to a character ([char]) “$([char][int]$_))”.

All this tells me that the characters I want have integer values between 9552 and 9580.


Now that we know that, we can take each line, split it up by characters and if a character’s int value falls in between 9550 and 9580 we can apply a different color to it like this:

foreach ($line in $Warning -split "`n")
{
    foreach ($char in $line.tochararray())
    {
        if ($([int]$char) -le 9580 -and  $([int]$char) -ge 9552)
        {
            Write-host -fore cyan $char -NoNewline
        }
        else
        {
            write-host -fore red $char -NoNewline
        }
    }
    write-host ""
}

gives us this:

or DarkRed and Red gives us:

Using a different Font (Alligator2) and some more colors and this code:

$Warning = @"
:::       :::     :::     :::::::::  ::::    ::: ::::::::::: ::::    :::  ::::::::  
:+:       :+:   :+: :+:   :+:    :+: :+:+:   :+:     :+:     :+:+:   :+: :+:    :+: 
+:+       +:+  +:+   +:+  +:+    +:+ :+:+:+  +:+     +:+     :+:+:+  +:+ +:+        
+#+  +:+  +#+ +#++:++#++: +#++:++#:  +#+ +:+ +#+     +#+     +#+ +:+ +#+ :#:        
+#+ +#+#+ +#+ +#+     +#+ +#+    +#+ +#+  +#+#+#     +#+     +#+  +#+#+# +#+   +#+# 
 #+#+# #+#+#  #+#     #+# #+#    #+# #+#   #+#+#     #+#     #+#   #+#+# #+#    #+# 
  ###   ###   ###     ### ###    ### ###    #### ########### ###    ####  ########  
"@

foreach ($line in $list -split "`n")
{
    foreach ($char in $line.tochararray())
    {
        switch ($([int]$char))
        {
            '#' {Write-host -fore DarkGreen $char -NoNewline}
            '+' {Write-host -fore DarkCyan $char -NoNewline}
            ':' {Write-host -fore Green $char -NoNewline}
            Default {Write-host $char -NoNewline}
        }

    }
    write-host ""
}

You get the idea!

Oh, and if you want to get rid of the vertical lines (better seen in the first example, you’ll need to change your font to Lucida Console.



2 Comments on “PowerShell warnings with ASCII art”

Leave a Reply