PowerShell and some adventures in environment variables, quotes and output wrapping

Summary: Solving issues with implementing a PowerShell script that generates PowerShell code with correct quoting and no output wrapping, and calling this PowerShell generator script from a cmd.exe batch script.

The story:

In my adventures with PowerShell I have such a simple problem that is giving me a headache for hours now.

I want to write out a set environment variables to a PowerShell file as PowerShell variables with the same name as the environment variable that are assigned the value of the environment variable.

So there is an environment variable set as follows:

set MyFirstLittleEnvironmentVariable=Hello Amsterdam!

And I want to write this out to:

$MyFirstLittleEnvironmentVariable = 'Hello Amsterdam!'

Powerful as PowerShell is, this is simple. For example I want to write out all variables starting with "My":

Get-Item -path env:My* | foreach { [String]::Format("{0}{1} = {2}{3}{4}", "`$", $_.Name, "`'", $_.Value, "`'")

Note all the trickery to get the quotes around the value, if you know a smarter way, please let me know. This costed me another hour:-(

This all works nice and sweet, if I execute this command from a PowerShell prompt I get exactly what I want.

Now I want to redirect this output into a file. I save the above command to file SaveMyEnvironmentVariables.ps1, and then I execute the following command:

SaveMyEnvironmentVariables.ps1 > "c:\My Script Files\MyEnvironmentVariables.ps1"

And what happens: the outputted lines are wrapped at 80 characters, not something you want when generating code!

After some digging I found some some links that helped me out a little bit, but still not solved the problem:

In my situation my output goes through Host-Out, and Host-Out has by default a formatting specified of 80 characters. See also help about_diplay.xml in your PowerShell command prompt.

I want to save my output by redirecting the output of my PowerShell script to another file. I could not get this working.

My current solution is:

Get-Item -path env:My* | foreach { [String]::Format("{0}{1} = {2}{3}{4}", "`$", $_.Name, "`'", $_.Value, "`'") } | Out-File -FilePath $Args[0] -width 2147483647

UPDATE: Thanks to The PowerShell Guy I could bring my solution back to the way more readable version below:

Get-Item -path env:My* | foreach { "`$$($_.Name) = `'$($_.Value)`'" } | Out-File -FilePath $Args[0] -width 2147483647

And for real good examples of the usage of PowerShell, have a look at http://www.thepowershellguy.com.

Where Args[0] is the first parameter specified to the script and 2147483647 is the max width (it's a signed 32 bit parameter).

I now have to call my script as follows:

SaveMyEnvironmentVariables.ps1 "c:\My Script Files\MyEnvironmentVariables.ps1" from the PowerShell prompt.

But actually I need to call it from a good old cmd.exe batch script. And there is got complex, so that is why I initially decided to solve my problem by redirecting my output. Examine the following statement carefully and especially look at the quotes;-), it took me another half an hour to solve all the problems you get with spaces in paths:

PowerShell -Command "& 'c:\My Script Files\SaveMyEnvironmentVariables.ps1' 'c:\My Script Files\MyEnvironmentVariables.ps1'"

3 Comments

  • You can also embedd the variable in the string using $()

    ls env:\my* |% {"set $($_.name) = '$($_.vALUE)'"}

    Greetings /\/\o\/\/

  • you can also do it direct :

    ls env:\my* |% {invoke-expression "`$$($_.name) = '$($_.Value)'"}

    or

    ls env:\my* |% {set-variable $_.name = $_.Value}


    Greetings /\/\o\/\/

  • Hi /V\oVV,

    Thanks for your response! In my situation I need to write the environment variable values for later usage from another script, but you showed some valueable new approaches. Especially the $(..) evaluation within strings was just what I needed! Thanks!!

    PS: love your blog!!

Comments have been disabled for this content.