1

I want to make variables from a particular column in a CSV.

CSV will have the following headers:

FolderName,FolderManager,RoleGroup,ManagerEmail

Under FolderName will be a list of rows with respective folder names such as: Accounts,HR,Projects, etc... (each of these names is a separate row in the FolderName column)

So I would like to create a list of variables to call on in a later stage. They would be something like the following:

$Accounts,
$HR,
$Projects,

I have done a few different scripts based on searching here and google, but unable to produce the desired results. I am hoping someone can lead me in the right direction here to create this script.

5
  • Please share your code and what you have tried so far.
    – Nasir
    Commented Nov 8, 2016 at 1:01
  • 1
    a list of variables ... a what? Variables containing what as values? To use them how? Commented Nov 8, 2016 at 1:02
  • Hey mate, thanks for your reply, and help in other ps script question! My apologies for me being unclear, and/or not explaining correctly! I will try to answer your questions to provide better understanding. 1. I am not sure if I am understanding this q, but this is not a command just a description. 2. Their value would be the name of the folder that is in the FolderName column. 3. I want to use this variable to create a dynamic filename for a csv output for the older than 7 year file name. For example FI_$VariableHere_Results.csv This would then be emailed to ManagerEmail Commented Nov 8, 2016 at 1:13
  • @TessellatingHeckler : stackoverflow.com/questions/13015303/… This is probably the closest thing I am finding to what I am trying to achieve, except I want to get variable name to create from a csv. Does that makes sense? Sorry if I am not! Commented Nov 8, 2016 at 1:22
  • Please edit your question to include your clarification in comments
    – Prisoner
    Commented Nov 8, 2016 at 2:16

3 Answers 3

3

Versions of this question ("dynamic variables" or "variable variables" or "create variables at runtime") come up a lot, and in almost all cases they are not the right answer.

This is often asked by people who don't know a better way to approach their problem, but there is a better way: collections. Arrays, lists, hashtables, etc.

Here's the problem: You want to read a username and print it out. You can't write Hello Alice because you don't know what their name is to put in your code. That's why variables exist:

$name = Read-Host "Enter your name"
Write-Host "Hello $name"

Great, you can write $name in your source code, something which never changes. And it references their name, which does change. But that's OK.

But you're stuck - how can you have two people's names, if all you have is $name? How can you make many variables like $name2, $name3? How can you make $Alice, $Bob?

And you can...

New-Variable -Name (Read-Host "Enter your name") -Value (Read-Host "Enter your name again")

Write-Host "Hello 

wait

What do you put there to write their name? You're straight back to the original problem that variables were meant to solve. You had a fixed thing to put in your source code, which allowed you to work with a changing value.

and now you have a varying thing that you can't use in your source code because you don't know what it is again.

It's worthless.

And the fix is that one variable with a fixed name can reference multiple values in a collection.

Arrays (Get-Help about_Arrays):

$names = @()

do {
    $name = Read-Host "Enter your name"
    if ($name -ne '')
    {
        $names += $name
    }
} while ($name -ne '')

# $names is now a list, as many items long as it needs to be. And you still 
# work with it by one name.

foreach ($name in $names) 
{ 
    Write-Host "Hello $name" 
}

# or

$names.Count

or

$names | foreach { $_ }

And more collections, like

Hashtables (Get-Help about_Hash_Tables): key -> value pairs. Let's pair each file in a folder with its size:

$FileSizes = @{}   # empty hashtable. (aka Dictionary)

Get-ChildItem *.txt | ForEach {

    $FileSizes[$_.BaseName] = $_.Length

}

# It doesn't matter how many files there are, the code is just one block 

# $FileSizes now looks like
@{
    'readme' = 1024;
    'test' = 20;
    'WarAndPeace' = 1048576;
}

# You can list them with

$FileSizes.Keys

and

foreach ($file in $FileSizes.Keys)
{
    $size = $FileSizes[$file]

    Write-Host "$file has size $size"
}

No need for a dynamic variable for each file, or each filename. One fixed name, a variable which works for any number of values. All you need to do is "add however many there are" and "process however many there are" without explicitly caring how many there are.

And you never need to ask "now I've created variable names for all my things ... how do I find them?" because you find these values in the collection you put them in. By listing all of them, by searching from the start until you find one, by filtering them, by using -match and -in and -contains.


And yes, New-Variable and Get-Variable have their uses, and if you know about collections and want to use them, maybe you do have a use for them.

But I submit that a lot of people on StackOverflow ask this question solely because they don't yet know about collections.

Dynamic variables in Powershell

Incrementing a Dynamic Variable in Powershell

Dynamic variable and value assignment in powershell

Dynamically use variable in PowerShell

How to create and populate an array in Powershell based on a dynamic variable?

And many more, in Python too:

https://stackoverflow.com/a/5036775/478656

How can you dynamically create variables via a while loop?

1
  • 1
    Thanks mate, I am going to research further based on this information arrays and hashtables. I appreciate your honest and insightful feedback into really dealing with the question. I also appreciate the examples and the language you used to convey your points, they were very very helpful! Thanks so much! Commented Nov 8, 2016 at 3:07
0

Basically you want to create folders based on the values you are getting from CSV File. (FileName has headers such as FolderName, FolderManager, RoleGroup, ManagerEmail)

$File=Import-csv "FileName"

$Path="C:\Sample"

 foreach ($item in $File){
$FolderName=$item.FolderName
$NewPath=$Path+"\$FolderName"
if(!(Test-Path $NewPath))
{
New-Item $NewPath -ItemType Directory
}
}

Hope this HElps.

1
  • Hey mate, Thanks for your help here, but no I was not wanting to create folders as they already existed. I understand my wording and way of asking the question was most likely the problem here rather than your answer. Thanks for your time however! Commented Nov 8, 2016 at 3:09
0

In PowerShell, you can import a CSV file and get back custom objects. Below code snippet shows how to import a CSV to generate objects from it and then dot reference the properties on each object in a pipeline to create the new variables (your specific use case here).

PS>cat .\dummy.csv                                                                                        
"foldername","FolderManager","RoleGroup"                                                                  
"Accounts","UserA","ManagerA"                                                                             
"HR","UserB","ManagerB"                                                                                   

PS>$objectsFromCSV = Import-CSV -Path .\dummy.csv                                                         

PS>$objectsFromCSV | Foreach-Object -Process {New-Variable -Name $PSItem.FolderName }                     

PS>Get-Variable -name Accounts                                                                            

Name                           Value                                                                      
----                           -----                                                                      
Accounts                                                                                                                                              
PS>Get-Variable -name HR                                                                                  

Name                           Value                                                                      
----                           -----                                                                      
HR    

`

Not the answer you're looking for? Browse other questions tagged or ask your own question.