Skip to content
Menu
The Lonely Administrator
  • PowerShell Tips & Tricks
  • Books & Training
  • Essential PowerShell Learning Resources
  • Privacy Policy
  • About Me
The Lonely Administrator

An Iron Scripter Warm-Up Solution

Posted on May 6, 2022May 6, 2022

We just wrapped up the 2022 edition of the PowerShell+DevOps Global Summit. It was terrific to be with passionate PowerShell professionals again. The culmination of the event is the Iron Scripter Challenge. You can learn more about this year's event and winner here. But there is more to the Iron Scripter than this event. Throughout the year, you can find scripting challenges to test your PowerShell skill at https://ironscripter.us. You are encouraged to share links to your solutions in the comments. Today, I have my solutions for a recent challenge.

Manage and Report Active Directory, Exchange and Microsoft 365 with
ManageEngine ADManager Plus - Download Free Trial

Exclusive offer on ADManager Plus for US and UK regions. Claim now!

The warm-up challenge was all about manipulating strings. That alone may not sound like much. But the process of discovering how to do it and wrapping it up in a PowerShell function is where the true value lies.

Beginner Level: Write PowerShell code to take a string like 'PowerShell' and display it in reverse.

Intermediate Level: Take a sentence like, "This is how you can improve your PowerShell skills." and write PowerShell code to display the entire sentence in reverse with each word also reversed. You should be able to encode and decode text. Ideally, your functions should take pipeline input. For bonus points, toggle upper and lower case when reversing the word.

Reversing Text

PowerShell treats every string of text as an array.

PS C:\> $w = "PowerShell"
PS C:\> $w[0]
P

Using the range operator, I can get elements in reverse.

PS C:\> $w[-1..-($w.length)]
l
l
e
h
S
r
e
w
o
P

Use the Join operator to put the characters back together again.

PS C:\> $w[-1..-($w.length)] -join ''
llehSrewoP

With this core concept validated, it is simple enough to wrap it in a function.

Function Invoke-ReverseWord {
    [cmdletbinding()]
    [OutputType("string")]
    Param(
        [Parameter(
            Position = 0,
            Mandatory,
            ValueFromPipeline,
            HelpMessage = "Enter a word."
        )]
        [ValidateNotNullOrEmpty()]
        [string]$Word
    )

    Begin {
        Write-Verbose "[$((Get-Date).TimeofDay) BEGIN  ] Starting $($myinvocation.mycommand)"
    } #begin
    Process {
        Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Processing $Word"
        Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Word length is $($Word.length)"
        #get the characters in reverse and join into a string
        ($Word[-1.. -($Word.length)]) -join ''

    } #process
    End {
        Write-Verbose "[$((Get-Date).TimeofDay) END    ] Ending $($myinvocation.mycommand)"
    } #end
}

Reversing a Sentence

Reversing words in a sentence follows the same principle. I can split the sentence into an array of words and then access the elements in reverse.

PS C:\> $t = "This is how you can improve your PowerShell skills"
PS C:\> $words = $t.split()
PS C:\> $words[-1..-($words.count)]
skills
PowerShell
your
improve
can
you
how
is
This

Again, I can join the words with a space. If I wanted to, I could reverse each word as well. That's what this function does.

Function Invoke-ReverseText {
    [CmdletBinding()]
    [OutputType("string")]
    Param(
        [Parameter(
            Position = 0,
            Mandatory,
            ValueFromPipeline,
            HelpMessage = "Enter a phrase."
        )]
        [ValidateNotNullOrEmpty()]
        [ValidatePattern("\s")]
        [string]$Text
    )
    Begin {
        Write-Verbose "[$((Get-Date).TimeofDay) BEGIN  ] Starting $($myinvocation.mycommand)"
    } #begin
    Process {
        Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Processing $Text"
        #split the phrase on white spaces and reverse each word
        $words = $Text.split() | Invoke-ReverseWord
        Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Reversed $($words.count) words"
        ($words[-1.. - $($words.count)]) -join " "
    } #process
    End {
        Write-Verbose "[$((Get-Date).TimeofDay) END    ] Ending $($myinvocation.mycommand)"
    } #end
}
PS C:\> Invoke-ReverseText "This is how you can improve your PowerShell skills"
slliks llehSrewoP ruoy evorpmi nac uoy woh si sihT
PS C:\> Invoke-ReverseText "This is how you can improve your PowerShell skills" | invoke-reversetext
This is how you can improve your PowerShell skills
PS C:\>

Toggle Case

Figuring out how to toggle case is a bit trickier. Each letter in a word is technically a [Char] type object.

PS C:\> $t = "PowerShell"
PS C:\> $t[0]
P
PS C:\> $t[0].gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Char                                     System.ValueType

[Char] objects have a numeric value.

PS C:\> $t[0] -as [int]
80

On my en-US system, upper-case alphabet characters fall within the range of 65-90. Lower-case letters are 97-112.

PS C:\> [char]80     
P
PS C:\> 100 -as [char]
d

To toggle case, I need to get the numeric value of each character and then invoke the toLower() or toUpper() method as required.

Function Invoke-ToggleCase {
    [cmdletbinding()]
    [OutputType("String")]
    Param(
        [Parameter(
            Position = 0,
            Mandatory,
            ValueFromPipeline,
            HelpMessage = "Enter a word."
        )]
        [ValidateNotNullOrEmpty()]
        [string]$Word
    )

    Begin {
        Write-Verbose "[$((Get-Date).TimeofDay) BEGIN  ] Starting $($myinvocation.mycommand)"
    } #begin
    Process {
        Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Processing $Word"
        $Toggled = $Word.ToCharArray() | ForEach-Object {
            $i = $_ -as [int]
            if ($i -ge 65 -AND $i -le 90) {
                #toggle lower
                $_.ToString().ToLower()
            }
            elseif ($i -ge 97 -AND $i -le 122) {
                #toggle upper
                $_.ToString().ToUpper()
            }
            else {
                $_.ToString()
            }
        } #foreach-object

        #write the new word to the pipeline
        $toggled -join ''

    } #process
    End {
        Write-Verbose "[$((Get-Date).TimeofDay) END    ] Ending $($myinvocation.mycommand)"
    } #end

}
PS C:\> invoke-togglecase $t
pOWERsHELL

Putting It All Together

Here's a function that does it all.

Function Invoke-ReverseTextToggle {
    [CmdletBinding()]
    [OutputType("string")]
    Param(
        [Parameter(
            Position = 0,
            Mandatory,
            ValueFromPipeline,
            HelpMessage = "Enter a phrase."
        )]
        [ValidateNotNullOrEmpty()]
        [ValidatePattern("\s")]
        [string]$Text
    )
    Begin {
        Write-Verbose "[$((Get-Date).TimeofDay) BEGIN  ] Starting $($myinvocation.mycommand)"
    } #begin
    Process {
        Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Processing $Text"
        #split the phrase on white spaces and reverse each word
        $words = $Text.split() | Invoke-ToggleCase | Invoke-ReverseWord
        Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Reversed $($words.count) words"
        ($words[-1.. - $($words.count)]) -join " "
    } #process
    End {
        Write-Verbose "[$((Get-Date).TimeofDay) END    ] Ending $($myinvocation.mycommand)"
    } #end
}
PS C:\> Invoke-ReverseTextToggle "This is how YOU can improve your PowerShell skills"
SLLIKS LLEHsREWOp RUOY EVORPMI NAC uoy WOH SI SIHt
PS C:\>
PS C:\> Invoke-ReverseTextToggle "This is how YOU can improve your PowerShell skills" | Invoke-ReverseTextToggle
This is how YOU can improve your PowerShell skills

After putting that together, I realized someone might not want all of the transformations. Maybe they only want to toggle case and reverse words. Here's a function that offers flexibility.

Function Convert-Text {
    <#
    This function relies on some of the previous functions or the functions could be nested
    inside the Begin block

    Order of operation:
      toggle case
      reverse word
      reverse text
    #>
    [cmdletbinding()]
    Param(
        [Parameter(Position = 0, Mandatory, ValueFromPipeline)]
        [ValidateNotNullOrEmpty()]
        [string]$Text,
        [Parameter(HelpMessage = "Reverse each word of text")]
        [switch]$ReverseWord,
        [Parameter(HelpMessage = "Toggle the case of the text")]
        [switch]$ToggleCase,
        [Parameter(HelpMessage = "Reverse the entire string of text")]
        [switch]$ReverseText
    )
    Begin {
        Write-Verbose "[$((Get-Date).TimeofDay) BEGIN  ] Starting $($myinvocation.mycommand)"
    } #begin

    Process {
        Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Converting $Text"
        $words = $text.Split()
        if ($ToggleCase) {
            Write-Verbose "toggling case"
            $words = $words | Invoke-ToggleCase
        }
        If ($reverseWord) {
            Write-Verbose "reversing words"
            $words = $words | Invoke-ReverseWord
        }
        if ($ReverseText) {
            Write-Verbose "reversing text"
            $words = ($words[-1.. - $($words.count)])
        }
        #write the converted text to the pipeline
        $words -join " "

    } #process

    End {
        Write-Verbose "[$((Get-Date).TimeofDay) END    ] Ending $($myinvocation.mycommand)"
    } #end

} #close Convert-Text

As written, this function relies on some of the earlier functions. But now, the user has options.

PS C:\> convert-text "I AM an Iron Scripter!" -ToggleCase
i am AN iRON sCRIPTER!
PS C:\>
PS C:\> convert-text "I AM an Iron Scripter!" -ReverseWord
I MA na norI !retpircS
PS C:\>
PS C:\> convert-text "I AM an Iron Scripter!" -ReverseWord -ToggleCase
i ma NA NORi !RETPIRCs
PS C:\>
PS C:\> convert-text "I AM an Iron Scripter!" -Reversetext -ToggleCase -ReverseWord
!RETPIRCs NORi NA ma i
PS C:\>
PS C:\> convert-text "I AM an Iron Scripter!" -Reversetext -ToggleCase -ReverseWord | convert-text -ReverseWord -ToggleCase -ReverseText   
I AM an Iron Scripter!

Challenge Yourself

If you have any questions about my code samples, please feel free to leave a comment. I also want to emphasize that my solutions are not the only way to achieve these results. There is value in comparing your work with others. I strongly encourage you to watch for future Iron Scripter challenges and tackle as much as possible. However, you don't have to wait. There are plenty of existing challenges on the site for all PowerShell scripting levels. Comments may be closed, so you can't share your solution, but that shouldn't prevent you from ramping your skills.


Behind the PowerShell Pipeline

Share this:

  • Click to share on X (Opens in new window) X
  • Click to share on Facebook (Opens in new window) Facebook
  • Click to share on Mastodon (Opens in new window) Mastodon
  • Click to share on LinkedIn (Opens in new window) LinkedIn
  • Click to share on Pocket (Opens in new window) Pocket
  • Click to share on Reddit (Opens in new window) Reddit
  • Click to print (Opens in new window) Print
  • Click to email a link to a friend (Opens in new window) Email

Like this:

Like Loading...

Related

3 thoughts on “An Iron Scripter Warm-Up Solution”

  1. Pingback: An Iron Scripter Warm-Up Solution - The Lonely Administrator - Syndicated Blogs - IDERA Community
  2. Pingback: Reversing Strings with Powershell – Curated SQL
  3. Pingback: PowerShell SnippetRace 24/2022 | PowerShell Usergroup Austria

Comments are closed.

reports

Powered by Buttondown.

Join me on Mastodon

The PowerShell Practice Primer
Learn PowerShell in a Month of Lunches Fourth edition


Get More PowerShell Books

Other Online Content

github



PluralSightAuthor

Active Directory ADSI Automation Backup Books CIM CLI conferences console Friday Fun FridayFun Function functions Get-WMIObject GitHub hashtable HTML Hyper-V Iron Scripter ISE Measure-Object module modules MrRoboto new-object objects Out-Gridview Pipeline PowerShell PowerShell ISE Profile prompt Registry Regular Expressions remoting SAPIEN ScriptBlock Scripting Techmentor Training VBScript WMI WPF Write-Host xml

©2025 The Lonely Administrator | Powered by SuperbThemes!
%d