SOLVED

Inserting variable in command string

Contributor

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! 

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]

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!

best response confirmed by charlie4872 (Contributor)
Solution

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:

@Joshua King No worries about being long winded because A) it works! and B) I learned something from the explanation and will be useful in the future. Thanks so much for taking time in explaining everything and making my task so much easier!!

 

 

www.000webhost.com