These Friday Fun posts are not supposed to be practical, yet hopefully still entertaining and educational. Today's article is no exception but I 'll be you'll try it at least once. And you'll maybe even learn something about PowerShell that perhaps you didn't know before. It all starts with a string. We use strings all the time for things like passwords and names. Let me start by explaining some basic concepts and then we'll get to the fun stuff.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
$t = "abcdefg"
The string object has a number of methods, but I'm not going to use any of them today. Instead, I want to start by showing that the string is an array, or collection, of characters. This means you can access any element by its index number.
PS C:\> $t[0] a PS C:\> $t[3] d PS C:\> $t[-1] g
You can start at the end of the array with -1. You can also get several elements with the Range ( .. ) operator.
PS C:\> $t[0..2] a b c
So, what about counting in reverse? We know we can start at -1. -2 would give us the 2nd to last element, -3 the third to last and so on. Therefore all we need to do is count backwards to the beginning.
PS C:\> $t[-1..-($t.length)] g f e d c b a
I used the string length to know how far back to count. But wait, it gets better. Let's bring in the -Join operator. This operator is designed to join elements of an array into a single string.
PS C:\> $a="adam","beth","charlie","darlene" PS C:\> $a adam beth charlie darlene PS C:\> $a -join "||" adam||beth||charlie||darlene
If you don't want to specify a delimiter, you can use -Join like this:
PS C:\> -join $a adambethcharliedarlene
See where I'm going with this? Let's join the reversed array of string characters.
PS C:\> -join $t[-1..-($t.length)] gfedcba
So if I can take any string and reverse it, why not reverse PowerShell? I created a function called Out-Reverse.
#requires -version 3.0 Function Out-Reverse { <# .Synopsis Reverse command output to text. .Description This command will take any input and write it to the console as reverse text. .Example PS C:\> get-service m* | Out-Reverse emaNyalpsiD emaN sutatS ----------- ---- ------ rvSpotkseDTCM rvSpotkseDTCM gninnuR reludehcS ssalC aidemitluM SSCMM deppotS ecivreS ecnanetniaM allizoM ecnanetniaMallizoM deppotS llaweriF swodniW cvSspM gninnuR rotanidrooC noitcasnarT detubirtsiD CTDSM deppotS ecivreS rotaitinI ISCSi tfosorciM ISCSiSM deppotS rellatsnI swodniW revresism deppotS retliF draobyeK tfosorciM retliFdraobyeKsM deppotS )REVRESLQSSM( revreS LQS REVRESLQSSM gninnuR revreS PCHD NAP sseleriW SNDPCHDiFiWyM deppotS .Example PS C:\> "PowerShell" | Out-Reverse llehSrewoP .Example PS C:\> get-eventlog -list | format-list | out-reverse noitacilppA : goL eslaF : stnevEgnisiaRelbanE 08402 : setyboliKmumixaM 0 : syaDnoitneteRmuminiM dedeeNsAetirwrevO : noitcAwolfrevO stnevEerawdraH : goL eslaF : stnevEgnisiaRelbanE 08402 : setyboliKmumixaM 0 : syaDnoitneteRmuminiM dedeeNsAetirwrevO : noitcAwolfrevO rerolpxE tenretnI : goL eslaF : stnevEgnisiaRelbanE 215 : setyboliKmumixaM 7 : syaDnoitneteRmuminiM redlOetirwrevO : noitcAwolfrevO ... .Notes Last Updated: July 16, 2014 Version : 0.9 .Inputs Object .Outputs String #> [cmdletbinding()] Param( [Parameter(Position=0,ValueFromPipeline)] [Object]$InputObject) Begin { Write-Verbose -Message "Starting $($MyInvocation.Mycommand)" $data = @() } #begin Process { $data += $InputObject } End { $Text = ($Data | Out-String).Split("`n") foreach ($line in $text) { -join $line[-1..-$($line.length)] } Write-Verbose -Message "Ending $($MyInvocation.Mycommand)" } #end } #define an alias Set-Alias -Name orv -Value Out-Reverse
The idea is that you can run any PowerShell expression, pipe it to Out-Reverse, and you'll get just that: reverse output.
The function takes any pipeline input and stores it in a temporary array. Once everything has been processed, the data is converted to a string with Out-String. Because I need to process each line separately, I split what would otherwise be a very long single string, into multiple strings on the end of line marker (`n).
$Text = ($Data | Out-String).Split("`n")
$Text is now an array of strings and I can reverse each one.
foreach ($line in $text) { -join $line[-1..-$($line.length)] }
It is kind of fun looking at reversed output. For you language geeks, this also makes a great palindrome tester.
PS C:\> "able was I saw elba" | orv able was I saw elba PS C:\> "madam i'm adam" | orv mada m'i madam
Or maybe you need some simple obfuscation.
PS C:\> get-content C:\work\ComputerData.xml | orv >sretupmoc< >'tne-18niw-hj'=eman retupmoc< >/ lairessoib< >/ noisrevso< >retupmoc/< >'10cd-ihc'=eman retupmoc< >/ lairessoib< >/ noisrevso< >retupmoc/< >sretupmoc/<
Actually, if you find a production-worthy use of this function I hope you'll share it with me and the community. But as always I hope you picked up a PowerShell tidbit along the way that you can use in your "real" PowerShell work.
Enjoy your weekend. I'm sure you earned it.
That’s a laugh-out-loud funny use of PowerShell, Jeff. Bravo.
Just the other day I was blogging about random passwords and saving them for future use but fearing they might fall in wrong hands…
Writing them in reverse could be a first step in obfuscation. Seeing as the passwords are random, it won’t be evident at first glance…
Thanks!