Jump to page sections
- PowerBot IRC ASCII Art Screenshot
- PowerShell Console and ISE Screenshots
- Documentation
- More Screenshots And Fun
- Download
- Source Code
It has been tested with PowerShell version 2 and 3 in its current form.
Write-Ascii no longer prepends an apostrophe by default, so in all the examples/screenshots where you might see "-nop" or "-NoPrependChar", you can ignore that and just leave it out. If you do want to add it, use the parameter "-PrependChar".Originally I wrote it to be used in conjunction with a modified version of PowerBot, a simple IRC bot framework based on the SmartIrc4Net library. This is why it can prepend an apostrophe, because somewhere along the way to IRC, the leading spaces seem to disappear.
Currently it supports only a pretty basic subset of characters (I did add a few "international"/accented ones randomly). If you want other characters, you will need to add them to the XML. The list of accepted characters is dynamically created from the read XML file. This XML file is expected to have the name "letters.xml", be encoded in UTF-8 and to be in the module's working directory.I wrote this for my own use, but I figured I'd share it in case someone was looking for something like this. It was harder than I thought to write the algorithm for compression, and quite a bit of work to create the XML.
Of course, this isn't the most useful script in the world; it has to be placed in the "fun" category.2018-12-09: Now on GitHub and in the PowerShell Gallery.
PowerBot IRC ASCII Art Screenshot
PowerShell Console and ISE Screenshots

Screenshot from ISE v3:

Documentation
Currently, only lower-case letters are supported, mostly because PowerShell/Windows is case-insensitive by default when reading the XML - and workarounds seem cumbersome.
Here's an example of the XML that's used for the letter "a": <char>
<name>a</name>
<fixation>default</fixation>
<lines>4</lines>
<width>7</width>
<data> __ _
/ _` |
| (_| |
\__,_|</data>
</char>
All the characters in the XML have from 4-6 lines, where some of them may consist of only whitespace. If the maximum number of lines in the letter with the most lines is 4, only 4 lines will be output and letters will be bottom-aligned (which doesn't matter in the case of max 4 lines). It's filtered just before output with a simple "''Where-Object { $_ -match '\S' }''", that prevents lines with only padding/whitespace to be output. Actually, an "extra" side-effect of the whitespace filtering, is that punctuation characters with only 2-3 lines will only produce those 2-3 lines if printed alone. Such as a period (two lines) and a comma (three lines).
After some consideration, I added an XML tag called "fixation", which ensures the correct bottom-alignment of the 5-line letters g, y, p and q - in addition to the special character "¤" - which I added for reasons unknown - beyond it being on the Norwegian default keyboard layout (shift-4).However, if you use the parameter '''-Compression''', and the letter with the most lines has less than 6 lines, these aforementioned 5-line letters will not be correctly bottom-aligned. It was designed like this to save line space on IRC. I made compression optional and made correct alignment the default behaviour.
This demonstrates how compression works for these special letters:
More Screenshots And Fun
The script module also sports -ForegroundColor and -BackgroundColor parameters that accept all the colors that the corresponding parameters to Write-Host accepts. I've implemented colors on IRC as well, but those are some custom changes to the script I use in the customized PowerBot, and not included on this page.

Don't tell me this isn't useful!

Here's a one-liner for a simple ASCII clock (press any key to stop it):
while (!$Host.UI.RawUI.KeyAvailable) { cls; Write-Ascii (get-date); sleep 1 }
And I simply couldn't resist adding a "color" called rainbow. Behold:

Download
*Write-Ascii.zip - contains the PowerShell script module and the XML with the currently supported characters. To use this module in PowerShell, unzip the compressed folder into one of your $env:PSModulePath folders, and then import it with "Import-Module Write-Ascii".
Type "Get-Help Write-Ascii -Detailed" to get the help text - after it's been imported. *2013-03-02: v1.0.0.5. Fixed a bug that made it say spaces weren't allowed.*2013-03-01: v1.0.0.4. Added support for pipeline input, removed maximum character limitation, made it not prepend an apostrophe by default. ++
Source Code
<# .SYNOPSIS Svendsen Tech's PowerShell ASCII art module creates ASCII art characters from a subset of common letters, numbers and punctuation characters. You can add new characters by editing the XML (for developers). Author: Joakim Svendsen, Svendsen Tech. Copyright (c) 2012, Svendsen Tech. All rights reserved. MIT License .DESCRIPTION This script reads characters from an XML file that's expected to have the name "letters.xml", be encoded in UTF-8 and to be in the module's working directory. It was written to be used in conjunction with a modified version of PowerBot (http://poshcode.org/2510), a simple IRC bot framework written using SmartIrc4Net; that's why it can prepend an apostrophe - because somewhere along the way the leading spaces get lost before it hits the IRC channel. Currently the XML only contains lowercase letters, mostly because PowerShell/ Windows is case-insensitive by default, which isn't an advantage here. Example: PS C:\> Import-Module Write-Ascii PS C:\> Write-Ascii "ASCII!" _ _ _ __ _ ___ ___ (_)(_)| | / _` |/ __| / __|| || || | | (_| |\__ \| (__ | || ||_| \__,_||___/ \___||_||_|(_) PS C:\> .PARAMETER InputText String(s) to convert to ASCII. .PARAMETER PrependChar Optional. Makes the script prepend an apostrophe. .PARAMETER Compression Optional. Compress to five lines when possible, even when it causes incorrect alignment of the letters g, y, p and q (and "¤"). .PARAMETER ForegroundColor Optional. Console only. Changes text foreground color. .PARAMETER BackgroundColor Optional. Console only. Changes text background color. #> function Write-Ascii { # Wrapping the script in a function to make it a module [CmdLetBinding()] param( [Parameter(ValueFromPipeline=$true, Mandatory=$true)][string[]] $InputText, [switch] $PrependChar, [switch] $Compression, [string] $ForegroundColor = 'Default', [string] $BackgroundColor = 'Default' #[int] $MaxChars = '25' ) begin { Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' # Algorithm from hell... This was painful. I hope there's a better way. function Get-Ascii { param([string] $Text) $LetterArray = [char[]] $Text.ToLower() #Write-Host -fore green $LetterArray # Find the letter with the most lines. $MaxLines = 0 $LetterArray | ForEach-Object { if ($Letters.([string] $_).Lines -gt $MaxLines ) { $MaxLines = $Letters.([string] $_).Lines } } # Now this sure was a simple way of making sure all letter align tidily without changing a lot of code! if (-not $Compression) { $MaxLines = 6 } $LetterWidthArray = $LetterArray | ForEach-Object { $Letter = [string] $_; $Letters.$Letter.Width } $LetterLinesArray = $LetterArray | ForEach-Object { $Letter = [string] $_; $Letters.$Letter.Lines } #$LetterLinesArray $Lines = @{ '1' = '' '2' = '' '3' = '' '4' = '' '5' = '' '6' = '' } #$LineLengths = @(0, 0, 0, 0, 0, 0) # Debug #Write-Host "MaxLines: $Maxlines" $LetterPos = 0 foreach ($Letter in $LetterArray) { # We need to work with strings for indexing the hash by letter $Letter = [string] $Letter # Each ASCII letter can be from 4 to 6 lines. # If the letter has the maximum of 6 lines, populate hash with all lines. if ($LetterLinesArray[$LetterPos] -eq 6) { #Write-Host "Six letter letter" foreach ($Num in 1..6) { $StringNum = [string] $Num $LineFragment = [string](($Letters.$Letter.ASCII).Split("`n"))[$Num-1] if ($LineFragment.Length -lt $Letters.$Letter.Width) { $LineFragment += ' ' * ($Letters.$Letter.Width - $LineFragment.Length) } $Lines.$StringNum += $LineFragment } } # Add padding for line 6 for letters with 5 lines and populate lines 2-6. ## Changed to top-adjust 5-line letters if there are 6 total. ## Added XML properties for letter alignment. Most are "default", which is top-aligned. ## Also added script logic to handle it (2012-12-29):Windows Powershell Artbottom elseif ($LetterLinesArray[$LetterPos] -eq 5) { #Write-Host "Five-letter letter" if ($MaxLines -lt 6 -or $Letters.$Letter.fixation -eq 'bottom') { $Padding = ' ' * $LetterWidthArray[$LetterPos] $Lines.'1' += $Padding foreach ($Num in 2..6) { $StringNum = [string] $Num $LineFragment = [string](($Letters.$Letter.ASCII).Split("`n"))[$Num-2] if ($LineFragment.Length -lt $Letters.$Letter.Width) { $LineFragment += ' ' * ($Letters.$Letter.Width - $LineFragment.Length) } $Lines.$StringNum += $LineFragment } } else { $Padding = ' ' * $LetterWidthArray[$LetterPos] $Lines.'6' += $Padding foreach ($Num in 1..5) { $StringNum = [string] $Num $LineFragment = [string](($Letters.$Letter.ASCII).Split("`n"))[$Num-1] if ($LineFragment.Length -lt $Letters.$Letter.Width) { $LineFragment += ' ' * ($Letters.$Letter.Width - $LineFragment.Length) } $Lines.$StringNum += $LineFragment } } } # Here we deal with letters with four lines. # Dynamic algorithm that places four-line letters on the bottom line if there are # 4 or 5 lines only in the letter with the most lines. else { #Write-Host "Four letter letter" # Default to putting the 4-liners at line 3-6 $StartRange, $EndRange, $IndexSubtract = 3, 6, 3 $Padding = ' ' * $LetterWidthArray[$LetterPos] # If there are 4 or 5 lines... if ($MaxLines -lt 6) { $Lines.'2' += $Padding } # There are 6 lines maximum, put 4-line letters in the middle. else { $Lines.'1' += $Padding $Lines.'6' += $Padding $StartRange, $EndRange, $IndexSubtract = 2, 5, 2 } # There will always be at least four lines. Populate lines 2-5 or 3-6 in the hash. foreach ($Num in $StartRange..$EndRange) { $StringNum = [string] $Num $LineFragment = [string](($Letters.$Letter.ASCII).Split("`n"))[$Num-$IndexSubtract] if ($LineFragment.Length -lt $Letters.$Letter.Width) { $LineFragment += ' ' * ($Letters.$Letter.Width - $LineFragment.Length) } $Lines.$StringNum += $LineFragment } } $LetterPos++ } # end of LetterArray foreach # Return stuff $Lines.GetEnumerator() | Sort Name | Select -ExpandProperty Value | ?{ $_ -match '\S' } | %{ if ($PrependChar) { "'" + $_ } else { $_ } } } # Populate the $Letters hashtable with character data from the XML. Function Get-LetterXML { $LetterFile = Join-Path $PSScriptRoot 'letters.xml' $Xml = [xml] (Get-Content $LetterFile) $Xml.Chars.Char | ForEach-Object { $Letters.($_.Name) = New-Object PSObject -Property @{ 'Fixation' = $_.fixation 'Lines' = $_.lines 'ASCII' = $_.data 'Width' = $_.width } } } function Write-RainbowString { param([string] $Line, [string] $ForegroundColor = '', [string] $BackgroundColor = '') $Colors = @('Black', 'DarkBlue', 'DarkGreen', 'DarkCyan', 'DarkRed', 'DarkMagenta', 'DarkYellow', 'Gray', 'DarkGray', 'Blue', 'Green', 'Cyan', 'Red', 'Magenta', 'Yellow', 'White')# $Colors[(Get-Random -Min 0 -Max 16)]
[char[]] $Line | %{ if ($ForegroundColor -and $ForegroundColor -ieq 'rainbow') { if ($BackgroundColor -and $BackgroundColor -ieq 'rainbow') { Write-Host -ForegroundColor $Colors[(Get-Random -Min 0 -Max 16)] ` -BackgroundColor $Colors[(Get-Random -Min 0 -Max 16)] -NoNewline $_ } elseif ($BackgroundColor) { Write-Host -ForegroundColor $Colors[(Get-Random -Min 0 -Max 16)] ` -BackgroundColor $BackgroundColor -NoNewline $_ } else { Write-Host -ForegroundColor $Colors[(Get-Random -Min 0 -Max 16)] -NoNewline $_ } } # One of them has to be a rainbow, so we know the background is a rainbow here... else { if ($ForegroundColor) { Write-Host -ForegroundColor $ForegroundColor -BackgroundColor $Colors[(Get-Random -Min 0 -Max 16)] -NoNewline $_ } else { Write-Host -BackgroundColor $Colors[(Get-Random -Min 0 -Max 16)] -NoNewline $_ } } } Write-Host '' } # Get ASCII art letters/characters and data from XML. Make it persistent for the module. if (-not (Get-Variable -EA SilentlyContinue -Scope Script -Name Letters)) { $script:Letters = @{} Get-LetterXML } # Turn the [string[]] into a [string] the only way I could figure out how... wtf #$Text = '' #$InputText | ForEach-Object { $Text += "$_ " } # Limit to 30 characters #$MaxChars = 30 #if ($Text.Length -gt $MaxChars) { "Too long text. There's a maximum of $MaxChars characters."; return } # Replace spaces with underscores (that's what's used for spaces in the XML). #$Text = $Text -replace ' ', '_' # Define accepted characters (which are found in XML). #$AcceptedChars = '[^a-z0-9 _,!?./;:<>()¤{}\[\]\|\^=\$\-''+`\\"æøåâàáéèêóòôü]' # Some chars only works when sent as UTF-8 on IRC $LetterArray = [string[]]($Letters.GetEnumerator() | Sort Name | Select -ExpandProperty Name) $AcceptedChars = [regex] ( '(?i)[^' + ([regex]::Escape(($LetterArray -join '')) -replace '-', '\-' -replace '\]', '\]') + ' ]' ) # Debug #Write-Host -fore cyan $AcceptedChars.ToString() } process { if ($InputText -match $AcceptedChars) { "Unsupported character, using these accepted characters: " + ($LetterArray -join ', ') + "."; return } # Filthy workaround (now worked around in the foreach creating the string). #if ($Text.Length -eq 1) { $Text += '_' }$Lines = @()
foreach ($Text in $InputText) { $ASCII = Get-Ascii ($Text -replace ' ', '_') if ($ForegroundColor -ne 'Default' -and $BackgroundColor -ne 'Default') { if ($ForegroundColor -ieq 'rainbow' -or $BackGroundColor -ieq 'rainbow') { $ASCII | ForEach-Object { Write-RainbowString -ForegroundColor $ForegroundColor -BackgroundColor $BackgroundColor -Line $_ } } else { Write-Host -ForegroundColor $ForegroundColor -BackgroundColor $BackgroundColor ($ASCII -join "`n") } } elseif ($ForegroundColor -ne 'Default') { if ($ForegroundColor -ieq 'rainbow') { $ASCII | ForEach-Object { Write-RainbowString -ForegroundColor $ForegroundColor -Line $_ } } else { Write-Host -ForegroundColor $ForegroundColor ($ASCII -join "`n") } } elseif ($BackgroundColor -ne 'Default') { if ($BackgroundColor -ieq 'rainbow') { $ASCII | ForEach-Object { Write-RainbowString -BackgroundColor $BackgroundColor -Line $_ } } else { Write-Host -BackgroundColor $BackgroundColor ($ASCII -join "`n") } } else { $ASCII -replace '\s+$' }} # end of foreach
} # end of process block } Export-ModuleMember -Function Write-Ascii
Blog articles in alphabetical order
A
- A Look at the KLP AksjeNorden Index Mutual Fund
- A primitive hex version of the seq gnu utility, written in perl
- Accessing the Bing Search API v5 using PowerShell
- Accessing the Google Custom Search API using PowerShell
- Active directory password expiration notification
- Aksje-, fonds- og ETF-utbytterapportgenerator for Nordnet-transaksjonslogg
- Ascii art characters powershell script
- Automatically delete old IIS logs with PowerShell
C
- Calculate and enumerate subnets with PSipcalc
- Calculate the trend for financial products based on close rates
- Check for open TCP ports using PowerShell
- Check if an AD user exists with Get-ADUser
- Check when servers were last patched with Windows Update via COM or WSUS
- Compiling or packaging an executable from perl code on windows
- Convert between Windows and Unix epoch with Python and Perl
- Convert file encoding using linux and iconv
- Convert from most encodings to utf8 with powershell
- ConvertTo-Json for PowerShell version 2
- Create cryptographically secure and pseudorandom data with PowerShell
- Crypto is here - and it is not going away
- Crypto logo analysis ftw
D
G
- Get rid of Psychology in the Stock Markets
- Get Folder Size with PowerShell, Blazingly Fast
- Get Linux disk space report in PowerShell
- Get-Weather cmdlet for PowerShell, using the OpenWeatherMap API
- Get-wmiobject wrapper
- Getting computer information using powershell
- Getting computer models in a domain using Powershell
- Getting computer names from AD using Powershell
- Getting usernames from active directory with powershell
- Gnu seq on steroids with hex support and descending ranges
- Gullpriser hos Gullbanken mot spotprisen til gull
H
- Have PowerShell trigger an action when CPU or memory usage reaches certain values
- Historical view of the SnP 500 Index since 1927, when corona is rampant in mid-March 2020
- How Many Bitcoins (BTC) Are Lost
- How many people own 1 full BTC
- How to check perl module version
- How to list all AD computer object properties
- Hva det innebærer at særkravet for lån til sekundærbolig bortfaller
I
L
M
P
- Parse openssl certificate date output into .NET DateTime objects
- Parse PsLoggedOn.exe Output with PowerShell
- Parse schtasks.exe Output with PowerShell
- Perl on windows
- Port scan subnets with PSnmap for PowerShell
- PowerShell Relative Strength Index (RSI) Calculator
- PowerShell .NET regex to validate IPv6 address (RFC-compliant)
- PowerShell benchmarking module built around Measure-Command
- Powershell change the wmi timeout value
- PowerShell check if file exists
- Powershell check if folder exists
- PowerShell Cmdlet for Splitting an Array
- PowerShell Executables File System Locations
- PowerShell foreach loops and ForEach-Object
- PowerShell Get-MountPointData Cmdlet
- PowerShell Java Auto-Update Script
- Powershell multi-line comments
- Powershell prompt for password convert securestring to plain text
- Powershell psexec wrapper
- PowerShell regex to accurately match IPv4 address (0-255 only)
- Powershell regular expressions
- Powershell split operator
- Powershell vs perl at text processing
- PS2CMD - embed PowerShell code in a batch file
R
- Recursively Remove Empty Folders, using PowerShell
- Remote control mom via PowerShell and TeamViewer
- Remove empty elements from an array in PowerShell
- Remove first or last n characters from a string in PowerShell
- Rename unix utility - windows port
- Renaming files using PowerShell
- Running perl one-liners and scripts from powershell
S
- Sammenlign gullpriser og sølvpriser hos norske forhandlere av edelmetall
- Self-contained batch file with perl code
- Silver - The Underrated Investment
- Simple Morningstar Fund Report Script
- Sølv - den undervurderte investeringen
- Sort a list of computers by domain first and then name, using PowerShell
- Sort strings with numbers more humanely in PowerShell
- Sorting in ascending and descending order simultaneously in PowerShell
- Spar en slant med en optimalisert kredittkortportefølje
- Spre finansiell risiko på en skattesmart måte med flere Aksjesparekontoer
- SSH from PowerShell using the SSH.NET library
- SSH-Sessions Add-on with SCP SFTP Support
- Static Mutual Fund Portfolio the Last 2 Years Up 43 Percent
- STOXR - Currency Conversion Software - Open Exchange Rates API