10

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?

Aerondight
  • 127
  • 1
  • 1
  • 8

3 Answers3

31

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.

zett42
  • 25,437
  • 3
  • 35
  • 72
Moerwald
  • 10,448
  • 9
  • 43
  • 83
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

Paul
  • 5,524
  • 1
  • 22
  • 39
  • 2
    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 lol – nkasco Mar 31 '16 at 12:26
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
        }
    }
Bobbiz
  • 43
  • 1
  • 4