A question about variable declaration

Hi guys,
The script that i’m talking about is working perfectly and doing all the things that i intend to.

The thing is, that i figured it out only after long testing, untill i got the right syntax
here is the script:

cls

#get the csv file
$filepath = import-csv "C:\users.csv" 

#set the variable for the uers
$newusers = $filepath


#set Passwords for new users 
$securepassword = "BlahBlah"


foreach ($user in $newusers) {

#get user information

    $User_Creation_Settings = @{

    Name                  = "$($user.'First Name') $($user.Lastname)"
    GivenName             = $user.'First Name'
    Surname               = $user.Lastname
    UserPrincipalName     = $user.UserPrincipalName
    SamAccountName        = $user.SamAccountName
    Path                  = $user.Path
    ScriptPath            = $user.ScriptPath
    ChangePasswordAtLogon = $false
    Department            = $user.Department
    DisplayName           = $user.DisplayName
    Description           = $user.Description
    Title                 = $user.'Job Title'
    AccountPassword       = ConvertTo-SecureString $securepassword -AsPlainText -Force
    Enabled               = $true

}

New-ADUser @User_Creation_Settings



#Get Groups information
$group1 = $user.Group1
$group2 = $user.Group2
$group3 = $user.Group3
$group4 = $user.Group4


#Add the users in to Groups

 Add-ADPrincipalGroupMembership -Identity $user.SamAccountName -MemberOf $user.group1
 Add-ADPrincipalGroupMembership -Identity $user.SamAccountName -MemberOf $user.group2
 add-ADPrincipalGroupMembership -Identity $user.SamAccountName -MemberOf $user.group3
 Add-ADPrincipalGroupMembership -Identity $user.SamAccountName -MemberOf $user.group4


 
Write-Host "`n"
Write-Host "The account for $($user.'First Name') $($user.Lastname) created in $($user.Path) successfully "


}
pause

I want to understand if i understood, why it actually worked in that way,
in that case:

 Name    = "$($user.'First Name') $($user.Lastname)"

is that mean that this string $($user.‘First Name’) is actually one variable?
and if so, why do i need to use the “$” twice? inside the () and outside the ().

I understand that it similar to this case

$(Get-Process MicrosoftEdge).Kill()

but in that case i use the “$” only once.

Thanks a lot for your help :slight_smile:

All this bit, see blow, you dont need

#get the csv file
$filepath = import-csv "C:\users.csv" 

#set the variable for the uers
$newusers = $filepath

Replace it with

foreach ($user in ($newusers = Import-Csv "C:\users.csv" ))

Also you dont need the $() twice

foreach ($user in ($newusers = Import-Csv "C:\users.csv")) 
{ 
    $name = $($user.Firstname + ' ' + $user.lastname)
}

Will return “Iain Barnetson”

Hi Iain,
Thanks alot for your information,

I didn’t knew about this magic trick :

 $($user.Firstname + ’ ’ + $user.lastname)

can you explain please in which cases i can use this trick and why it’s better than mine?

also i didn’t knew that i can do this


foreach ($user in ($newusers = Import-Csv “C:\users.csv” ))

Both “tricks” are equivalent. You can also do this:

name = $user.Firstname + ' ' + $user.lastname

So, about $( ) notation. Basically, it inserts any expression into a string. You don’t need it in this case because you’re assigning a value to a hashtable key. If you were attempting to insert it into a larger string, then yes, you need it.

You can insert the results from cmdlets, objects, basically anything that can be converted into string form, into a string in this manner. Try:

$String = "The Date is: $(Get-Date)"
$String

Neat, right? These expressions can be as complex as you like, but I’d recommend keeping them fairly simple. The most common use for these is when a variable contains an object that you have to access the property of:

$String = "The property value is: $($Object.Property)"

This here is necessary, because while PowerShell will happily insert variable values into double-quoted strings (e.g., you can do “The variable value is: $Variable” without issues) it runs into difficulty figuring out the boundaries of what you want. It assumes by default that a following dot is part of the string, meant as a regular period, part of a sentence or whatnot, instead of assuming you want to access the object property. So you use the expression syntax, enclosing it in $( )

In your original example, you have an interesting quirk:

Name                  = "$($user.'First Name') $($user.Lastname)"

Note how the property of $user.‘First Name’ is actually in quotes. That’s because the property has a space in it. Generally speaking, I’d avoid this where possible; it just clutters up scripts, but if that’s how it was defined in the input file you more or less have to deal with it, heh. But apart from that, if you were to simply do:

Name = "$User.'First Name' $User.Lastname"

You would actually get whatever is the closest string approximation of $User is (which is probably a table of values), followed by the string ".‘First Name’ ", followed by the same table of values again, followed by the string “.Lastname”.

That’s why you need the extra $( ) in this case. It indicates to PS that everything in the parentheses is an expression. The $ is required because without it you wouldn’t be able to use regular parentheses in your strings, and that would be needlessly complicated for common use. :slight_smile:

Thanks alot Joel !

actually this is a bit confusing, because you have the Variable “name” two times there

Name = "$User.First Name $User.Lastname"

I did make a small mistake, see above, forgot a couple quote marks, but anyway:

The first would be a part of the hashtable in context, so it’d be the $hashtable[‘Name’] entry, or end up getting splatted to the -Name parameter in the cmdlet it gets passed to.

The second isn’t a variable at all. Variables in PS are always prefixed with the $ dollar-sign symbol. That there is just part of the string – it’s mainly there to illustrate that that is how PS would see the string, more or less, if you don’t use the $( ) expression syntax when accessing properties of an object. :slight_smile:

Thanks alot for the explanation, i really appreciate it.