Friday, January 18, 2008

Copying and pasting long strings into the console

In the PowerShell NNTP newsgroup, a user had a long string of code that covered multiple lines (had line breaks), and the user was attempting to paste the code into the PowerShell console.

The string was a long Exchange 2007 command.  Because of the line breaks that were included in the copy and paste, the command string would not run in the Exchange Management Shell.

A very simple example, yet still similar, of what the user was copying and pasting from Notepad (or some other text editor/application) was:

write-host
"testing"
-foregroundcolor
"red"

So if I copy this from Notepad, then paste it directly into a PowerShell console, and try to run it, it will fail when it hits the -foregroundcolor line.

So, just for fun, I thought there must be a easier way to do this, and started looking at HERE strings.

So from, PowerShell, I typed:

PSH>$multi=@' [hit enter]
[copy and paste the code from Notepad as is]
>> '@ [closed off the HERE string]
>> [hit enter]

Now, I have a string named $multi with all the data I need:

PSH>$multi
write-host
"testing"
-foregroundcolor
"red"

Now, my only problem is that it is on separate lines, but it is still a string object.

PSH>$multi.gettype()

IsPublic IsSerial Name
-------- -------- ----
True     True     String

I need to combine this all into a single string, then I can use invoke-expression to run it.

So, I need to loop through every single character in $multi, and combine it into one single line.  I have to do a something a little fancy with the return character.  To easy the change, I also turn it into a string, then I have the replace method available.

So here's something I put together:

for($i=0;$i -lt $multi.length;$i++)
{
  if($multi[$i].tostring() -eq [char]10)
  {
    [string]$join+=$multi[$i].tostring().replace([char]10,[char]32)
  }
  else
  {
    [string]$join+=$multi[$i]
  }
}

 

After I run this, I get:


PSH>$join
write-host "testing" -foregroundcolor "red"


Finally to invoke it, I just do:


PSH>invoke-expression $join
testing [output is red]


Obviously, I have to reset $join to nothing to reuse it again later:


PSH>$join=""


Hopefully, this helps others when trying to do quick copy and pasting into a PowerShell console.

It would be good to create a function of this, and likely define the input and output strings as arguments.

I'll do just that in a future blog post.

Update: January 24th, 2008.  Check the comments on how to drastically simplify this.  Since a HERE string is a string object, I should have just used the replace method on the entire HERE string, instead of doing a for loop at all...