Computer >> 컴퓨터 >  >> 시스템 >> Windows Server

BITS와 PowerShell로 불안정한 네트워크에서 대용량 파일 안전하게 복사하는 방법

로컬 및 글로벌 네트워크 환경에서 파일은 일반적으로 SMB, FTP 또는 HTTP 프로토콜을 통해 전송됩니다. 그러나 이러한 프로토콜들은 대용량 파일 전송 중 연결이 끊겼을 때 이어받기(재개) 기능이 취약하다는 공통적인 문제를 가지고 있으며, 네트워크가 느리거나 불안정할 경우 이 문제는 더욱 심각해집니다.

또한 위 프로토콜로 파일을 복사하면 서버와 수신자 간의 가용 대역폭을 모두 사용하기 때문에 네트워크 성능 저하 및 다른 애플리케이션의 동작에 부정적인 영향을 줄 수 있습니다. 네트워크 장비에서 QoS 정책을 세부적으로 설정하는 것이 항상 가능한 것도 아닙니다.

이 글에서는 BITS 프로토콜과 PowerShell을 활용하여 느리거나 불안정한 네트워크 환경에서 대용량 파일을 효율적으로 복사하는 방법을 살펴보겠습니다.

BITS 프로토콜이란?

BITS(Background Intelligent Transfer Service)는 Windows 시스템 간에 파일을 전송하기 위해 제공되는 Windows 서비스입니다. 다운로드와 업로드 모두 지원하며, Windows 자동 업데이트(WUS 서버에서 업데이트를 받는 경우 포함), SCCM 배포 지점에서 프로그램을 받을 때 등 다양한 상황에서 활용됩니다.

BITS 프로토콜의 주요 장점

  • 대역폭 자동 제어: BITS는 통신 채널의 가용 대역폭을 지능적으로 관리하여 다른 네트워크 애플리케이션과 서비스에 영향을 주지 않습니다. 할당되지 않은 여유 대역폭만 사용하며, 전송 중 다른 애플리케이션이 네트워크 사용량을 늘리면 BITS 클라이언트가 자동으로 전송 속도를 낮춥니다.
  • 백그라운드 전송: 파일 다운로드가 사용자에게 투명하게 백그라운드에서 진행됩니다.
  • 자동 재개: 통신 채널이 끊기거나 컴퓨터가 재부팅되더라도 BITS 작업은 자동으로 이어서 진행됩니다.
  • 일시 중지 및 재개: 데이터 손실 없이 다운로드를 중지하거나 재개할 수 있습니다.
    참고: robocopy.exe 유틸리티 역시 연결이 끊긴 경우 파일 복사를 재개하는 기능을 제공합니다.
  • 작업 우선순위 관리: 다운로드 작업의 우선순위를 조정할 수 있습니다.
  • 방화벽 친화적: 파일 전송이 80(HTTP) 또는 443(HTTPS) 포트를 사용하므로 방화벽에서 추가 포트를 열 필요가 없습니다. SMB 복사에 사용되는 445 포트와 달리 보안 이슈도 적습니다(SMB 1.0 구버전에는 다수의 알려진 취약점이 존재합니다).
  • IIS 서버 필수 아님: BITS 수신 측과 서버 측 모두 IIS 웹 서버가 반드시 배포되어 있어야 하는 것은 아닙니다.

이러한 특성 덕분에 BITS는 위성 회선, GPRS 연결 등 느리고 불안정한 네트워크에서 대용량 파일을 전송할 때 가장 적합한 프로토콜이라 할 수 있습니다.

BITS 사용을 위한 OS 및 PowerShell 버전 요구 사항

BITS 프로토콜은 Windows XP부터 도입되었으며, 당시에는 bitsadmin.exe 유틸리티로 BITS 작업을 관리했습니다. 해당 유틸리티는 여전히 지원되지만 더 이상 권장되지 않으므로(deprecated), 전용 PowerShell cmdlet을 사용하는 것이 좋습니다.

이 시나리오를 구현하려면 Windows Vista 또는 Windows Server 2008 이상, 그리고 PowerShell 2.0 이상이 필요합니다. 최신 Windows 10과 Windows Server 2016/2012 R2는 BITS를 완전히 지원합니다.

: Windows Server 2003도 사용 가능합니다. 이 경우 KB923845 업데이트와 PowerShell 2.0을 설치해야 합니다.

BITS 지원은 클라이언트와 서버 양쪽 모두에 필요하다는 점을 유의하세요.

PowerShell로 BITS 프로토콜을 통해 파일 다운로드하기

IIS HTTP 서버에 저장된 대용량 ISO 파일(https://10.1.1.18/erd65_32.iso)을 다운로드한다고 가정해 보겠습니다. 해당 URL에는 익명 접근이 허용되어 있다고 가정하며, 인증이 필요한 URL 접근 방법은 뒤에서 다룹니다.

먼저 PowerShell 세션에서 BITS 모듈을 가져옵니다:

Import-Module BitsTransfer

모듈을 가져온 후 사용 가능한 명령 목록은 다음과 같이 확인할 수 있습니다:

Get-Command *-BITS*

확인 결과 총 8개의 cmdlet을 사용할 수 있습니다:

  • Add-BitsFile
  • Complete-BitsTransfer
  • Get-BitsTransfer
  • Remove-BitsTransfer
  • Resume-BitsTransfer
  • Set-BitsTransfer
  • Start-BitsTransfer
  • Suspend-BitsTransfer

BITS를 이용한 동기식 파일 전송

Start-BitsTransfer cmdlet은 HTTP(S)를 통해 파일을 다운로드할 수 있을 뿐 아니라(Invoke-WebRequest cmdlet과 유사), 네트워크 공유 폴더(SMB)에서도 파일을 가져올 수 있습니다. 지정된 URL에서 BITS 프로토콜로 파일을 다운로드하여 로컬 디렉터리 C:\Temp에 저장하려면 다음 명령을 실행합니다:

Start-BitsTransfer –Source https://10.1.1.18/erd65_32.iso -Destination c:\temp

"This is a file transfer that uses the Background Intelligent Transfer service (BITS)"라는 메시지가 표시되면 지정된 파일이 BITS를 통해 다운로드되고 있는 것입니다.

이 경우 cmdlet은 동기 모드로 ISO 파일 다운로드를 시작합니다. 파일 탐색기나 Copy-Item cmdlet을 통한 일반적인 파일 복사와 유사하게 화면에 진행률 표시줄이 나타납니다. 단, 동기 모드에서는 컴퓨터가 재시작되면 다운로드가 재개되지 않으며 파일 전체를 처음부터 다시 내려받아야 합니다.

비동기 모드로 BITS를 통해 대용량 파일 전송하기

BITS 다운로드는 비동기 모드로도 시작할 수 있습니다. 앞서 소개한 명령에 -Asynchronous 매개변수를 추가하면 됩니다. 비동기 모드에서는 서버나 클라이언트 재부팅, 통신 채널 중단 등 어떤 문제가 발생하더라도 원본이 복구되는 즉시 BITS 작업이 자동으로 재개되며, 연결이 끊긴 시점부터 파일 다운로드를 계속합니다:

Start-BitsTransfer -Source https://10.1.1.18/erd65_32.iso -Destination c:\temp -Asynchronous

중요: 기본적으로 Start-BitsTransfer는 Foreground(최우선) 우선순위로 실행됩니다. 이 모드에서 시작된 다운로드는 다른 프로세스들과 채널 대역폭을 경쟁하게 됩니다. 이를 피하려면 명령 인자로 다른 우선순위를 명시적으로 지정해야 합니다. 예를 들어 -Priority low를 추가합니다:

Start-BitsTransfer -Source https://10.1.1.18/erd65_32.iso -Destination c:\temp -Asynchronous -Priority low

비동기 BITS 작업은 백그라운드에서 실행되며 화면에 다운로드 과정이 표시되지 않습니다. BITS 작업의 상태는 PowerShell 콘솔에서 Get-BitsTransfer 명령으로 확인할 수 있습니다:

Get-BitsTransfer | fl

이 명령은 전송 상태(여기서는 전송 완료: Transferred), 전송된 바이트 수, 전체 파일 크기, 작업 생성 시간, 완료 시간 등의 정보를 반환합니다.

컴퓨터에서 실행 중인 모든 BITS 작업의 상태를 표 형태로 확인할 수도 있습니다:

Get-BitsTransfer | Select DisplayName, BytesTotal, BytesTransferred, JobState | Format-Table -AutoSize

비동기 전송 모드에서는 TMP 확장자를 가진 임시 파일이 생성됩니다(기본적으로 파일 탐색기에서 숨김 처리됨). 이 임시 파일을 원본 파일로 변환하려면 Complete-BitsTransfer 명령을 실행합니다:

Get-BitsTransfer | Complete-BitsTransfer

이후 BITS 다운로드 작업은 완료 처리되고 작업 목록에서 제거됩니다.

원격 파일 서버로 파일 업로드하기

로컬 파일을 원격 Windows 파일 서버의 네트워크 공유 폴더로 업로드할 수도 있습니다. 편의상 복사 작업 이름을 함께 지정하는 명령은 다음과 같습니다:

Start-BitsTransfer -Source C:\iso\w10_1809.iso -Destination \\manch-fs1\iso -Asynchronous -DisplayName CopyISOtoMan

BITS 작업을 일시 중단하려면:

Get-BitsTransfer -Name CopyISOtoMan | Suspend-BitsTransfer

중단된 작업을 재개하려면 Resume-BitsTransfer cmdlet을 사용합니다:

Get-BitsTransfer -Name CopyISOtoMan | Resume-BitsTransfer -Asynchronous

Add-BitsFile cmdlet으로 기존 BITS 작업에 파일을 추가할 수 있습니다:

Get-BitsTransfer -Name CopyISOtoMan | Add-BitsFile -Source C:\iso\w10msu\* -Destination \\manch-fs1\iso -Asynchronous

컴퓨터의 모든 BITS 다운로드 작업을 삭제하려면(다른 사용자가 시작한 작업 포함):

Get-BitsTransfer -AllUsers | Remove-BitsTransfer

단, System 계정으로 실행 중인 BITS 작업은 취소할 수 없습니다(0x80070005 "작업을 취소할 수 없음" 오류 발생). 이런 작업을 취소하려면 SYSTEM 권한으로 Remove-BitsTransfer 명령을 실행해야 합니다.

인증이 필요한 서버에서 다운로드하기

파일이 저장된 서버가 사용자 인증을 요구하는 경우, 다음 명령으로 리소스 접근에 필요한 자격 증명 입력 창을 표시할 수 있습니다:

Start-BitsTransfer -Source https://10.1.1.18/erd65_32.iso -Destination c:\temp -Asynchronous -Priority low -Authentication NTLM -Credential Get-Credential

다운로드 진행률 추적 스크립트

BITS 작업 결과를 쉽게 추적하기 위해 몇 초마다 다운로드 진행률(%)을 화면에 표시하는 간단한 스크립트를 사용할 수 있습니다. 다운로드가 완료되면 스크립트가 자동으로 TMP 파일을 원본 형식으로 변환합니다:

Import-Module BitsTransfer
$bitsjob = Start-BitsTransfer -Source https://10.1.1.18/erd65_32.iso -Destination c:\temp -Asynchronous
while( ($bitsjob.JobState.ToString() -eq 'Transferring') -or ($bitsjob.JobState.ToString() -eq 'Connecting') )
{
  Write-Host $bitsjob.JobState.ToString()
  $Proc = ($bitsjob.BytesTransferred / $bitsjob.BytesTotal) * 100
  Write-Host $Proc "%"
  Sleep 3
}
Complete-BitsTransfer -BitsJob $bitsjob

BITS로 디렉터리 내용 복사하기

앞서 언급했듯이 BITS는 웹 서버를 요구하지 않으므로, 다른 Windows 컴퓨터나 네트워크 공유 폴더에서 직접 파일을 복사할 수 있습니다:

Start-BitsTransfer -Source \\lon-rep01\os\RHEL4.8-x86_64-AS-DVD.iso -Destination c:\temp -Asynchronous

BitsTransfer는 특정 폴더의 모든 파일과 폴더를 재귀적으로 복사하지 못하고, 다른 프로그램이 사용 중인 파일도 복사할 수 없습니다. 지정된 네트워크 공유 폴더의 모든 파일과 하위 디렉터리를 복사하려면 다음 스크립트를 사용합니다(대상 디렉터리 존재 여부를 먼저 확인하고 없으면 생성하도록 구성했습니다):

Import-Module BitsTransfer
$Source="\\lond-rep01\share\"
$Destination="c:\tmp\"
if ( -Not (Test-Path $Destination))
{
  $null = New-Item -Path $Destination -ItemType Directory
}
$folders = Get-ChildItem -Name -Path $source -Directory -Recurse
$bitsjob = Start-BitsTransfer -Source $Source\*.* -Destination $Destination -Asynchronous -Priority low
while( ($bitsjob.JobState.ToString() -eq 'Transferring') -or ($bitsjob.JobState.ToString() -eq 'Connecting') )
{
  Sleep 4
}
Complete-BitsTransfer -BitsJob $bitsjob
foreach ($i in $folders)
{
  $exists = Test-Path $Destination\$i
  if ($exists -eq $false) {New-Item $Destination\$i -ItemType Directory}
  $bitsjob = Start-BitsTransfer -Source $Source\$i\*.* -Destination $Destination\$i -Asynchronous -Priority low
  while( ($bitsjob.JobState.ToString() -eq 'Transferring') -or ($bitsjob.JobState.ToString() -eq 'Connecting') )
  {
    Sleep 4
  }
  Complete-BitsTransfer -BitsJob $bitsjob
}

PowerShell과 BITS로 HTTP 서버에 파일 업로드하기

BITS는 HTTP 서버에서 파일을 다운로드하는 것뿐 아니라 원격 웹 서버로 파일을 업로드하는 것도 지원합니다. 이를 위해서는 대상 서버에 Bits Server Extension 구성 요소가 포함된 IIS 웹 서버가 설치되어 있어야 합니다. IIS 가상 디렉터리 설정의 Bits Uploads 섹션에서 "Allow clients to upload files(클라이언트가 파일을 업로드하도록 허용)" 옵션을 활성화해야 합니다.

익명 인증을 사용하는 경우 NTFS 권한 수준에서 익명 사용자가 해당 디렉터리에 쓸 수 있도록 허용해야 합니다. 인증된 사용자로 업로드가 수행되는 경우에는 업로드 폴더에 RW(읽기/쓰기) 권한을 부여해야 합니다.

BITS 프로토콜로 HTTP 서버에 파일을 업로드하려면 다음 명령을 실행합니다:

Start-BitsTransfer -Source c:\iso\winsrv2016.iso -Destination https://10.1.1.18/MEDVImages/winsrv2016.iso -TransferType Upload

주의: IIS는 기본적으로 최대 30MB까지만 업로드를 허용합니다. 대용량 파일 업로드를 허용하려면 web.config 파일의 maxAllowContentLength 매개변수 값을 변경해야 합니다.

결론

BITS 기능은 SMB 프로토콜을 통한 일반적인 네트워크 파일 복사의 훌륭한 대안이 될 수 있습니다. BITS 파일 전송 작업은 연결 중단이나 컴퓨터 재시작에도 불구하고 계속 수행되며, 대역폭을 많이 점유하지 않아 다른 애플리케이션에 방해가 되지 않습니다. WAN 네트워크를 통해 대용량 ISO 이미지나 가상 머신 파일(vmdk, vhdx)을 전송해야 한다면 BITS 프로토콜이 최적의 솔루션이 될 수 있습니다.