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!

Keith
  • 1,959
  • 10
  • 35
  • 46
  • using multidimensional-arrays to store the value ans the variable name. use this example : http://stackoverflow.com/questions/9397137/powershell-multidimensional-arrays – Hiten004 Oct 28 '13 at 21:33

5 Answers5

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*
}
mjolinor
  • 66,130
  • 7
  • 114
  • 135
  • 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? – Keith Oct 28 '13 at 21:55
  • 2
    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. – mjolinor Oct 28 '13 at 22:00
  • 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 – Keith Oct 28 '13 at 22:08
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
Community
  • 1
  • 1
Mehrdad Mirreza
  • 984
  • 12
  • 20
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
    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. – ishmaelMakitla Aug 04 '16 at 16:26
  • It would seem, that this solution is centered around parameters specifically, not around variables in general. – Hilarion Nov 19 '18 at 10:20
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"
}
MLCroix
  • 11
  • 2
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"
Garric
  • 591
  • 3
  • 10