Use Microsoft .NET Framework String Methods from Windows PowerShell

Use Microsoft .NET Framework String Methods from Windows PowerShell

  • Comments 7
  • Likes

 

Summary: Microsoft Scripting Guy Ed Wilson teaches how to use .NET Framework string methods from within Windows PowerShell,

 

Hey, Scripting Guy! QuestionHey, Scripting Guy! There are many things I need to do with strings and with text files that do not seem to be supported with Windows PowerShell. It is strange, but many common operations seem to have been neglected. I saw somewhere a technique for running VBScript code from within Windows PowerShell, and I am thinking about trying that out. What do you think is it doable?

-- PW

 

Hey, Scripting Guy! AnswerHello PW, Microsoft Scripting Guy Ed Wilson here. Working with the .NET Framework is always fun. It almost seems like a trick to be able to use such a powerful resource from a mere scripting language.

Because Windows PowerShell resides upon the .NET Framework, it means I have access to .NET Framework classes from inside Windows PowerShell. One of the most important classes for Windows PowerShell scripters is the System.String class. I looked at the System.String class yesterday.

I want to continue exploring the System.String class today by looking at the EndsWith method. The EndsWith method returns a Boolean value if a string ends with a particular string value. In the example that follows a string is stored in the $a variable. To examine several string ending scenarios use the EndsWith method. A single letter match returns true, and a single letter that does not match returns false. If a partial word letter sequence matches a sequence of letters in the last word, then it returns true. Wildcard characters match as literals and therefore return unexpected results. The code that follows shows these scenarios.

PS C:\> $a = "this is a string"
PS C:\> $a.EndsWith("g")
True
PS C:\> $a.EndsWith("e")
False
PS C:\> $a.EndsWith("ring")
True
PS C:\> $a.EndsWith("sring")
False
PS C:\> $a.EndsWith("string")
True
PS C:\> $a.EndsWith("str*")
False
PS C:\> $a.EndsWith("strin*")
False
PS C:\>

 

An interesting method is the clone method. It is interesting not from the perspective of direct utility but from a readability point of view. The clone method copies the object that is contained in a variable. In the example seen here, I use the clone method to clone the string stored in the $a variable and to store the resultant copy in the $b variable. I then use direct assignment to store the contents of $a in the $c variable. The effect, in this scenario is the same, but there are differences in the actual behavior of the two operations. The code is shown here.

PS C:\> $a = "a new string"
PS C:\> $b = $a.Clone()
PS C:\> $b
a new string
PS C:\> $c = $a
PS C:\> $c
a new string
PS C:\> $b.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object


PS C:\> $c.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object


PS C:\>

 

Occasionally I have to insert text into the one that is stored in a variable. To do this requires two steps. The first step involves determining the insertion point, and the second step is the actual insertion itself. Several methods can determine the insertion point for a string. There is only one insert method. If I need to add a string to the end of a string, I can use the length property of the string to determine my insertion point. The code that appears here shows this technique.

$a = "This is a string"

PS C:\> $a.Insert($a.length," that is cool")

This is a string that is cool

 

Instead of going to all the trouble of using the insert method to add to the end of a string stored in a variable, I would probably use concatenation as seen here.

PS C:\> $a = "This is a string"

PS C:\> $a + " that is cool"

This is a string that is cool

PS C:\>

 

Concatenation cannot perform sophisticated types of string augmentation. The LastIndexOf method locates a character or series of characters inside a string. This location becomes the insertion point. In the code that appears here the LastIndexOf method locates the letter a in the string stored in the $a variable. The first try does not work due to failure to account for the need for a space before the insertion string. In addition, it fails because the LastIndexOf method returns a zero-based number. The last command corrects both problems.

PS C:\> $a = "This is a string"

PS C:\> $a.insert($a.LastIndexOf("a"),"really big")

This is really biga string

PS C:\> $a.insert($a.LastIndexOf("a") +1," really big")

This is a really big string

PS C:\>

 

Sometimes I have to replace a word in a string that is stored in a variable. The Replace method makes quick work of these cases. The syntax is replace(original, replacement). In the code that follows a string is stored in the $a variable. The Replace method replaces the word string with the word phrase. The output displays to the Windows PowerShell console but is not stored in either the original variable or a new variable. This code appears here.

PS C:\> $a = "This is a string"

PS C:\> $a.Replace("string","phrase")

This is a phrase

PS C:\>

 

In addition to using the Replace method from the System.String class, Windows PowerShell provides a replace operator that works in a similar manner as the Replace method. Most of the time I will use the Replace method from the String class because tab expansion will complete the command for me. In the code seen here, tab expansion does not work for the replace operator. Therefore, the command requires manual typing into the Windows PowerShell console. As seen here, the command and the output matches well to the Replace method from the String class.

PS C:\> $a = "This is a string"

PS C:\> $a -replace("string","phrase")

This is a phrase

PS C:\>

 

A common scenario is parsing text from an array. Whether the array comes from reading a text file through the Get-Content cmdlet, or is a hard-coded array such as the one shown here, the String methods work in the same way as they did with a single string. In the code example seen here, an array of computer names is created and stored in the $a variable. When the contents of the $a variable displays each computer name is listed on a single line. The IndexOf method locates the colon that follows the word computer in each element of the array. It appears in position 8. When the SubString method is used to retrieve all the text following starting position 9 the space was included in the text that returns. Adding an additional space to allow for the starting position corrects the output. This code appears here.

PS C:\> [array]$a = "computer: berlin","computer: hamburg","computer: munich"
PS C:\> $a
computer: berlin
computer: hamburg
computer: munich
PS C:\> $a | foreach-object { $_.indexof(":") }
8
8
8
PS C:\> $a | foreach-object { $_.substring(9) }
 berlin
 hamburg
 munich
PS C:\> $a | foreach-object { $_.substring(10) }
berlin
hamburg
munich
PS C:\>

 

The commands and their associated output appear in the following figure.

 

PW, that is all there is to using .NET Framework String methods to manipulate strings with Windows PowerShell. This also ends .NET Framework week. Join me tomorrow when I open the virtual mail bag and answer a whole raft of puzzling questions-that's right, it is time for Quick Hits Friday.

I invite you to follow me on Twitter or Facebook. If you have any questions, send email to me at scripter@microsoft.com or post them on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

 

Ed Wilson, Microsoft Scripting Guy

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Dear Scripting guy,

      I would like to know how to send a control message to a service using PS.  The syntax with sc.exe is

    sc <server> control [service name] <value>

    I have created services that take custom commands and do cool things (a scheduler that starts running its scheduled tasks right away rather than wait for the scheduled time, re-read the config file, etc.), and would like to use PS to send those commands to it.  To be ultra clear, I would like a PS way to do this:

    sc.exe \\myserver control dwscheduler 201

    Thanks,

    Aaron

  • You can use the executecommand method from the System.ServiceProcess.ServiceController .NET Framework class to do this. The easy way to obtain this class is to use the Get-Service Windows PowerShell cmdlet. Following your example, you could do the following: (Get-Service -computername myserver -name dwscheduler).ExecuteCommand(201)

    Using aliases and positional parameters, you can shorten the typing to this:

    (gsv dwscheduler -cn myserver).ExecuteCommand(201)

  • Dear Scripting guy,

     Thanks!  So, the return type of Get-Service is a System.ServiceProcess.ServiceController.  Good.

     I found that out by running

    (get-Service <service>).GetType().Name

    Is there a better way to find the Type of a variable?

    Aaron

  • Dear Scripting Man,

     Ahh, Get-Service returns a System.ServiceProcess.ServiceConroller.  This is good, now I know what's going on.

     I found that type name by running

    (get-Service <service>).GetType().Name

    Is there a better way to find out what type a variable is?

     I'm still not used to everything being an object.  It took a bit when I learned java (and c#), and I guess it will take a little while while learning PS coming from Unix and command.com where everything is as it looks, processes and strings of characters.

    Thanks,

    Aaron

  • Dear Scripting Man,

      Sorry for the duplicate post earlier, I can't seem to edit it or delete it.

     Also, in your example, you used "-cn" for "-ComputerName".  I read somewhere (I really wish there were an official language guide for PowerShell so that I don't have to say, "I read somewhere") that you can specify just enough of the parameter name to make it unique to good effect.  It looks like you've just taught me that Powershell also reads camel-case?  What if there is a parameter "-cn" and a parameter "-ComputerName" ? Or perhaps there's a parameter alias for ComputerName?  If so, is this alias just for gsv, or is it PS-wide?  Thanks for your time.

    Aaron

  • You can use either Get-Member or typename() to retrieve the type of a variable. -CN is an alias for the -computername parameter. At this point, the online help files, and technet and MSDN comprise the official language guide for Windows PowerShell.

  • What about Substring and all the stuff you can do with that??

    I was reading this trying to figure out a more graceful way to extract a substring from a string. Is there a good way to remove characters that appear before and after a desired substring?