Powershell script looping issue

I have written a script that's purpose is to list all files in a directory from a list of computers that are imported from a .txt file and it will compress the files to a network path. I am not sure if I have written it correctly, hoping you can look at it and let me know if there is a better way.

Script looks like this:

$destination = \\networkpath

$machines = (Get-Content "\\networkpath\machines.txt")

foreach ($machine in $machines) { $sourcefiles = gci "\\$machine\C$\localpath" }

foreach ($sourcefile in $sourcefiles) { 
    Compress-Archive -Path "\\$machine\C$\localpath" -Destinationpath "$Destination\$Sourcefile.zip" -CompresionLevel Optimal -Verbose }

The script works for one machine (the last one in the text file) so it looks like it just isn’t looping, probably because of this double foreach loop I am using. I tried piping the output of $sourcefiles to a compress-archive but this doesn’t zip the files individually.

Any ideas where I went wrong here would be appreciated!

The main issue is that you are looping and overwriting $sourceFiles every time, which is why you only see the last computer If you wanted to get results from all computers into a variable, you can do this:

$sourceFiles = foreach ($machine in $machines) { 
    gci "\\$machine\C$\localpath"
}

Another issue is that you are passing the -Path rather than what was gathered in $sourceFiles, so you could do this:

$destination = "\\networkpath"

$machines = (Get-Content "\\networkpath\machines.txt")

foreach ($machine in $machines) { 
    $sourcefiles = gci "\\$machine\C$\localpath" 

    foreach ($sourcefile in $sourcefiles) { 
        $compParams = @{
            Path            = $sourceFile.FullName
            Destinationpath = "$Destination\$Sourcefile.zip" 
            CompresionLevel = 'Optimal'
            Verbose         = $true
        } 

        Compress-Archive @compParams
    }
}

Another consideration is that you are compressing individual files. If you want to compress multiple files per the documentation, the -Path parameter is a string array [], which means you can do something like this:

$destination = "\\networkpath"

$machines = (Get-Content "\\networkpath\machines.txt")

foreach ($machine in $machines) { 
    $sourcefiles = gci "\\$machine\C$\localpath" 

    $compParams = @{
        Path            = $sourceFiles.FullName
        Destinationpath = "$Destination\$Sourcefile.zip" 
        CompresionLevel = 'Optimal'
        Verbose         = $true
    } 

    Compress-Archive @compParams

}

You many also want to look at Test-Path, Test-Connection and try\catch.

Rob,

Thanks this is great, think it is working and testing it now. One thing I couldn’t use was the string array, it was giving me null or empty on -path. Any idea why this happened? I used your code from above and verified the inputs are correct. Is it possible string arrays don’t accept pwsh variables?

A more likely cause would be that the Get-ChildItem (gci) command did not return any results, so the array is NULL. You should wrap an if:

if ($sourceFiles) {...