A question about variable declaration

This topic contains 6 replies, has 3 voices, and was last updated by  Lev Leiderman 3 weeks, 1 day ago.

  • Author
  • #97245

    Lev Leiderman

    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:

    #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 "

    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 🙂

  • #97248

    iain Barnetson

    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"

    • #97254

      Lev Leiderman

      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" ))
  • #97310

    Joel Sallow

    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)"

    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. 🙂

    • #97331

      Lev Leiderman

      Thanks alot Joel !

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

      Name = "$User.First Name $User.Lastname"
  • #97350

    Joel Sallow

    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. 🙂

    • #97352

      Lev Leiderman

      Thanks alot for the explanation, i really appreciate it.

You must be logged in to reply to this topic.