백업 스크립트

사내 또는 팀 내부 망에서 각종 중요 자료를 백업하는 절차는 대체로 비슷하다.

  1. 사람이 없을 때 작업 스케줄러가 백업 스크립트를 실행한다.
  2. 백업 스크립트가 지정된 로컬 폴더를 압축한다.
  3. 백업 스크립트가 압축 파일을 어딘가에 있는 공유 폴더에 복사한다.
  4. 백업이 잘 끝났다는 사실을 관리자에게 알린다.

일련의 과정을 MSBuild 로 구현하면 다음과 같은 모양새가 나온다. 이 스크립트에서는 MSBuild 확장기능을 제공하는 MSBuild.Earlgrey.Tasks 라이브러리를 사용하였다. 확장기능 중 ForFiles와 RoboCopy 는 MSBuild.Earlgrey.Tasks 를 쓰지 않고 명령 줄에서 직접 실행할 수도 있다. Windows 7 (아마 Vista도) 사용자라면 말이다.

 

로컬 백업

<?xml version="1.0" encoding="UTF-8"?>
<Project 
	ToolsVersion="3.5" 
	InitialTargets=""
	DefaultTargets="LocalBackup" 
	xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
>
	<!-- Special characters -->  
	<PropertyGroup>  
		<Semicolon>%3b</Semicolon>  

		<Ampersand>&</Ampersand>
		<LeftAngleBracket><</LeftAngleBracket>
		<RightAngleBracket>></RightAngleBracket>
		<StraightQuotationMark>"</StraightQuotationMark>
		<Quot>$(StraightQuotationMark)</Quot>
		<Apostrophe>'</Apostrophe>
	</PropertyGroup>  

	<PropertyGroup>
		<RootDir>$(MSBuildProjectDirectory)</RootDir>
	</PropertyGroup>	

	<!-- MSBuild.Earlgrey.Tasks 를 사용한다. -->  
	<Import Project="$(RootDir)\MSBuildExtension\MSBuild.Earlgrey.Tasks.Targets"/>

	<!-- 백업할 폴더 -->  
	<ItemGroup>
		<SrcDir Include="C:\중요한 폴더">
			<IgnoreWarning>false</IgnoreWarning>
		</SrcDir>
	</ItemGroup>

	<!-- 백업한 압축 파일을 저장할 폴더 -->  
	<PropertyGroup>
		<LocalBackupDir>f:\Backups</LocalBackupDir>
	</PropertyGroup>	

	<!-- 디스크 용량이 차지 않도록 오래된 압축 파일을 삭제한다. -->  
	<Target Name="DeleteOldBackups">
		<!-- 10 일 이상된 압축 파일의 목록을 얻는다 -->
		<ForFiles
			PathName="$(LocalBackupDir)"
			Command="CMD /C ECHO @path"
			Date="-10"
			Recursive="true"
			ContinueOnError="true"
		>
			<Output TaskParameter="FilesFound" ItemName="FilesFound" />
		</ForFiles>

		<Warning
			Text="$(QUOT)@(FilesFound)$(QUOT) will be deleted!"
			Condition="'@(FilesFound)' != ''"
			/>

		<!-- 오래된 파일을 지운다 -->
		<Delete Files="@(FilesWillBeDeleted)" />
	</Target>

	<!-- 지정된 로컬 폴더를 압축해 백업한다. -->
	<Target Name="LocalBackup" DependsOnTargets="DeleteOldBackups">
		<!-- 하루에 한번 백업하므로 압축 파일의 이름이 겹치지 않게 날짜를 파일 이름에 붙인다 -->
		<Time>
			<Output TaskParameter="Month" PropertyName="Month" />
			<Output TaskParameter="Day" PropertyName="Day"  />
			<Output TaskParameter="Year" PropertyName="Year" />
		</Time>

		<!-- 7-Zip 으로 원본 폴더를 압축해 지정된 백업 폴더에 백업한다. -->
		<MSBuild.Earlgrey.Tasks.IO.Compression.SevenZip.Pack
			ContainsRootDir="true"
			Overwrite="true"
			SrcFolder="%(SrcDir.FullPath)"
			ZipFilePath="$(LocalBackupDir)\%(SrcDir.Filename)-$(Year)-$(Month)-$(Day).7z"
			IgnoreWarning="%(SrcDir.IgnoreWarning)"
		/>

	</Target>

</Project>

 

원격 백업

<?xml version="1.0" encoding="UTF-8"?>
<Project 
	ToolsVersion="3.5" 
	InitialTargets=""
	DefaultTargets="RemoteBackup" 
	xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
>

	<Import Project="msbuild-localbackup.xml" />

	<!-- 백업한 파일을 저장할 원격 공유 폴더 -->
	<PropertyGroup>
		<RemoteBackupDir>\\원격 머신\백업 폴더</RemoteBackupDir>
	</PropertyGroup>

	<Target Name="RemoteBackup" DependsOnTargets="LocalBackup">
		<!-- RoboCopy 를 이용해 원격 공유 폴더에 백업 압축 파일을 복사한다 -->
		<BetterRoboCopy
			SourceFolder="$(LocalBackupDir)" 
			DestinationFolder="$(RemoteBackupDir)" 
			SourceFiles="*" 
			AllSubdirectories="true"
			Options="/R:3"
		/>

		<!-- 백업이 완료되었음을 관리자에게 알린다 -->
		<Email SmtpServer="smtp.server.com"
			TextEncoding="UTF-8"
			From="noreply@noreply.net"
			To="no-reply@noreply.net"
			Subject="[백업] $(Year)-$(Month)-$(Day)"
			IsBodyHtml="false"
			Body="무사히 완료되었습니다." 
		/>
	</Target>

</Project>

This work, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.