Storing PowerShell Variables in External files

On our PowerShell community forums, we have recently received questions asking if it is possible to store PowerShell variables in external files, and if so, how is it done. It is indeed possible to store variables in external files for PowerShell to use. These external variables can be stored in a variety of file types. Storing them in a PowerShell file is one of the easiest because you can just dot source these files.

We will cover the following methods to store variables:

  • Script Files
  • Text Files
  • JSON Files
  • XML Files

The examples shown in this post are pretty simple, but that doesn’t mean that it isn’t possible to store fairly complex variables in external files. If you want to experiment with storing external variables you can download the sample files for this post here.

Script Files

Dot sourcing may be the easiest way to store external variables—but it isn’t always the safest. When a file is dot sourced we are telling PowerShell to execute that script. If there is any malicious code in the file, then that code will also run.

In addtion to dot sourcing, you will also need to ensure that the external variables PowerShell script is signed and that Remote Execution is enabled on your machine.

Dot sourcing can be helpful if we need to get information about something dynamically. For the other options discussed in this post, the data stored in the file types will have to be manually changed.

1
2
3
4
# Here we dot source the External variables PowerShell File
. "C:\Test\BlogPosts\ExternalVariables.ps1"
 
Write-Host $External_Variable1 $External_Variable2

Here is what is in the ExternalVariables.ps1 file:

#Declaration of External variables
$External_Variable1 = ‘Sapien’
$External_Variable2 = ‘Technologies’

Text Files

External variables can also be stored in a number of text files and formats, such as plain text in a general .txt file using the Get-Content cmdlet. When we import variables this way, we aren’t running any code, so it’s not a problem if you don’t constantly monitor the files to get information.

The following three pictures are examples of different ways of storing information in a simple text file:

1
2
3
4
5
6
7
8
9
10
11
12
13
$ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path
$ScriptDir += "\ExternalVariables.txt"
 
# Use get content to get all of the lines that are in the txt files
 
$External_Variables = Get-Content -Path $ScriptDir
 
#The Information from the ExternalVariables comes in as an array 
#So to print all of the strings in $program we use a foreach loop
foreach ($string in $External_Variables)
{
	Write-Host $string	
}

Here is what is in the ExternalVariables.txt file:

“PowerShell Studio”
“PrimalScript”
“Version Recall”

Just like an array, we can store hash tables in text files. To get our hash table from a text file, we will have to pipe the output of the Get-Content to the ConvertFrom-StringData cmdlet to convert the output into a hash table.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path
$ScriptDir += "\ExternalVariablesHashTable.txt"
# Getting the contents of the External Variable text file
# This file is store in plan text and is not in any special format
 
# We use the "raw" parameter here in Get-Content so that when we get the contents
# of the file so that our hashtable is not converted to an object
$program = Get-Content -raw -Path $ScriptDir | ConvertFrom-StringData
 
write-host "`nType of the variable `$program`n"
$program.GetType()
 
write-host "`nPrinting `$program" 
$program

Here is what is in ExternalVariablesHashTable.txt:

Company=Sapien Technologies
Product=PowerShell Studio

Storing information in a text file like this is a convenient way to keep information in a human-readable format. Text files also come with the benefit of not being executable, so if there happens to be malicious code stored in a file you don’t regularly manage it won’t be executed.

JSON File

It is also possible to store external variables in a JSON format. The only caveat being that we will need to once again pipe the output of Get-Content to another cmdlet; however this time it’s ConvertFrom-Json rather than ConvertFrom-StringData. For those unfamiliar with JSON or need to brush up on the format, please visit www.JSON.org.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path
$ScriptDir += "\jsonfile.json"
#Getting information from the json file
#The we pass the output from Get-Content to ConvertFrom-Json Cmdlet
$JsonObject = Get-Content $ScriptDir | ConvertFrom-Json
 
#Right now we have an array which means that we have to index
#an element to use it
$JsonObject.Users[0]
 
#When indexed we can call the attributes of the elements
Write-Host "Attributes individually printed"
$JsonObject.Users[0].Name
$JsonObject.Users[0].Age
$JsonObject.Users[0].City
$JsonObject.Users[0].Country
$JsonObject.Users[0].UserId

Here is what is in the JSON File:

{
“Users”: [{
Name:”John Smith”,
Age:”35″,
City:”San Francisco”,
Country:”USA”,
UserId:”52917″
},
{
Name:”Jane Wellington”,
Age:”28″,
City:”Seattle”,
Country:”USA”,
UserId:”25589″
},
{
Name:”Samantha Scott”,
Age:”33″,
City:”Los Angeles”,
Country:”USA”,
UserId:”11564″
}
]
}

XML File

If we store our variables in an XML format, we can add comments to the variable file if necessary. The only two file formats that we will talk about in this post that allows for comments are XML or PS1. JSON and normal TXT files do not allow for comments. For a concise overview of the XML format, visit w3schools.com/xml.

1
2
3
4
5
6
7
8
9
$ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path
$ScriptDir += "\XMLFile.xml"
#Read in all of the information from our variables XML file
#We will need to cast the variable as [XML] when we store all of the file information in it
 
[xml]$XML_Variable = Get-Content -Path $ScriptDir
 
#Referencing the Food Object array stored within the Breakfast Object
$XML_Variable.Breakfast_menu.Food[0] | Format-List

Here is what is in the XML file:


Belgian Waffles
$5.95
Two of our famous Belgian Waffles with plenty of real maple syrup
650

Strawberry Belgian Waffles
$7.95
Light Belgian waffles covered with strawberries and whipped cream
900

Berry-Berry Belgian Waffles
$8.95
Belgian waffles covered with assorted fresh berries and whipped cream
900

When choosing between XML and JSON storage formats, it comes down to which one is more familiar. Since the main difference between them is that XML allows comments, it is just a matter of preference. All of these options are viable ways to store information in external files to either be read by another program or used by the same program at a later time. How complex, whether it is dynamic or not, and how much information needs to be stored will dictate the format to use.

Exporting to Files

Just like importing information with PowerShell, it is also possible to export information and objects to an external file from the program we are using. PowerShell Studio 2018 comes with snippets that make exporting information much easier—simply pass the path of the external file and the object to the corresponding export function and the snippet will take care of everything else. We will cover Exporting to Files using Snippets in a future blog post.