0

Trying to get these two to work but keep getting errors. Basically looking to pickup all files from C:\Temp\Test with .txt extension and copy it to Server1 and Server2 D:\Temp\Test.

Doesn't work...

$servers = "Server1","Server2"
$SourcePath = (Get-ChildItem C:\Temp\Test *.txt).Name
$servers | ForEach {
Invoke-Command $servers -ScriptBlock {
$CompName = (Get-WmiObject -Class Win32_ComputerSystem).Name
$DestPath = "\\$CompName\D$\Temp\Test"
Copy-Item $SourcePath -Destination $DestPath -Recurse
}
}
MMT
  • 1
  • 1
  • 2
  • Hint: check output from `$servers | ForEach { "a server = $_"; $servers }`. Moreover, if your script throws an exception, please [edit] your script to include the exception, with both the message and the stack trace. "*Doesn't work...*" enunciation does not suffice! – JosefZ Nov 29 '16 at 21:32
  • Possible duplicate of [How can I pass a local variable to a script block executed on a remote machine with Invoke-Command?](http://stackoverflow.com/questions/35492437/how-can-i-pass-a-local-variable-to-a-script-block-executed-on-a-remote-machine-w) – user4003407 Nov 29 '16 at 23:15

1 Answers1

2

This is a common mistake actually. When you use Invoke-Command to invoke your scriptblock on the remote server it creates a new instance of PowerShell on that remote computer. That new instance of PowerShell has no idea what the $SourcePath variable is, since it was never set in that new instance. To work around this give your scriptblock a parameter, and then supply the value of $SourcePath when you invoke to scriptblock. It can be done like this:

$servers = "Server1","Server2"
$SourcePath = (Get-ChildItem C:\Temp\Test *.txt).Name
$servers | ForEach {
    Invoke-Command $servers -ScriptBlock {
        Param($SourcePath)
        $CompName = (Get-WmiObject -Class Win32_ComputerSystem).Name
        $DestPath = "\\$CompName\D$\Temp\Test"
        Copy-Item $SourcePath -Destination $DestPath -Recurse
    } -ArgumentList $SourcePath
}
TheMadTechnician
  • 34,906
  • 3
  • 42
  • 56