Forum Discussion

charlie4872's avatar
charlie4872
Copper Contributor
Mar 06, 2020
Solved

Inserting variable in command string

I am trying to make a small script to get user, computer and SID info for changing a registry value. Below is my script...

 

$computer = read-host -prompt 'Enter Computername'
$user = read-host -prompt 'Enter Username'
$sid = Get-Aduser -identity $user | select-object SID
invoke-command -computer win7test01 -scriptblock {(New-PSDrive -psprovider registry -Name HKU -Root HKEY_USERS),(Set-ItemProperty "hku:\$sid\SOFTWARE\Microsoft\Office\16.0\Lync\printtest@contoso.com" -Name 

 

What I am trying to do is insert the SID gathered by the $sid portion which returns the correct value after running the command by itself and the typing $sid. What I am having an issue with is inserting that variable into the Set-ItemProperty portion as you can see from the line above. It fails when I run it and I am wondering if there is any way this can be done or do I have to manually modify the code and enter the SID before running the script. I am fairly new to Powershell so just wondering what the best way to accomplish this would be. Many thanks in advance! 

  • Ahh, what you'll find is that your $sid variable doesn't actually contain what you're expecting it to contain.

     

    The way it's being used you're wanting it to be a string of just the SID, but it's currently an object with one property. (Seems like a nitpicky distinction but id does have implications in situations like this.)

     

    If you call $sid, what you'll see output atm is:

     

    SID
    ---
    S-1-5-21-7375663-6890924511-1272660413-2944159

    but what you actually want is just

    S-1-5-21-7375663-6890924511-1272660413-2944159

     

    All of that is to say, either change this line:

    $sid = Get-Aduser -identity $user | select-object SID

     

    To

    $sid = Get-Aduser -identity $user | select-object -ExpandProperty SID

    The -ExpandProperty option "expands" the select property such that it's the new "Object" being returned, rather than selecting child properties of the parent object. Basically it means you just get back a string...

     

    And alternative to that approach is:

    $sid = (Get-Aduser -identity $user).SID

    Which pulls that property out and has much the same effect as the expandproperty.

     

    One final option is to reference that property directly inside the Invoke-Command scriptblock:

    $($Using:sid.SID)

     

    This method actually opens up a few posibilities. For example, if you got rid of the select-object and did something like

    $UserObject = Get-Aduser -identity $user

     

    Then you could reference the sid when needed:

    $($Using:UserObject.SID)

     

    But elsewhere you could also use the other properties:

    $($Using:UserObject.SamAccountName)

     

    -----

     

    Sorry that was a touch long winded, just wanted to fully playout the problem and potential solutions :smile:

4 Replies

  • Hey charlie4872, there's a few options available which are listed in the about_Remote_Variables help topic.

     

    To summarize, if you're using a recent PowerShell version (3 +) you can use the "Using" scope, which tells PowerShell to pull your local variable through to the remote session:

     

    invoke-command -computer win7test01 -scriptblock {(New-PSDrive -psprovider registry -Name HKU -Root HKEY_USERS),(Set-ItemProperty "hku:\$($Using:sid)\SOFTWARE\Microsoft\Office\16.0\Lync\printtest@contoso.com" -Name ...)}

     

    Note that I made the variable there $($Using:sid), with it wrapped in $(), to make sure it expands properly. This is the same technique you'd use if you needed to pull out a property from a variable in the middle of a string.

     

    The second option is to use the -ArgumentList parameter on Invoke-Command. The example shows putting a pram block in your script block:

     

    $ps = "*PowerShell*"
    Invoke-Command -ComputerName S1 -ScriptBlock {
      param($log)
      Get-WinEvent -LogName $log
    } -ArgumentList $ps

     

    But I think it's also possible to reference the arguments via an $Args variable, e.g. $Args[0]

    • charlie4872's avatar
      charlie4872
      Copper Contributor

      Thanks for the reply Joshua King I used the first suggestion and it does resolve the SID but is giving me the error below....

       

      "Cannot find path 'HKU:\@{SID=correct sid string does show here}\SOFTWARE\Microsoft\Office\16.0\Lync\printtest@contoso.com" -Name "UpgradeNotificationLearnMoreSeen" -Value 1)}

       

      I dont know if it is because or the @ symbol and curly brackets at the beginning and end but it doesn't appear is is reading it correctly. Any ideas on what is happening? Thanks again for your help!

      • Joshua King's avatar
        Joshua King
        MVP

        Ahh, what you'll find is that your $sid variable doesn't actually contain what you're expecting it to contain.

         

        The way it's being used you're wanting it to be a string of just the SID, but it's currently an object with one property. (Seems like a nitpicky distinction but id does have implications in situations like this.)

         

        If you call $sid, what you'll see output atm is:

         

        SID
        ---
        S-1-5-21-7375663-6890924511-1272660413-2944159

        but what you actually want is just

        S-1-5-21-7375663-6890924511-1272660413-2944159

         

        All of that is to say, either change this line:

        $sid = Get-Aduser -identity $user | select-object SID

         

        To

        $sid = Get-Aduser -identity $user | select-object -ExpandProperty SID

        The -ExpandProperty option "expands" the select property such that it's the new "Object" being returned, rather than selecting child properties of the parent object. Basically it means you just get back a string...

         

        And alternative to that approach is:

        $sid = (Get-Aduser -identity $user).SID

        Which pulls that property out and has much the same effect as the expandproperty.

         

        One final option is to reference that property directly inside the Invoke-Command scriptblock:

        $($Using:sid.SID)

         

        This method actually opens up a few posibilities. For example, if you got rid of the select-object and did something like

        $UserObject = Get-Aduser -identity $user

         

        Then you could reference the sid when needed:

        $($Using:UserObject.SID)

         

        But elsewhere you could also use the other properties:

        $($Using:UserObject.SamAccountName)

         

        -----

         

        Sorry that was a touch long winded, just wanted to fully playout the problem and potential solutions :smile:

Resources