AD2995
AD2995

Reputation: 31

How do I change the value of a variable using a function in powershell?

I want to check the count of the items in a variable and change the value of the variable depending upon the count. Further, I want to use this function to validate other variables as well. Below mentioned is the code.

$c=@()

function Status($s)
{
   if($s.Count -eq "0"){
       $s = "Fail"
   }else{
       $s="success"
   }
}

Status $c

Here I expected the value of $c would be "Fail". But instead the value remains to be null.

Upvotes: 3

Views: 3700

Answers (3)

T-Me
T-Me

Reputation: 1884

If you want to change multiple variables in one function you need references or scopes. Scopes will change the variable with the same name inside the function and globally. Calling a variable by reference is indifferent to the variable names outside the function.

Reference:
Working with references your variable in the function needs to be of type [ref] ( or System.Management.Automation.PSReference ). In that case the argument you use must be cast to [ref] and to this before calling the function enclose the var with brackets ([ref]$c). When using references, you can't just change the variable itself, but you need to work with its .value. The value of your reference represents your original variable. ([ref]$s.Value -eq $c)
Using that your code would look like this:

$c=@()

function Status([ref]$s)    #Define $s as [ref]. only arguments of type [ref] are valid
{
    if($s.value.Count -eq 0)
    {
        $s.Value = "Fail"    #This will change the type of $c from array to string
    }
    else
    {
        $s.Value += "success"    #This will recreate the array with an additional object (string)
    }
}

Status ([ref]$c)    #The variable must be cast to [ref] to be valid
$c

Scopes: Normally a function is executed in a lower scope than the rest of the script. That means variables only exist in their scope and in lower scopes and changes in lower scopes won't reflect to higher scopes. However, you can directly address a variable in another scope using $<scope>:var ($script:s). The downside is you work with the variable itself. The name of the variable inside the function and outside must be the same. (reading the help for scopes is highly recommended)
Here is your code with scopes:

$s=@()    #var needs to have the same name

function Status    #No parameter here
{
    if($script:s.Count -eq "0")
    {
        $script:s = "Fail"    #This will change the type of $s from array to string
    }
    else
    {
        $script:s += "success"    #This will recreate the array with an additional object (string)
    }
}

Status
$s

Upvotes: 3

user8385393
user8385393

Reputation: 104

For a more global function, here is a “get the value of the specified variable” function.

# PowerShell
function getVar($name){
   return (Get-Variable -Name $name).Value
}

The only problem with this is that if you have two variables with different scopes, the function may return the wrong variable, therefore the wrong value.

Here is a function to set a variable. It suffers from the same cons as above though.

# PowerShell
function setVar($name, $value){
    Set-Variable -Name $name -Value $value
}

You can use the -Scope $scope part to help if you need to.

Happy coding!

Upvotes: 1

Theo
Theo

Reputation: 61013

Without fiddling around with scopes or sending variables by reference, why don't you simply have the function return 'Fail' or 'Success'?

BTW The .Count property is of type Int32, so you should not surround the value 0 with quotes, making it a string.

function Get-Status($s) {
    if($s.Count -eq 0) { 'Fail' } else { 'Success' }
}

Now, if you want to overwrite the variable $c with the outcome of whatever the function returns, simply do:

$c = @()
$c = Get-Status $c  # will reset variable $c to the string value of 'Fail'

P.S. I renamed the function so it conforms to the Verb-Noun naming convention in PowerShell

Upvotes: 3

Related Questions