Contact

Subscribe via Email

Subscribe via RSS

Categories

Recent Posts

Creative Commons Attribution 4.0 International License
© Rakhesh Sasidharan

Converting text to capital case, lower case, and title case

The previously blogged System.Globalization.CultureInfo class has some useful methods for converting text to upper case, lower case, and title case.

These methods can be used thus:

Good to know!

Removing the first four characters in an array in PowerShell

Looking at my site stats I saw someone had reached this blog via the above query. Here’s a quick one liner on how to do it:

Assuming an array of strings $array, do the following:

That’s all!

You can also do the following (probably more readable):

Warning: There are probably better/ more efficient ways to do this as I am just a beginner to PowerShell.

What I do is (a) for each element of the array (b) extract a sub-string starting from the 5th place (strings start from 0, hence SubString(4) stands for “extract everything from the 5th character”) and (c) put it back into the array. Rather than keep a counter I just use the IndexOf method to find the index of the element we are looking – this is required so I can replace the element at that index with the extracted text.

If you don’t care about putting the extracted text back into the array it’s even more straight-forward:

Modifying Junk Email configuration using PowerShell

You can use the (Set|Get)-MailboxJunkEmailConfiguration cmdlets to set or view the Junk Email configuration of a mailbox. For instance:

From the Get-MailboxJunkEmailConfiguration output above I can see Junk Email configuration is Enabled for this mailbox, all email addresses in the Contacts folder of this mailbox are automatically added to the trusted senders list, any emails from the example.com domain are considered trusted senders and delivered to the mailbox, and no domain is considered blocked and hence not delivered to mailbox. Further, the mailbox is not solely relying on these trusted lists – if it were, then only addresses in the trusted list would be allowed through and everything else discarded.

To change these values use the Set-MailboxJunkEmailConfiguration cmdlet. Its syntax is pretty straightforward.

To add entries to the trusted or blocked senders lists one must retrieve the entries first and then append to it. So either do it the longish way like this:

Or do it all in one go like this:

In either case the result is the same:

Of course, goes without saying, the beauty of being able to do something like this via PowerShell rather than manually on Outlook or Outlook Web App is that you can do bulk action. Like for instance:

Easy to see at one shot what the status for each user is.

I can get rid of the OU name in the Identity column via some format-table regexpery.

A variation of the above:

Here I am using regexp to strip out the “rakhesh.com/Planet” bit so I only get the user identity and the OU it is in. I do this by making the + regexp operator non greedy so it doesn’t match all the input text – rather, it stops at the first “/” character. I then put this regexp in brackets to club it together and tell PowerShell to match exactly two instances of this (hence the {2}) so what remains is the bit which I want. Regexps are great when they work and you can make sense of them!

Dot star replace matches twice

Have a look at this:

Works as expected. It matches “bc” in the input text and replaces the output with “ff” followed by whatever was matched (in this case “bc”).

The second example makes things clearer. It’s obvious in retrospect but easy to forget. We are not matching for the words “bc”, we are actually matching for a pattern “abc”: the text “bc” preceded by an “a”. If such a pattern is found, that matched pattern is replaced with the words “ff” followed by part of the matched pattern (in this case “bc”).

The third example simply drives home the point that the pattern can be anywhere in the input and that multiple instances are matched & replaced.

Another one:

What’s going wrong here? I expected the entire input to be replaced with one word – “blah”. Why do I have it twice then? This happens even if I do variations of the above thus:

It looks like the pattern matching-replacing is taking place twice. Lines 3 & 4 make it clearer above. The first time “abc” is replaced with “blah[abc]” as expected, and then a matching-replacing seems to occur again on that same input text adding “blah[]” to “blah[abc]”. No matching seems to take place however, or the matched pattern is empty, and that’s why there’s no text within the square brackets.

Hmm. So maybe that’s the problem! The matched pattern is empty – which is acceptable as my regexp pattern is .* and that matches empty text too. If I replace .* with .+ (at least one character must match) does that work as expected?

Sweet, it does!

Moral of the story: be careful using the .* pattern – apart from matching everything in the input, it will also match the emptiness that remains.

Obfuscate email addresses with PowerShell

Came across the following piece of code in someone’s signature today.

It’s a geeky way of obfuscating your email address. If you copy paste that bit of code into a PowerShell window and press ENTER, you get an email address.

I’d like to make something similar. Especially since it just coincides with what I was playing around with today morning. But before that I’d also like to understand what’s going on above. So let’s break this one-liner and peek behind the curtain.

Understanding

First things first: if I remove the [string] type cast and run the code I get a bunch of characters – one on each line. So what the type cast does is convert these characters to a one-liner string.

Next, I piped the email address that was output to the Measure-Object cmdlet with the -Character switch. That gave me the number of characters in the address: 34. This coincides with the next bit of the code – 0..33 – which is shorthand for generating the numbers 0 to 33 (34 numbers). So looks like that bit is responsible for driving something to generate each character of the address.

Great. What’s happening next?

The code generates 34 numbers. For each of these numbers it does something.

First a sub-string is extracted from that long series of numbers. This long series of numbers is stored as a string (hence the double-quotes). From this a sub-string of 2 characters is extracted. The starting point of extraction jumps forward by 2 each time (position 0, then 2, then 4, 6, 10, and so on up to 66) – breaking the long string into a series of 2 digit numbers.

Here’s the relevant code:

This generates numbers 68,65,52, … 70.

To each of these the code adds the number 46. So the numbers actually output are 114,111,98, … 116. Each of these is then converted to a character – which is what the [char][int] bit does. And the rest we already know – these characters are converted to one long string showing the email address. (There’s one gotcha though, in that the string has the characters separated by a space. Which is why we have a -replace " " tacked on the end – this simply replaces are spaces with nothing, combining all the characters into one word).

Genius! (At least for a PowerShell child like me).

Creating

Okay. So how do I create something similar?

First things first: if I were to just convert an email address to ASCII/ UTF-8 codes what do I get?

I could join these numbers, with dots perhaps, to form a long string.

If I wanted to get my address from such a string I’d do something like this:

That outputs the numbers, I can just convert them back to an address.

Great. So that’s something I could paste in a signature somewhere and anyone running that code will get an email address.

I got side tracked though. What would I do to get something similar to the code the user created? Backtracking:

I have a series of numbers. They are of varying length so I can’t just club them together and hope to extract. I need to get them all to a uniform length, so an easy idea would be to just subtract them all by some number to make them 2 digits each. The number has to be larger than 46 – as that’s the smallest number – so why not just use 46 as the number to subtract from all?

So now all I need to do to reverse the process is (a) split the long number into chunks of two, (b) add 46 to each, (c) convert to a char, and (d) convert the array of characters into a string.

It worked! Sort of. Something messed up though. And the email address is mostly generated but for the last 4 characters. It looks like the string is falling short for the Substring method.

A few minutes of head scratching later, I realize the problem. When I converted all the numbers to two digits, one of them was one digit – the number 46 that got subtracted by itself. This was resulting in a string that fell short. Not to worry, all I had to do was pad a 0 to that number and then it will work.

Automating

Can I automate this process? One where any string I give is converted to code that will generate the string when run.

A proper generic code would take a bit more effort and time, but since I am mainly concerned with email addresses I can take some short cuts. If I were going to build a generic code I’d (1) need a way to find the smallest ASCII/ UTF-8 code in the set entered, (2) while subtracting that number from every number I’d have to ensure any single digit number is accordingly padded, and (3) I’d also have to be concerned with any text that may have an ASCII/ UTF-8 code which won’t reduce to two digits when I do the subtraction above.

First thing to notice is that the number that we are subtracting – in my example above, as well as the code I started off with – is 46. Which turns out to be the dot in the email address. Next thing to notice is that letters A-Z and a-z have codes 65-90 and 97-122. Similarly the numbers 0-9 have codes 48-57. So by limiting myself to this set of characters I can be sure that the lowest number will always be 46, and that I can subtract it from any of the expected characters and expect a single or double digit result.

But why not got a teeny weeny step further. Checking WikiPedia for the syntax of valid email address I see that the lowest ASCII/ UTF-8 code for an allowed character is 32 (the character being “) and the highest allowed ASCII/ UTF-8 code for an allowed character is 126 (the character being ~). So the code I generate will be similar to the code I started this post with, except that I’ll be adding 32 instead of 46. And so the code I create to generate this code will output 32.

So without much ado here’s the code:

Of course, replace “abc@example.com” with the email address you’d like to obfuscate.

For the curious, here’s an explanation of my code (the bit after the first pipeline).

Line 1 outputs the part of the final code that starts with a [string] and ends at the beginning of the series of digits (just before the left bracket).

Line 3 outputs the part of the final code that starts where the digits end (just after the right bracket) and goes all the way up to -replace " ".

These two lines are pretty straight-forward. Only point to note is I escape the $ symbols with a backtick (`) so they don’t get interpreted as variables. And I get the length of the input text via $_.Length (this is why I put the whole block within a ForEach-Object loop as that’s the only way to make $_ variable available). Also, I put the expression as $($_.Length-1) because if I don’t do that PowerShell expands $_ into a string and then tacks “.Length-1” to it as another string.

Line 2 is a variant of what I created earlier. It converts the input string into an array of characters, cast into an array of integers, and pipes these into another ForEach-Object loop that subtracts the number 32 from each and if the result is less than 9 (i.e. single digit) pads a “0” before outputting the number.

And that’s it!

Getting the ASCII/ UTF-8 value of a string

To display the character associated with an ASCII/ UTF-8 code do the following:

Thanks to this PowerTip.

Now how about the reverse? Can I get the ASCII/ UTF-8 code of a character.

No luck. But I think am the right track.

The error InvalidCastFromStringToInteger is what tells me PowerShell is trying to cast from a [string] to [int] – which is not what I want and will obviously fail. I want to cast from a [char] to [int] so let’s be explicit about that.

Good, that works!

Now how about getting the ASCII/ UTF-8 of a string. Can I do that?

As expected, you can’t just pass two characters and hope it works!

What I need is an array of [char] elements. Which I can then type cast to an array of [int] elements.

First let’s look whether there’s any method available to convert a string to an array of characters?

Looks like there is. Does the following work?

No, but that gives me a hint on the solution. The output of the ToCharArray() method is of the data type System.Char[] whereas [char] is shorthand for the System.Char data type.

So maybe [char[]] is what I need? Does such a data type exist?

Sure enough it does!

So let’s try the following:

I don’t need the ToCharArray() method either as if I just type cast a string to an array of characters the method is invoked implicitly. Sweet!

Armed with this info I try type casting the string to an array of integers to get their ASCII/ UTF-8 values:

Nice!

Can I make this better? As in, say I had a longish string; currently the above snippet just gives a bunch of codes and that’s not very helpful if I want to see the code of a particular letter. Can I get the output such that it shows each character followed by it’s ASCII/ UTF-8 code? Something like this:

D’oh! Doesn’t help. But I am on the right track, and I know what to do. You see, within double quotes the [int] is not evaluated (thanks to this Hey, Scripting Guy! post) and so I have to force evaluation through any one of the methods mentioned in that post. I prefer the VBScript approach, so here goes:

Bingo!