How do I pass variables with the Invoke-Command cmdlet?
Asked Answered
K

3

11

I have to get Event-Logs from some servers and I don't want to read in the credentials for each server which is found.

I've tried to pass my variables by using the ArgumentList parameter but I doesn't work.

This is my code:

$User = Read-Host -Prompt "Enter Username"
$Password = Read-Host -Prompt "Enter Password" -AsSecureString
$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password)
$UnsecurePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)

Get-ADComputer -Filter "OperatingSystem -Like '*Server*'" | Sort-Object Name |
ForEach-Object{
    if($_.Name -like '*2008*'){
        Invoke-Command -ComputerName $_.Name -ArgumentList $User, $UnsecurePassword -ScriptBlock {  
            net use P: \\Server\dir1\dir2 /persistent:no /user:$User $UnsecurePassword
            Get-EventLog -LogName System -After (Get-Date).AddHours(-12) -EntryType Error, Warning | format-list | 
            out-file P:\EventLog_$env:COMPUTERNAME.log
            net use P: /delete /yes
        }
    }
}

How can I use the variables in the Invoke-Command ScriptBlock?

Kalvn answered 31/3, 2016 at 8:58 Comment(0)
B
9

Either you declare the parameters at the beginning of your scriptblock:

   {  
        param($user,$unsecurepassword)
        net use P: \\Server\dir1\dir2 /persistent:no /user:$User $UnsecurePassword
        Get-EventLog -LogName System -After (Get-Date).AddHours(-12) -EntryType Error, Warning | format-list | 
        out-file P:\EventLog_$env:COMPUTERNAME.log
        net use P: /delete /yes
    }

Or you acces your arguments using the $args variable:

#first passed parameter
$args[0]
#second passed parameter
$args[1]
....

Documentation: MSDN

Brenn answered 31/3, 2016 at 9:15 Comment(1)
Just make sure your variables in param() match up with the ones you pass in through the -ArgumentList. I learned that one the hard way when my $computer kept showing up as my user ID lolMoth
M
33

Alternatively you can use the $Using:scope. See Example 5 under this link.

Example:

$servicesToSearchFor = "*"
Invoke-Command -ComputerName $computer -Credential (Get-Credential) -ScriptBlock { Get-Service $Using:servicesToSearchFor }

With $Using: you don't need the -ArgumentList parameter and the param block in the scriptblock.

Mariejeanne answered 7/2, 2017 at 7:21 Comment(1)
This works WAY better than param and the like! Thank you!Travesty
B
9

Either you declare the parameters at the beginning of your scriptblock:

   {  
        param($user,$unsecurepassword)
        net use P: \\Server\dir1\dir2 /persistent:no /user:$User $UnsecurePassword
        Get-EventLog -LogName System -After (Get-Date).AddHours(-12) -EntryType Error, Warning | format-list | 
        out-file P:\EventLog_$env:COMPUTERNAME.log
        net use P: /delete /yes
    }

Or you acces your arguments using the $args variable:

#first passed parameter
$args[0]
#second passed parameter
$args[1]
....

Documentation: MSDN

Brenn answered 31/3, 2016 at 9:15 Comment(1)
Just make sure your variables in param() match up with the ones you pass in through the -ArgumentList. I learned that one the hard way when my $computer kept showing up as my user ID lolMoth
M
0

When you use ScriptBlock with Invoke-Command, all variables inside ScriptBlock are assumed to be defined in the remote session when it connected, so its not available on your current script block as an usual variable usagee form!

If you need to use a variable filled inside your script on the remote side, you should to use Using scope modifier to identify that local variable in a remote command environment.

See Example 9 on the: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/invoke-command?view=powershell-7.3

change your code like these:

...
    ForEach-Object{
    if($_.Name -like '*2008*'){
        Invoke-Command -ComputerName $_.Name -ArgumentList $User, $UnsecurePassword -ScriptBlock {  
            net use P: \\Server\dir1\dir2 /persistent:no /user:$Using:User $Using:UnsecurePassword
            Get-EventLog -LogName System -After (Get-Date).AddHours(-12) -EntryType Error, Warning | format-list | 
            out-file P:\EventLog_$env:COMPUTERNAME.log
            net use P: /delete /yes
        }
    }
Meliamelic answered 21/12, 2022 at 9:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.