Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Condition with a function call in PowerShell

Tags:

powershell

Something is really weird with this language. I'm trying to execute a function and use its result value as condition. This is my code:

function Get-Platform()
{
    # Determine current Windows architecture (32/64 bit)
    if ([System.Environment]::GetEnvironmentVariable("ProgramFiles(x86)") -ne $null)
    {
        echo "x64"
        return "x64"
    }
    else
    {
        echo "x86"
        return "x86"
    }
}

if (Get-Platform -eq "x64")
{
    echo "64 bit platform"
}
if (Get-Platform -eq "x86")
{
    echo "32 bit platform"
}

The expected output is this:

x64
64 bit platform

But the actual output is this:

64 bit platform
32 bit platform

What's going on here? How can this be fixed? I couldn't find any examples on the web that use functions inside an ifcondition. Is that possible at all in Powershell? I'm on Windows 7 with no special setup, so I have whatever PS version comes with it.

like image 540
ygoe Avatar asked Apr 10 '13 15:04

ygoe


2 Answers

If you want to compare the return value of a function in a conditional, you must group the function call (i.e. put it in parentheses) or (as @FlorianGerhardt suggested) assign the return value of the function to a variable and use that variable in the conditional. Otherwise the comparison operator and the other operand would be passed as arguments to the function (where in your case they're silently discarded). Your function then returns a result that is neither "" nor 0 nor $null, so it evaluates to $true, causing both messages to be displayed.

This should do what you want:

...
if ( (Get-Platform) -eq 'x64' ) {
  echo "64 bit platform"
}
...

BTW, you should avoid using separate if statements for conditions that are mutually exclusive. For a platform check an if..then..elseif

$platform = Get-Platform
if ($platform -eq "x64") {
  ...
} elseif ($platform -eq "x86") {
  ...
}

or a switch statement

Switch (Get-Platform) {
  "x86" { ... }
  "x64" { ... }
}

would be more appropriate.

I'd also avoid echoing inside the function. Just return the value and do any echoing that might be required in with the returned value. Anything echoed inside the function will also be returned to the caller.

One last note: personally I'd rather not rely on the existence of a particular folder or environment variable for determining the operating system architecture. Using WMI for this task deems me a lot more reliable:

function Get-Platform {
  return (gwmi Win32_OperatingSystem).OSArchitecture
}

This function will return a string "32-Bit" or "64-Bit", depending on the operating system architecture.

like image 104
Ansgar Wiechers Avatar answered Sep 23 '22 06:09

Ansgar Wiechers


I think you are comparing a function and not the function result. Also somehow the echo does not work as expected in a function. I usually use Write-Host.

Here is my solution to your problem:

function Get-Platform()
{
    # Determine current Windows architecture (32/64 bit)
    if ([System.Environment]::GetEnvironmentVariable("ProgramFiles(x86)") -ne $null)
    {
        Write-Host("x64")
        return "x64"
    }
    else
    {
        Write-Host("x86")
        return "x86"
    }
}

$platform = Get-Platform

if ($platform -eq 'x64')
{
    echo "64 bit platform"
}

if ($platform -eq 'x86')
{
    echo "32 bit platform"
}
like image 36
flayn Avatar answered Sep 25 '22 06:09

flayn