2

I'm trying to do something pretty simple, and conceptually it should work, but it doesn't seem to, and I'm not sure why. I have a file I need to copy to multiple folders on multiple servers. I've been searching and trying different solutions all morning. Here's what I have that I think should work:

$servers = @("\\server1.domain.com","\\server2.domain.com","\\server3.domain.com","\\server4.domain.com")

$dests = @("\E$\path1","\E$\path2","\E$\path3","\E$\path4","\E$\path5")

$file = "C:\Users\user\file.txt"

foreach ($server in $servers)
{net use $server /USER:domain\username password
{foreach ($dest in $dests)
{copy-item -Path $file -Destination $server$dest}}}

The logic is that it will hit the first foreach, get the first servername, do a net use to cache my credentials on the computer, hit the second foreach, get the first path, then copy the file to the first path on the first server, then copy the file to the second path on the first server, etc. etc. At the end of the paths, it will return to the first foreach, move onto the second server, and go through the list of paths on the second server, and on and on.

I've seen similar posts other places where they don't use the second foreach, but I tried that and it didn't work, like this:

foreach ($server in $servers)
{net use $server /USER:domain\username password
{copy-item -Path $file -Destination $server$dest}}}

Thank you for any help anyone can give me on this. I'm sure it's something really simple that I'm just missing.

Colyn1337
  • 2,397
  • 2
  • 23
  • 40
Squirreljester
  • 203
  • 1
  • 2
  • 7
  • Thank you for putting effort into your question. Though, please add the exact error message you encounter in the future. Powershell errors are usually incredibly specific and help with isolating the exact cause of your issue. – Colyn1337 Jun 16 '16 at 20:39
  • Thanks, and I would have included an error if there was one, I just get a string of these: foreach ($path in $paths) {copy-item -Path $file -Destination $server$path} The command completed successfully. – Squirreljester Jun 16 '16 at 21:38
  • You're getting that output from the `net use` command, not your `copy-item` command. When `copy-item` command is successful you'll get an object returned to you. Otherwise it outputs nothing when it fails. – Colyn1337 Jun 16 '16 at 21:57
  • You are not running the copy-item command at all. Your second script is doing `net use xyz` `{powershell-code}` as two separate lines - and the code inside braces `{}` is a script block. An anonymous function. You aren't running it, you're just making the scriptblock and then it exits the pipeline and prints itself `{copy-item -Path $file ... }`. Your first attempt does the same, and it puts the `{foreach` in a scriptblock. Where did you get this unhelpful code style where loop lines begin with braces from? It's not LISP with Reverse-Polish parameters passing a copy item command into `net` ... – TessellatingHeckler Jun 16 '16 at 22:01
  • @Colyn1337 That's kind of where I figured it was coming from. – Squirreljester Jun 17 '16 at 13:37
  • @TessellatingHeckler The weird thing is, I had a second part of that script that copied to a single location on each server, so I didn't need to try and use the second foreach, it was set up the same way, and that worked. And when I try to encapsulate all 3 lines in a single {} it tells me "missing statement body in foreach loop" at the end of the line with the second foreach. And the last time I coded something was Qbasic and batch files back in the day (I'm still pretty new to powershell), where it was easy to nest "for" loops inside each other like I'm trying to do here. – Squirreljester Jun 17 '16 at 13:41
  • @Squirreljester It is possible to nest for loops, but that's not what your code is doing. I spread it out in a couple of ways to try and explain what I was seeing here: http://pastie.org/private/jjdx8bwqwg7pptfxfccl8q – TessellatingHeckler Jun 17 '16 at 20:05

1 Answers1

4

When using network resource file systems, and UNC paths, you should use the filesystem:: PSProvider in Powershell. Here's a couple examples:

Test-Path "filesystem::\\127.0.0.1\c$"
Test-Path "filesystem::\\$env:computername\c$"

Adapting this process to your code should be as simple as:

foreach ($server in $servers){

    net use $server /USER:domain\username password

    foreach ($dest in $dests){

        copy-item -Path $file -Destination "filesystem::$server$dest"

    }#End foreach ($dest in $dests)

}#End foreach ($server in $servers)

Remember, as a powershell professional your code should be as easily read as possible. As with all professional writing, style matters.

Also, you should look into using Get-Credential for using username/passwords so you're not writing them in plain text.

Colyn1337
  • 2,397
  • 2
  • 23
  • 40
  • 1
    I see what I did now, based on this, I was bracketing the foreach line along with the other lines, and I shouldn't do that. I'm also not familiar with that filesystem item, I'll have to read up some help files on it. Thanks! I don't have enough rep points to up-vote this, but I'll come back when I do. – Squirreljester Jun 17 '16 at 13:51
  • If desired, you may be able to accept the answer. To do so simply click on the "checkmark" below the voting arrows of this answer. – Colyn1337 Jun 17 '16 at 20:59