Monday, September 14, 2009

I hate computers OR unexpected results running powershell dos commands

You would think running a dos command from powershell would be simple right? I was trying to assemble a fairly complex command, run it and parse the results. (Trying to run TFPT from the Visual Studio powertools. This in it self was a work around so I could load 32 bit libraries in a x64 shell).

The command was pretty complex so I didn't realize where my problem truely was for some time after trying various invoke-expression/item, "&" running, cmd /c, etc.

I could not figure out why my command would run correct at the dos prompt but not work when running through cmd /c. Apparently, there is a VERY important little space that I wouldn't have thought would matter. Silly me.

$var = cmd /c " `"$TFPT`" workitem ..."
is not the same as
$var = cmd /c "`"$TFPT`" workitem ..."

It seems that the powershell processor needs that space for it to correctly pass the line to the cmd shell. I don't know why.

Hopefully this will help somebody out.

Wednesday, September 09, 2009

Force a powershell script to run in x86 process with arguments

I needed to instantiate TFS variables but they seem to only be available in 32 bit run space.  I found a few great work ups for the vcvars here:

http://www.agileprogrammer.com/dotnetguy/archive/2007/11/22/23853.aspx

http://www.tavaresstudios.com/Blog/post/The-last-vsvars32ps1-Ill-ever-need.aspx

 

I will note that in my travels I found Jaredpar and added most of these functions to my library to test for x64/x86 program space.

 

I ended up going w/ the last one but I then needed to make sure my script was running in x86 space.  This would be automated out of SCOM so I couldn’t really just tell my users to run in in the right version (besides, what kind of solution is that?).  Some of the tasks would be run from x86 space and some from x64. 

 

Vivek Sharma had a good write up that put me on the right path here: http://www.viveksharma.com/TECHLOG/archive/2008/12/03/running-scripts-that-only-work-under-32bit-cleanly-in-64bit.aspx.

 

I had two problems.  First off, the solution doesn’t work.  -file didn’t work, I assume this is a powershell 2 change.  Neither did –executionpolicy.  ( I didn’t check if either were around in v1 but I did check my solution against a v1 install).  I also needed the arguments so after a bit of banging around, this is what I came up with.

 

#force this to run in 32 bit

if ($env:Processor_Architecture -ne "x86")

{

      write-warning "Running x86 PowerShell..."

            &"$env:WINDIR\syswow64\windowspowershell\v1.0\powershell.exe" -NonInteractive -NoProfile $myInvocation.Line

      exit

}

 

 

 

I created the following and called it test-Launch32Bit.ps1 to show usage.  Run with PS> test-Launch32Bit.ps1 –arg1 argument1 –arg2 aarrrrgghhh

"My Script Line: $($myinvocation.line)"

"My Proc Architecture: $env:Processor_Architecture"

"List arguments below:"

"##############"

$args

"##############"

 

 

#force this to run in 32 bit

if ($env:Processor_Architecture -ne "x86")

{

      write-warning "Running x86 PowerShell..."

            &"$env:windir\syswow64\windowspowershell\v1.0\powershell.exe" -noninteractive -noprofile $myinvocation.Line

      exit

}

 

 

Note that you will need to set your execution policy beforehand for each x86 and x64 registry trees.  They are not the same setting!  I am sure this stems from the invisible x86 registry redirection.  Easiest thing is to just run each yourself and set-executionpolicy to whatever your env demands. 

analytics