2

Is there a way to get only the locally declared variables in a powershell script?

In this snippit, I would want it to return only myVar1, myVar2, anotherVar:

$myVar1 = "myVar1"
$myVar2 = "myVar2"
$anotherVar = "anotherVar"
Get-Variable -Scope Script 

But it instead returns a ton of other local script variables.

The problem I'm trying to solve, and maybe you can suggest another way, is that I have many Powershell scripts that have a bunch of misc variable constants declared at the top.

I want to export them all to disk (xml) for import later.

So to call Get-Variable bla* | Export-Clixml vars.xml, I need to know all of the variable names.

So is there a way I can like do

$allVars = {
    $myVar1 = "alex"
    $myVar2 = "iscool"
    $anotherVar = "thisisanotherVar"
}
Get-Variable allVars | Export-Clixml "C:\TEMP\AllVars.xml"

And then later Import-Clixml .\AllVars.xml | %{ Set-Variable $_.Name $_.Value } ?

So that the rest of the script could still use $myVar1 etc without major changes to what is already written?

2
  • ls variable: should be ok? Commented Dec 12, 2016 at 19:23
  • It gets all sorts of other variables I wouldn't want to load, such a PWD for example. Commented Dec 12, 2016 at 19:31

1 Answer 1

3

The issue is there are more variables that are accessible in that scope beyond the ones you already declared. One thing you could do is get the list of variables before you declare yours. Get another copy of all the variables and compare the list to just get yours.

$before = Get-Variable -Scope Local
$r = "Stuff"
$after =  Get-Variable -Scope Local

# Get the differences
Compare-Object -Reference $current -Difference $more -Property Name -PassThru

The above should spit out names and simple values for your variables. If need be you should be able to easily send that down the pipe to Export-CliXML. If your variables are complicated you might need to change the -depth for more complicated objects.

Caveat: If you are changing some default variable values the above code currently would omit them since it is just looking for new names.

Also not sure if you can import them exactly in the same means as they were exported. This is largely dependent on your data types. For simple variables this would be just fine

I need to know all of the variable names.

The only other way that I am aware of (I never really considered this) would be to change all of the variable to have a prefix like my_ so then you could just have one line for export.

Get-Variable my_* | Export-Clixml vars.xml
Sign up to request clarification or add additional context in comments.

9 Comments

If the scripts aren't calling each other, you don't need to record $before, you can just compare -Scope 0 to -Scope 1. Of course that has its own problem in that it will catch modified variables too (even if they were not declared by any user script).
That's what I figured I would have to do. Is there a better method than the XML-Variable approach to store a bunch of constants for reuse? I have one script called RefreshEnvironment for example, and we have Test1 and Test2 servers, where the "function" of the script is identical, but Test1 has different server names and same with Test2
@AlexKwitny XML is a better approach for complex variables and objects. It is more type aware. Else you could using CSV files but that would only be good for string and numbers.
@AlexKwitny: I happened to have need for a solution to this in my scripts. I settled on using one global variable (a hash table) exported from a module to contain the rest of the (considerable) configuration data. This hash contained only simple values and other nested hashes. Of course, I still use parameters to my cmdlets whenever that is more appropriate than the reference context, but using constantly repeated parameters for everything got old fast, even with splatting.
@AlexKwitny: Almost. If your keys or values need escaping then dumping a string to a hash is much more painful -- I have no idea why there is no built-in cmdlet for it, since it means PowerShell lacks a simple serialization format (CliXml works as long as you don't want to peek inside, ConvertTo/ConvertFrom-Json do not roundtrip). I wrote such a function anyway for debugging purposes and you can find attempts online as well, but my scenario was originally only for easily importing these values from a file and changing them from the command line, not saving them back.
|

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.