File copy is missed on first server

Welcome Forums General PowerShell Q&A File copy is missed on first server

This topic contains 2 replies, has 2 voices, and was last updated by

 
Participant
6 months, 1 week ago.

  • Author
    Posts
  • #101628

    Participant
    Points: 0
    Rank: Member

    Hi,

    I have a code that zips and copy files from one server to rest of the servers. It reads server names from txt file. If I put only 1 server in txt file all the files are copied correctly. But, if put more then 1 servers in txt file, files are copied on all other servers expect the first one. On first one only 1 or 2 folders are copied.

    I am first ziping-> copy -> unzip. Somehow connection seems to drop. See below code :-

    function global:CopyMedia ()
    {
        $StopWatch = [System.Diagnostics.Stopwatch]::StartNew()
        $StartTime = $StopWatch.Elapsed
        Write-Host "Starting time: $StartTime"
        Write-Host "Reading Config File....."
        $ConfigFile = Split-Path -Path $PSCommandPath 
        $ConfigFile = $ConfigFile + "\" + "Config.ps1"
        ."$ConfigFile"
    
        $RunspaceError = $null
    
        $pool = [RunspaceFactory]::CreateRunspacePool(1, $ParallelServerThreshold)
        $pool.ApartmentState = "MTA"
        $pool.Open()
        $runspaces = @()
    
        $scriptblock = 
        {
            Param (
            [PSCredential] $Cred,
            [string] $UserName,
            [string] $Password,
            [string] $ServerName,
            [string] $Drive,
            [string] $SourceDrive,
            [string] $SourceFolder,
            [string] $File
            )
    
            $UnzipFile = $Drive + "\AHSInstall\" + $File
            $UnZipFolder = $Drive + "\AHSInstall\"
    
            Invoke-Command -ComputerName $ServerName -Credential $cred -ScriptBlock {
                NET USE $using:SourceDrive /u:$using:UserName $using:Password
                Robocopy $using:SourceFolder ($using:Drive + "\AHSInstall\") $using:File /J
                NET USE $using:SourceDrive /D
                
                Expand-Archive -Path $using:UnzipFile -DestinationPath $using:UnZipFolder -Force
                Remove-Item –path $using:UnzipFile
            }
        }
    
        try 
        {
            $ToCopyFile = $ToCopyFolder + '.zip'
            $SourceFolder = "\\" + "$env:computername.$env:userdnsdomain" + "\" + $ToCopyFolder.Replace(":", "$")
            $SourceFolder = (Split-Path -Path $SourceFolder) + "\"
            $SourceDrive = Split-Path -Path $SourceFolder
    
            Write-Host "Compressing folders for copy....."
            Compress-Archive -Path $ToCopyFolder -CompressionLevel NoCompression -DestinationPath $ToCopyFile -Force
            $File = Split-Path -Path $ToCopyFile -Leaf -Resolve
    
            Write-Host "Reading Servers from text file..."
            foreach ($Server in $Servers)
            {
                $ServerName = $Server.Trim()
    
                if($ServerName -eq $env:computername -Or $ServerName -eq ("$env:computername.$env:userdnsdomain")) 
                { 
                    Write-Host "No need to copy as running script from same server: $ServerName" -ForegroundColor Green
                    Continue
                }
    
                If($PreferredDrive.Trim().Length -eq 2)
                 {
                    Write-Host "Checking Freespace on drive $PreferredDrive on server $ServerName....."
                    $Disk = Get-WMIObject Win32_Logicaldisk -ComputerName $ServerName -Credential $Cred -Filter "DeviceID='$PreferredDrive'" | Select-Object DeviceID, Freespace
                    $Drive = $PreferredDrive.Trim()
                    if ($Disk -eq $null) 
                     {
                        Write-Host "`nDrive $Drive does not exists on server $ServerName.....`n" -ForegroundColor Yellow
                        Continue
                     }
                 }
                Else
                 {
                    Write-Host "Finding drive having maximum Freespace on server $ServerName....."
                    $Disk = Get-WMIObject Win32_Logicaldisk -ComputerName $ServerName -Credential $Cred | Select DeviceID, Freespace | sort Freespace -Descending | select -First 1
                    $Drive = $Disk.DeviceID    
                 }
            
                $Freespace = $Disk.Freespace/1024/1024/1024
                if($Freespace -le $MinimumDriveSpaceRequired)
                 { 
                    Write-Host "`nNot enough Freespace on drive $Drive on server $ServerName`n" -ForegroundColor Yellow
                    Continue
                 }
    
                Write-Host "Starting thread for server: $ServerName. Which will do copy, unzip & delete....."
                $runspace = [PowerShell]::Create()
                $null = $runspace.AddScript($scriptblock)
                $null = $runspace.AddArgument($Cred)
                $null = $runspace.AddArgument($WindowsDomainUsername)
                $null = $runspace.AddArgument($WindowsDomainUsernamePassword)
                $null = $runspace.AddArgument($ServerName)
                $null = $runspace.AddArgument($Drive)
                $null = $runspace.AddArgument($SourceDrive)
                $null = $runspace.AddArgument($SourceFolder)
                $null = $runspace.AddArgument($File)
                $runspace.RunspacePool = $pool
                $runspaces += [PSCustomObject]@{ Pipe = $runspace; Status = $runspace.BeginInvoke() }
            }
            
            if($runspaces -ne $null)
             {
                Write-Host "Copy in progress. Please wait....."
                while ($runspaces.Status.IsCompleted -notcontains $true) {}
    
                Write-Host "Checking for any errors in the threads and disposing them....."
                $i=0
                foreach ($runspace in $runspaces) 
                 {
                    $RunspaceError += $runspaces[$i].Pipe.Streams.Error
                    $runspace.Pipe.Dispose()
                    $i++
                 }
                if($RunspaceError -cne $null)
                 {
                    Write-Host "`nFollowing error occured in threads: `n$RunspaceError" -ForegroundColor Red
                 }
                else
                {
                    Write-Host "No erros have been found. All the threads completed successfully....." -ForegroundColor Green
                }   
             }
    
            Write-Host "Deleting zipped copy....."
            Remove-Item –path $ToCopyFile
            
            Write-Host "Media Copy Completed....."
            Write-Host "`nMedia has been copied on below servers:"
            Write-Output $Servers
            Write-Host "`n"
        }
        catch
        {
            Write-Host "Following error occured: `n$($PSItem.ToString())" -ForegroundColor Cyan
        }
        finally
        {
            $pool.Close() 
            $pool.Dispose()
        }
    
       $EndTime = $StopWatch.Elapsed
       Write-Host "End time: $EndTime"
       $TimeTaken = $EndTime - $StartTime
       Write-Host "Time taken to copy media on all servers: $TimeTaken"
       
       Write-Host "***********************************"
       Read-Host -Prompt "Check for any errors in the above script. Hit enter to exit copy media script"
    }
    
  • #101655

    Participant
    Points: 241
    Helping Hand
    Rank: Participant

    Sorry if you expected something else. I don't like to digg into your big chunk of code. You might be better of splitting off your giant function in smaller pieces. If you have "simpler" functions you could stich them together with a controller script. They would be easier to maintain and to debug and probalby even better reusable.

    • #101712

      Participant
      Points: 0
      Rank: Member

      Hi Olaf,

      Thanks for taking time and going through this. I am actually using Runspaces as per post (https://blog.netnerds.net/2016/12/runspaces-simplified/) it has 6 parts so it might look big. Actual working code is just inside scriptblock. I also have one controller (master) script which call all of these scripts.

      $scriptblock = 
          {
              Param (
              [PSCredential] $Cred,
              [string] $UserName,
              [string] $Password,
              [string] $ServerName,
              [string] $Drive,
              [string] $SourceDrive,
              [string] $SourceFolder,
              [string] $File
              )
      
              $UnzipFile = $Drive + "\AHSInstall\" + $File
              $UnZipFolder = $Drive + "\AHSInstall\"
      
              Invoke-Command -ComputerName $ServerName -Credential $cred -ScriptBlock {
                  NET USE $using:SourceDrive /u:$using:UserName $using:Password
                  Robocopy $using:SourceFolder ($using:Drive + "\AHSInstall\") $using:File /J
                  NET USE $using:SourceDrive /D
                  
                  Expand-Archive -Path $using:UnzipFile -DestinationPath $using:UnZipFolder -Force
                  Remove-Item –path $using:UnzipFile
              }
          }
      

The topic ‘File copy is missed on first server’ is closed to new replies.