3

I have an array of variables and was wondering if its possible to get/return the name of each variable from the array (not the value of the variable)?

For example, something like:

$varArray = @($var1, $var2, $var3)

ForEach ($v in $varArray)
{
   *return the name of the variable here, not the value*
}

So I'd have something like this:

var1

var2

var3

NOTE: I do plan on getting the "values" of each variable at a different point in the script, so just need the variable names here.

Thanks in advance!

1

5 Answers 5

6

I'd switch from using an array to using a hash table. Make the hash table keys the variable names:

$VarHT = @{Var1=$var1;Var2=$var2;Var3=$var3)

ForEach ($v in $varHT.Keys)
{
   *return the name of the variable here, not the value*
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you, this works. Now what if the number/names of variables in $varArray are unknown? Meaning, $varArray contains a list of variables being passed in from another script, and I just need to loop thru $varArray to get the name of each variable. How would I do that?
I don't think you can. when the invocation is made the variables are expanded to their values, and the values are what gets passed. The name of the variable that originally held the value is not part of the information passed to the called script or function.
Darn, was hoping that would be feasible. Anyway, thanks for your input, mjolinor. What you and Hiten004 both mentioned gave me some ideas on how to approach my problem in a different way. Thanks, -Keith
1

This is not possible as @mjolinor explained, but (if you can access the sender script) you could shift the array content one layer higher by using "variable names" instead of the variables (s.th. like the concept of the array of pointers in good old C):

$varArray = @('$var1', '$var2', '$var3')

Accessing the names is then trivial:

ForEach ($v in $varArray)
{
    Write-Output "Var name: $v"
}

But you pay the price for it, when you want to use the variable values. Instead of:

$anotherVar = $v

you have to use:

$anotherVar = (Get-Variable $v.substring(1)).Value

More convenient would be to wrap that ugly expression in a function:

function Expand ($var)
{
    (Get-Variable $var.substring(1)).Value
}

and then:

$anotherVar = Expand $v

Comments

1

You can use something like this at the start of your script. I've had to do this in the past with Ansible.

<code>
$requiredParameters = @(
    @{"parameterName" = "vmname";},
    @{"parameterName" = "domain";}
)

$converted_params = @{}
$args.psobject.properties | ForEach { $converted_params[$_.Name] = $_.Value }

ForEach ($obj in $requiredParameters)
{
    If ($converted_params.ContainsKey($obj.parameterName))
    {
        New-Variable -Name $obj.parameterName `
        -Value $converted_params.$($obj.parameterName)
    }
    Else
    {
        If ($obj.ContainsKey("defaultValue"))
        {
            New-Variable -Name $obj.parameterName -Value $obj.defaultValue
        }
        Else
        {
            throw ("missing required argument: " + $obj.parameterName )
        }
    }
}
</code>

2 Comments

You should really add some explanation as to why this code should work - you can also add comments in the code itself - in its current form, it does not provide any explanation which can help the rest of the community to understand what you did to solve/answer the question.
It would seem, that this solution is centered around parameters specifically, not around variables in general.
1

I was looking for a solution for this problem and solved it by placing the variables in a psObject. you can create psobjects with the createParaObject function and place these in an array. After that, you will be able to get the variable name and value from the object.

function createParaObject {
    Param (
        $name,
        $value
    )

    $props = @{
    Name = $name
    Value = $value
    }
    $object = new-object psobject -Property $props
    return $object
}

$a = createParaObject -name 'a' -value 1
$b = createParaObject -name 'b' -value 2
$c = createParaObject -name 'c' -value $NULL
$d = createParaObject -name 'd' -value 4

$array = $($a,$b,$c,$d)

foreach($var in $array) {
    $name = $var.Name
    $val = $var.Value
    write-host "$name : $val"
}

2 Comments

It's not a variable
It will be a shame when you can't pass it to a function that requires an int32 for example.
0
for ($i=1; $i -le 5; $i++)
{
    if ((Get-Variable -Name "var$i" -ValueOnly -ErrorAction SilentlyContinue) -eq $null){New-Variable -Name "var$i" -Value $i}
    (Get-Variable -Name "var$i").Name
    Get-Variable -Name "var$i" -ValueOnly
}
'============'
"$var1`n$var2`n$var3`n$var4`n$var5"
for ($i=1; $i -le 5; $i++)
{
    Remove-Variable "var$i" -ErrorAction SilentlyContinue;
}
'==== Already removed ==='
"$var1`n$var2`n$var3`n$var4`n$var5`n"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.