PowerShell Pipeline
Taking Control of Strings in PowerShell
Here's how to format and use strings in your code.
Strings are a very common thing to see and use in PowerShell. Parameters may take strings and a lot of times the objects that are outputted by various commands have strings as their properties. In fact, everything in PowerShell can be casted as a string. By casting I mean that we can convert everything (integers, objects, etc.) to a string, even though it may not look like it did prior to the string conversion.
Working with Strings
The first thing that I will talk about is working with strings. This includes formatting and the differences between double quotes and single quotes (yes, there is a big difference between these two).
When I think of a string, I think of a bunch of text like this:
I simply write out something with double (or single) quotes and it shows up on the console. Now I used double quotes here, which is fine, but using double quotes means that I can actually evaluate a variable and display it in my string. So I could do something like this to have a different type of message:
$MyName = "Boe Prox"
"Hello $($MyName), today is $((Get-Date).DayOfWeek)"
Now I have taken my variable (or a command) and will evaluate it and display it as a string within my text. This is very useful if you wanted to display some verbose or debug messages as well as display your own errors if needed.
Notice also how I have each of these encased in a $(). This ensures that I properly evaluate the variable or command. Not doing that will result in something like the following image.
I've mentioned double quotes and given an example, but what about single quotes? Usually you will want to use these when you are only planning on displaying text without looking to evaluate any variables or commands within the text. Using my example above, you will see that everything is treated as a literal text and nothing gets evaluated.
$MyName = 'Boe Prox'
'Hello $($MyName), today is $((Get-Date).DayOfWeek)'
It is definitely important to know the difference between these two so you are providing the proper output.
If you wanted to know just how many characters are in a string, you can use the Length property to find this out.
$MyName = "Boe Prox"
("Hello $($MyName), today is $((Get-Date).DayOfWeek)").Length
Here-Strings are a great technique to use if you want to have a lot of text that cover several lines. Using HTML code is a great example of this.
@"
This is a an example
of some lines of text
that were created on
$(Get-Date)
"@
In this example I used double quotes, but you can also use single quotes if you are not planning on evaluating variables or commands.
One last thing on this topic. Did you know that you can format these strings? It is quite simple using the –f operator to perform the formatting. Given, some of these may seem a little odd, but once you start using them, it becomes like second nature. A couple of examples are seen below.
#Show Day of the Week
"Today is {0:dddd}" -f (Get-Date)
#Percentage
"{0:P}" -f (5/10)
#Currency
"{0:C}" -f 5
#Convert to Hex
"0x{0:x}" -f 55
Manipulating Strings
Now that we have spent some time with formatting strings and displaying ways to display them, we should take a look at manipulating those strings.
If for some reason you wanted to put all of the text in all caps, you can make use of the ToUpper() method that is available in the string.
$Text = "Hello there!"
$Text.ToUpper()
The same can be done with ToLower() to ensure that nothing is capitalized.
$Text = "THIS IS ALL CAPS"
$Text.ToLower()
Let's say that you have a string that is comma separated, but you wanted to turn this into an array of items instead. We can make use of the .Split() method or use the –Split operator to perform this action. The important thing to remember is that using the .Split() method is a literal approach and is case sensitive. So what you ask for is what you get. Using –Split assumes that you are using Regular Expressions instead, so you need to make sure that you have an understanding of this technique. Although in most cases with the –Split, you can just use the similar character, such as a comma in this case.
$Text = 'cat,dog,bird,turtle,frog'
$Text.Split(',')
$Text -split ','
We can also find the location of a character in a string by looking at IndexOf() and supplying the character. In this case, we can see that the letter "y" is the 37th character in the following string.
$Text = 'The quick brown fox jumps over the lazy dog'
$Index = $Text.IndexOf('y')
$Index
I can actually use this knowledge with SubString() to display all of the characters up until this character. With Substring, I can specify a starting index and then display all of the text up until the end or until it goes to a specified index that is specified. Note that if you specify an index that goes beyond the length of the string, it will throw an error.
$Text = 'The quick brown fox jumps over the lazy dog'
$Index = $Text.IndexOf('y')
$Text.Substring(0,$Index)
The last thing that I will show today is how you can replace things in a string using both the .Replace() method and the Regular Expression approach using the –Replace operator. Much like the .Split() operator, it requires a literal value that is case sensitive while the regular expression provides some more flexibility with what you can replace.
An example of how case sensitivity can play into using .Replace()
$Text = "This is Boe, but boe isn't around at the moment"
$Text.Replace('Boe','Jeff')
This example shows how you can make use of regular expressions with –Split to provide some more flexibility in what you can replace. In this case, I want to replace the first two octets in a IP address with xxx so it is not completely known.
$IPs = "168.192.1.1, 185.25.26.59, 10.15.1.12, 158.128.2.45"
$IPs -replace '\d{1,3}\.\d{1,3}\.','xxx.xxx.'
With that, we have covered some approaches to working with strings and manipulating strings using a variety of methods. We haven't really begun to scratch the surface of the different ways that we can manipulate strings, but this should certainly get you going in the right direction.
About the Author
Boe Prox is a Microsoft MVP in Windows PowerShell and a Senior Windows System Administrator. He has worked in the IT field since 2003, and he supports a variety of different platforms. He is a contributing author in PowerShell Deep Dives with chapters about WSUS and TCP communication. He is a moderator on the Hey, Scripting Guy! forum, and he has been a judge for the Scripting Games. He has presented talks on the topics of WSUS and PowerShell as well as runspaces to PowerShell user groups. He is an Honorary Scripting Guy, and he has submitted a number of posts as a to Microsoft's Hey, Scripting Guy! He also has a number of open source projects available on Codeplex and GitHub. His personal blog is at http://learn-powershell.net.