<# ----------------------------------------------------------------------------- Script: PSCode.psm1 Version: 0.9 Author: Jeffery Hicks http://jdhitsolutions.com/blog http://twitter.com/JeffHicks http://www.ScriptingGeek.com Date: 7/17/2012 Keywords: Comments: Some fun commands to encode and decode text using a character substitution algorithm. Plus a function to reverse a string. "Those who forget to script are doomed to repeat their work." **************************************************************** * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED * * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK. IF * * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, * * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING. * **************************************************************** ----------------------------------------------------------------------------- #> Function ConvertTo-PSCode { <# .SYNOPSIS Encode a string into a secret code .DESCRIPTION This command will encode a string or array of strings into a secret code. Each word is broken down into its corresponding [CHAR] value. A new value is then calculated by adding and offset to the [CHAR] value and then turning that value back into text. This has the effect that each word has a different replacement algorithm. The offset is calculated by taking the word length and getting the modulo remainder when divided by pi, rounded to the next integer and then plus 3. You can use a scriptblock and specify your own calculation using $word to reference the current word. .PARAMETER Text The strings to encode. .PARAMETER Scriptblock A scriptblock that returns a numeric value to be used as the offset. The default is {($word.length%[math]::pi)+3}. .EXAMPLE PS C:\> "PowerShell Rules" | ConvertTo-PSCode Ts{ivWlipp Wzqjx .EXAMPLE PS C:\> Get-content plain.txt | ConvertTo-PSCode | out-file secret.txt Take the contents of plain.txt, encode them and save the result to a new file. .EXAMPLE PS C:\> "I am the walrus" | convertto-pscode -scriptblock {$word.length+2} L eq ymj itz}{ Encoding with a custom scriptblock to calculate the offset. .NOTES NAME : ConvertTo-PSCode VERSION : 0.9 LAST UPDATED: 7/17/2012 AUTHOR : Jeffery Hicks .INPUTS String .OUTPUTS String .LINK ConvertFrom-PSCode #> [cmdletbinding()] Param( [Parameter(Position=0,Mandatory=$True,ValueFromPipeline=$True)] [AllowEmptyString()] [AllowNull()] [string[]]$Text, [ValidateNotNullorEmpty()] [scriptblock]$Scriptblock={($word.length%[math]::pi)+3} ) Begin { #an array to hold encoded output Write-Verbose "Starting $($myinvocation.mycommand)" $Out=@() } Process { #split text into words and lines foreach ($line in $text) { $newLine="" Write-Verbose "Processing line: $line" $NewLine+= foreach ($word in ($line.Split())) { write-Verbose " Processing word: $word" $chars = for ($i=0;$i -lt $word.length;$i++) { $x=$word[$i] #get the current numeric value $x=[char]::ConvertToUtf32("$x",0) #Calculate an offset. The default is the length of the #word modulo pi rounded to an integer plus 3 [int]$off=&$Scriptblock Write-Verbose "Using an offset of $off based on length $($word.length)" [int]$y=$x+$off #get the new value [char]::ConvertFromUtf32($y) } #for #write the new "word" to the pipeline $NewWord=$chars -join "" $NewWord } #foreach word $Out+=$NewLine } #foreach line } #end process End { Write $Out } } #function Function ConvertFrom-PSCode { <# .SYNOPSIS Dencode a secret code into plain text .DESCRIPTION This command will decode a string or array of strings that was encoded with ConvertTo-PSCode back into plain text. If you used a custom scriptblock to encode the text, you will need to specify it here as well to decode. .PARAMETER Text The strings to encode. .PARAMETER Scriptblock A scriptblock that returns a numeric value to be used as the offset. The default is {($word.length%[math]::pi)+3}. .EXAMPLE PS C:\> "Ts{ivWlipp Wzqjx" | ConvertFrom-PSCode PowerShell Rules .EXAMPLE PS C:\> "This is a secret" | convertto-pscode | convertfrom-pscode This is a secret A "round-trip" demo that verifies coding and decoding. .EXAMPLE PS C:\> "I am the walrus" | convertto-pscode -scriptblock {$word.length+2} | convertfrom-pscode -Scriptblock {$word.length+2} I am the walrus A "round-trip" demo using a custom offset scriptblock. .NOTES NAME : ConvertFrom-PSCode VERSION : 0.9 LAST UPDATED: 7/17/2012 AUTHOR : Jeffery Hicks .INPUTS String .OUTPUTS String .LINK ConvertTo-PSCode #> [cmdletbinding()] Param( [Parameter(Position=0,Mandatory=$True,ValueFromPipeline=$True)] [AllowEmptyString()] [AllowNull()] [string[]]$Text, [ValidateNotNullorEmpty()] [scriptblock]$Scriptblock={($word.length%[math]::pi)+3} ) Begin { #an array to hold decoded output Write-Verbose "Starting $($myinvocation.mycommand)" $Out=@() } Process { #split text into words and lines foreach ($line in $text) { $newLine="" Write-Verbose "Processing line: $line" $NewLine+= foreach ($word in ($line.Split())) { write-Verbose " Processing word: $word" $chars = for ($i=0;$i -lt $word.length;$i++) { $x=$word[$i] #get the current numeric value $x=[char]::ConvertToUtf32("$x",0) #Calculate an offset that will be subtraced from the CHAR value. #The default is the length of the word modulo pi #rounded to an integer [int]$off=&$Scriptblock Write-Verbose "Using an offset of $off based on length $($word.length)" [int]$y=$x-$off #get the new value [char]::ConvertFromUtf32($y) } #for #write the new "word" to the pipeline $NewWord=$chars -join "" $NewWord } #foreach word $Out+=$NewLine } #foreach line } #end process End { Write $Out } } #function Function Invoke-PSCode { <# .SYNOPSIS Invoke a coded file .DESCRIPTION This command will take an encoded PowerShell file and execute it. .PARAMETER Text The encoded text. .PARAMETER Scriptblock The offset scriptblock. .PARAMETER Arguments A hash table of parameters to be passed to the encoded script. .EXAMPLE PS C:\> Get-Content c:\work\secret.txt | Invoke-PSCode -arguments @{Name="foo";Computername="server01"} Decode the secret.txt file and invoke it, passing it a few parameters. .NOTES NAME : Invoke-PSCode VERSION : 0.9 LAST UPDATED: 7/17/2012 AUTHOR : Jeffery Hicks .LINK Convertto-PSCode ConvertFrom-PSCode .INPUTS String .OUTPUTS None #> [cmdletbinding()] Param( [Parameter(Position=0,Mandatory=$True,ValueFromPipeline=$True)] [AllowEmptyString()] [AllowNull()] [string[]]$Text, [ValidateNotNullorEmpty()] [scriptblock]$Scriptblock={($word.length%[math]::pi)+3}, [hashtable]$Arguments ) Begin { Write-Verbose "Starting $($myinvocation.mycommand)" #define an empty string to hold the contents of the decoded command $a="" } Process { foreach ($item in $text) { #add each decoded line to the variable plus a line return Write-Verbose "Decoding $item" $a+="{0} `n" -f (ConvertFrom-PSCode -Text $item -Scriptblock $Scriptblock) } } #process End { Write-Verbose "Running command" #create a scriptblock $myCommand=$ExecutionContext.InvokeCommand.NewScriptBlock($a) #splat the arguments to the script block &$myCommand @Arguments Write-Verbose "Ending $($myinvocation.mycommand)" } } #end function Function ConvertTo-ReverseString { <# .Synopsis Reverse a string .Description This is a simple function to take a string and write it back to the pipeline in reverse. .Parameter Text The string or strings to be converted. .Example PS C:\> convertto-reversestring "PowerShell can be fun!" !nuf eb nac llehSrewoP .Example PS C:\> get-content data.txt | ConvertTo-ReverseString | Out-File reverseddata.txt Take the contents of data.txt, reverse each line and then save the results to a new file. #> [cmdletbinding()] Param( [Parameter(Position=0,ValueFromPipeline=$True)] [AllowEmptyString()] [AllowNull()] [string[]]$Text ) Process { Foreach ($item in $text) { Write-Verbose "Reversing $item" -join $(for ($i=$item.length;$i -ge 0;$i--) {$item[$i]}) } #foreach } #Process } #end function Export-ModuleMember -Function *