강좌 / 팁

윈 도 우 Windows Sysprep 팁

2017.01.18 02:28

CraXicS 조회:10394 추천:15

 

  

 

 

 

 

 

 

 

 

Windows를 커스텀(OEM)으로 배포하기 위해 Microsoft에서 제공하는 Sysprep 기술을 사용합니다. 이 글에서는 이제 막 Sysprep 봉인 기술을 익힌 입문자들을 대상으로 좀 더 효율적인 봉인/배포 방법이나 팁들을 알려드리겠습니다. Sysprep 활용, 가상머신 활용, ISO 및 WIM 파일 수정, 배치 파일 구현, Windows PE 활용 등의 기초적인 지식이 있다는 전제 하의 입문자들을 대상으로 작성합니다. 글쓰는 것이 서툴다 보니 일단 읽어보면서 실습하기보다는 끝까지 읽어 흐름을 파악한 후 다시 읽어보면서 따라하시는 것을 추천합니다.

 

이 글에서 잘못 기술된 부분이 있을 수 있으며, 좀 더 효율적인 방법도 있을 수 있습니다. 댓글 남겨주시면 수정하겠습니다.

 

링크: Sysprep 기초 이론

 

예시 작업 환경:

호스트 OS: Windows 7 SP1_amd64_ko

가상화 프로그램: VMware Workstation Pro 12

파일 관리: UltraISO 9, 반디집 5, GImagex 2, DISM 6.3

배치 파일 컴파일러: Bat to Exe Converter 2

 

1. Windows 업데이트 통합하기

 항상 새로 Sysprep 작업할 시 MSDN 순정 이미지를 사용하는 것이 좋습니다. Windows 업데이트 통합 시에도 필요 없거나 대체되는 업데이트들이 있고, 무결성을 보증하기도 하지요.

 

1-1. 개요

 2016년 10월부터 Windows 7 및 Windows 8.1도 Windows 10의 업데이트 모델을 따라가면서(첨부: Windows_Update.pdf) 더 이상 정기적인 개별 업데이트가 출시되는 대신 월별 롤업으로 대체되고 있습니다. 매달 출시되는 롤업이 이전 달의 롤업 내용을 포함하며 기존의 개별 업데이트를 대체하는 경우도 있기에 통합이 간소화 되었는데요. 이제 기존에 남아있는 몇 안 되는 각종 개별 업데이트(월별 롤업이 대체하지 않고, 독립적으로 배포되는, 이전에 출시된 업데이트들)를 분석하여 최소한의 업데이트만 적용함으로써 이미지 용량 최소화, 스크립트화를 통한 빠른 통합을 해볼 만 합니다. 이제 일반인들이 통합을 할 때마다 업데이트 부분에서 고려해야 할 것은 기존 개별 업데이트들 중 이번 달 최신 롤업이 대체하는 것만 봉인 작업에서 제외시키면 되는 겁니다.

 

1-2. 업데이트를 통합하는 방법

 감사모드로 진입한 후에는 최대한 잡다한 작업을 자제하여 최소한의 시스템 수정으로 봉인하는 것이 가장 깨끗하겠죠. Windows Update를 통해 수동으로 업데이트하는 것보다 순정 install.wim 파일을 마운트해서 DISM으로 업데이트를 통합한 후 오프라인으로는 통합이 되지 않는 업데이트만 따로 Microsoft Update 카탈로그(링크: Microsoft Update Catalog)에서 다운받은 뒤 순정 Windows를 설치할 ISO 파일에 같이 넣어 감사모드에서 설치함으로써 인터넷 연결이나 Windows Update 실행 없이 설치할 수 있습니다. Windows Update를 실행하면 Windows 시스템 디렉터리에 임시파일이 생성되고 이는 곧 install.wim 파일의 용량에도 영향을 미칩니다.

 

참고: 댓글을 통해 알아본 바 업데이트(*.msu) 파일을 감사모드에서 설치하는 방식이 권장된다고 하네요. 오프라인 통합 시 업데이트가 적용이 되지 않는 현상도 몇몇 있어 참고하기 바랍니다. 이 글에서는 배치파일을 통한 오프라인 통합 방법을 기술합니다. (물론 조금만 손보면 감사모드에서의 설치로 바꿀 수 있습니다.)

 

 그럼 임시로 설치한 Windows에서 업데이트 확인 후 나타나는 모든 업데이트들을 카탈로그에서 각각 다운받아야 하는가? 선택적 업데이트들 중에는 우리가 필요하지 않는 업데이트들도 존재하기에 필요하다 싶은 업데이트만 적용하면 될 것입니다. 물론 중요 업데이트들 중 보안 업데이트는 모두 받아 통합하는 것이 좋겠지요. VM에 임시로 Windows를 설치한 후 나타나는 중요 업데이트들 중 보안 업데이트는 모두 카탈로그에서 다운받아 .msu 파일을 준비해둡니다. 카탈로그 홈페이지를 Internet Explorer로 접속하면 Active X 설치 안내창이 뜹니다. Active X를 설치하면 각각 업데이트들을 한 개씩 다운받는 대신 미리 바스켓에 담아 나중에 한꺼번에 다운로드 할 수 있습니다. 업데이트 코드명(예: “KB3125574” 또는 “3125574” 등…)을 입력하여 해당 대상용 업데이트들을 다운로드 합니다.

 

 아래 이미지는 Windows 7 64bit 경우 KB3020369(편의성 업데이트 기반 업데이트), KB3125574(2016년 5월 편의성 롤업), KB3172605(2016년 7월 업데이트 롤업) 설치 후 나타나는 개별 업데이트 목록 중 일부를 나타냅니다.(월별 롤업, 중요 보안 업데이트, .NET Framework 업데이트 및 기타 Microsoft 제품 제외) 위 3가지 업데이트는 Windows 7의 수십 개의 업데이트 통합 롤업 및 업데이트 확인 지연 문제를 해결하는 업데이트들이므로 필수로 설치하는 것이 좋겠다 생각하여 이를 기초로 작성하였습니다.

 

 

[이미지-01]

이미지-01.png

 

 

첨부: Windows 7 64bit 및 Windows 8.1 32bit, 64bit 시스템에 대한 포함 및 제외할 업데이트 목록.xlsx

 

 위 이미지의 판정, 판정 근거, 업데이트 요약은 제가 예시로써 정해놓은 것입니다. 업데이트 설명란의 요약된 내용은 정확히 기입되지 않았을 수 있으니 옆의 URL을 클릭해서 자세한 기술 문서를 통해 알려진 문제, 주의 사항, 정확한 증상, 해결 과정 등을 검토해서 선택하시길 바랍니다.

 

 개별 업데이트들을 모두 다운받았으면 이전에 다운받아놓았던 중요 보안 업데이트들과 이번달 최신 롤업 업데이트, Windows 8.1의 경우 최신 Adobe Flash Player 보안 업데이트, .NET Framework 보안 업데이트, .NET Framework 월별 롤업 등을 작업 폴더 안에 서브 폴더를 구성하여 모두 모아줍니다. 아래 이미지는 그 예입니다.

 

참고: 제 경우 최신 .NET Framework 설치, 업데이트 및 월별 롤업들은 오프라인 통합이 되지 않아 Sysprep 감사모드 진입 후 수동으로 설치하였습니다.

 

[이미지-02] – Windows 7 64bit 기준 예시

이미지-02.png

 

아래 목록은 위 이미지에 나타난 폴더에 제가 예시로 구성한 파일 목록입니다.

 

├─Base //기반 업데이트들

│      windows6.1-kb3020369-x64_base_update.msu

│      windows6.1-kb3125574-v4-x64_convenience_rollup.msu

│      windows6.1-kb3172605-x64_20160912.msu

│     

├─IE11

│      IE-Hyphenation-en.MSU.expt //(저는 이 파일은 필요 없다는 판단에 통합 시 제외시키기 위해 고의로 확장자를 변경했습니다.)

│      IE-Spelling-en.MSU.expt //(저는 이 파일은 필요 없다는 판단에 통합 시 제외시키기 위해 고의로 확장자를 변경했습니다.)

│      IE-Win7.CAB

│      ielangpack-ko-KR.CAB

│     

├─Imp

│      AMD64-all-windows6.1-kb2900986-x64.msu

│      AMD64-all-windows6.1-kb3138612-x64.msu

│     

├─ImpSec

│      AMD64-all-windows6.1-kb2667402-v2-x64.msu

│      AMD64-all-windows6.1-kb2676562-x64.msu

│      AMD64-all-windows6.1-kb2698365-x64.msu

│      AMD64-all-windows6.1-kb2813347-x64.msu

│      AMD64-all-windows6.1-kb2862330-v2-x64.msu

│      AMD64-all-windows6.1-kb2912390-x64.msu

│      AMD64-all-windows6.1-kb2984972-x64.msu

│      AMD64-all-windows6.1-kb3004375-v3-x64.msu

│      AMD64-all-windows6.1-kb3031432-x64.msu

│      AMD64-all-windows6.1-kb3035126-x64.msu

│      AMD64-all-windows6.1-kb3035132-x64.msu

│      AMD64-all-windows6.1-kb3046269-x64.msu

│      AMD64-all-windows6.1-kb3059317-x64.msu

│      AMD64-all-windows6.1-kb3078601-x64.msu

│      AMD64-all-windows6.1-kb3110329-x64.msu

│      AMD64-all-windows6.1-kb3123479-x64.msu

│      AMD64-all-windows6.1-kb3156016-x64.msu

│      AMD64-all-windows6.1-kb3156017-x64.msu

│      AMD64-all-windows6.1-kb3156019-x64.msu

│      AMD64-all-windows6.1-kb3159398-x64.msu

│      AMD64-all-windows6.1-kb3161561-x64.msu

│      AMD64-all-windows6.1-kb3161949-x64.msu

│      AMD64-all-windows6.1-kb3161958-x64.msu

│      AMD64-all-windows6.1-kb3170455-x64.msu

│      AMD64-all-windows6.1-kb3177186-x64.msu

│     

├─ModDrvFW

│      AMD64-all-windows6.1-kb2685811-x64.msu

│      AMD64-all-windows6.1-kb2685813-x64.msu

│     

├─MonthlyRollup

│      AMD64-all-windows6.1-kb3212646-x64.msu //2017년 1월 월별 롤업

│     

├─NFW351Sec

│      IA64_AMD64_X86-all-windows6.1-kb2446710-x64.msu

│      IA64_AMD64_X86-all-windows6.1-kb2478662-x64.msu

│      IA64_AMD64_X86-all-windows6.1-kb2894844-x64.msu

│      IA64_AMD64_X86-all-windows6.1-kb3163245-x64.msu

│     

├─Opt

│      AMD64-all-windows6.1-kb2547666-x64.msu

│      AMD64-all-windows6.1-kb2761217-x64.msu

│      AMD64-all-windows6.1-kb3118401-x64.msu

│      AMD64-all-windows6.1-kb3179573-x64.msu

│      AMD64-all-windows6.1-kb3181988-x64.msu

│      windows6.1-kb2750841-x64.msu

│     

└─PreIE11

        AMD64-all-windows6.1-kb2670838-x64.msu //IE 11을 통합하기 위한 기반 업데이트입니다.

        AMD64-all-windows6.1-kb2729094-v2-x64.msu //IE 11을 통합하기 위한 기반 업데이트입니다.

        AMD64-all-windows6.1-kb2758857-x64.msu //IE 11을 통합하기 위한 기반 업데이트입니다.

 

 자 이제 업데이트를 통합하는 과정만 남았네요. 이제 DISM 툴을 사용하는 시간입니다. 작업 폴더 루트에 install.wim 파일을 두고 DISM 6.3 버전을 구해 작업 폴더에 둡니다. DISM이 6.3 미만 또는 초과 버전이라면 명령어가 다르거나 지원하지 않는 명령어가 있을 수 있습니다. 자세한 내용은 Microsoft 홈페이지의 해당 Windows 버전의 DISM 명령줄 옵션 기술 문서를 참조하십시오.

 

호스트 운영체제의 시스템 종류에 따라 알맞은 버전을 다운로드 하십시오.

 

첨부: DISM_6.3.9600.17029_x86.7z

첨부: DISM_6.3.9600.17029_amd64.7z

 

여기서는 Windows 7_amd64 및 Windows 8.1_x86 버전에 대한 install.wim 파일을 준비했습니다.

 

[이미지-03]

이미지-03.png

 

 

위 이미지에서는 DISM 및 모아놓은 업데이트 폴더, install.wim 파일명에 접미사로 해당 Windows를 구분할 수 있는 버전명을 붙혔습니다. 여러 운영체제를 동시에 통합할 수도 있으므로 이렇게 표시했습니다. 자신만의 정해진 규칙이 있다면 어떻게 구성하든 상관없습니다. DISM 폴더의 경우에도 나눴는데 두 install.wim 파일에 대한 통합을 동시에 실행하면 DISM 프로그램도 동시에 실행되어야 함으로 그대로 복사하고 폴더명만 변경했습니다.

 

1-3. 자동 통합 배치 파일 구현

통합 작업을 자동화 시켜줄 배치 파일을 구현해야 합니다. 처음 배치 파일을 프로그래밍할 때 잘만 해놓으면 나중에는 버전명이나 파일명 정도만 변경하고 실행만 시키면 되니 처음 구성할 때 유연하게 만드시길 바랍니다. 배치 파일 기초 지식: 링크: https://snoopybox.co.kr/1404

 

저는 배치 파일을 구현할 때 Windows 메모장 대신 Notepad++ 프로그램을 사용합니다. (좀 더 괜찮은 프로그램 있으면 소개해주세요.)

 

제가 예시로 구현한 install.wim 업데이트 통합 배치 파일 구성은 다음과 같습니다.

 

[이미지-04]

이미지-04.png

 

다음은 예제 배치 파일 소스에 주석을 달아 놓은 이미지입니다.

 

[이미지-05]

이미지-05.png

 

제가 미리 작성한 배치 파일을 수정하거나 직접 배치 파일을 새로 구성하여(새로 구성할 실력이라면 Alt+BackSpace를 누르십시오.) 통합 과정을 담은 배치 파일을 만드십시오. 그럼 통합을 위해 배치 파일만 실행해 놓고 완료될 때까지 구경하시면 됩니다.

 

첨부: BEEP  //배치 파일에서 비프음을 출력하기 위한 파일입니다. 작업 폴더 루트에 두시면 됩니다.

첨부: 주석예시_Prepare_Add Updates and Optimize Features_Win7EKSP1_amd64_ko_[install_Win7_amd64.wim]_주석을 포함한 예시.cmd (주석을 포함한 예시 설명 파일)

첨부: Prepare_Add Updates and Optimize Features_Win7EKSP1_amd64_ko_[install_Win7_amd64.wim].cmd (예시 배치 파일_Windows 7 amd64.cmd)

첨부: Prepare_Add Updates and Optimize Features_Win8.1PKWMCUP1_x86_ko_[install_Win81_x86.wim].cmd (예시 배치 파일_Windows 8.1 x86.cmd)

 

참고: Windows 8.1의 배치 파일을 보면 .NET Framework 3.5를 활성화시키는 명령어가 있습니다. Windows 8.1에는 기본값으로 .NET FW 3.5가 비활성화 되어있는데 호환성을 위해 활성화해주는 작업입니다. 링크: https://support.microsoft.com/ko-kr/kb/2785188 기술 문서를 참고하여 설명하자면 MSDN ISO 내부에 SxS 폴더가 있습니다. 이것을 배치 파일에서 명시하고 있는 경로에 복사해와서 .NET FW를 활성화 시키면 됩니다. 이 SxS 폴더가 작업에 필요한 파일들이여서 복사해오거나 아니면 경로를 ISO의 가상 드라이브 경로로 수정하면 됩니다. .NET FW 3.5를 활성화시키지 않으신다면 굳이 복사해올 필요 없겠죠?

 

 

여기까지 끝냈으면 작업 폴더 구성은 다음과 같을 겁니다.

 

[이미지-06]

이미지-06.png

 

배치 파일을 열어 변수들과 작업 폴더 속 각종 폴더명, 파일명, 누락된 파일명이 있는지 반드시 점검하고 배치 파일을 실행해봅니다.

 

30분 정도 뒤에 보면 다 완성되어 있을 겁니다.

 

install_Win7_amd64_exp.wim

install_Win81_x86_exp.wim

 

2. Sysprep 용 ISO 제작

 이제 이 install.wim 파일을 ISO 파일에 넣어 VM에 설치하면 될텐데요… 매번 Windows 설치 프로그램을 통해 클릭하며 파티션 설정하며 설치하는 것 보다 응답파일을 구현해서 한방에 감사모드까지 진입하도록 해보겠습니다.

 

2-1. WinPE 제작

 일단 저는 기본 뼈대 즉, ISO 파일과 Windows PE(boot.wim)는 Windows 8.1 32비트 버전을 택했습니다. 64비트 버전이 더 성능이 좋긴 하나 WinPE 부팅 차이는 별로 없고 제 컴퓨터에서 DISM Apply 명령으로 2GB 가량의 install.wim 파일을 푸는데 1분정도 차이가 나더라구요… 이 정도는 무시하면서 까지 32비트를 선택한 이유는 용량이 작습니다. 뭐, 무시할 만한 크기 차이이므로 체감은 거의 없으나 ISO 파일 생성, 부팅 속도에 약간이나마 영향을 주고, 링크: Windows 설치 프로그램 지원 플랫폼 및 플랫폼 간 배포 기술 문서를 참고해보면 WinPE 5.x(Win8.1) x64 및 Windows 8.1 설치 프로그램 x64 버전에서  x86 버전의 운영체제는 설치할 수 없습니다. 더 정확히, 경험을 더해 말하자면 응답파일의 일부 기능(디스크 할당 등…)을 실행하면 오류가 발생합니다. 그 외 응답파일 없이 WinPE x64안에 Windows 설치 프로그램 x64 버전 사용으로 x86, amd64 버전의 Windows 7이상의 OS 설치는 가능합니다. 여기서는 Windows 설치 프로그램의 응답 파일 구성을 최대한 활용하고 호환성을 고려해 32비트 버전을 택했습니다.

 

 MSDN Windows 8.1 with update x86 한국어 버전의 ISO 파일을 준비한 뒤 UltraISO로 이 파일을 엽니다. 파일 시스템 구조를 최대한 직관적으로 보이기 위해 온라인 상태(Windows가 부팅된 상태)에서 Windows를 설치하기 위한 Windows 설치 프로그램은 모두 삭제합니다.(필요에 따라 온라인 설치도 구성하면 더 좋겠지요. 하지만 이 글에서는 이 부분을 생략합니다.) 또 boot 폴더의 중국어, 일본어 폰트 파일, EFI 폴더 등을 삭제하는데요… 어짜피 이 ISO 파일은 Sysprep 용으로만 사용할 것이기에 다른 불필요한 구성요소는 최대한 제거하는 것이 ISO 파일 수정 및 관리하기에도 편합니다. 자세한 정리 방법은 링크: Windows 설치 ISO 용량 줄이기를 참조하십시오. sources 디렉터리의 setup.exe와 boot.wim은 남겨두십시오. 이제 다른 이름으로 저장하여 작업 폴더에 저장합니다. 저는 “Framework.iso”라 저장했습니다.

 

자, 아래와 같은 이미지일 것입니다.

 

[이미지-07]

이미지-07.png

 

 이제 저 boot.wim 파일을 작업 폴더로 복사해 옵니다. UltraISO에서 드래그로 복사해와도 됩니다. 이제 이 파일의 2번 인덱스를 Export 합니다. 링크: Windows 설치 boot.wim 용량 줄이기 게시 글을 통해 2번 인덱스에 대한 설명을 참조하십시오. GImageX와 같은 편한 유틸리티로 이 boot.wim을 마운트 합니다. 그러면 sources(Windows 설치 프로그램)폴더와 setup.exe 파일이 나옵니다. WinPE는 기본적으로 부팅할 때 setup.exe 파일이 루트에 있으면 이 파일을 실행하고 이 파일의 실행과 종료가 곧 WinPE의 시작과 종료가 됩니다. 나중에 Sysprep 후 imagex로 Capture 할 때에도 이 ISO 파일을 사용하기 위해 이 setup.exe 파일을 다른 파일로 변경합니다. 텍스트 편집기를 열어 자신만의 방식이나 알고리즘을 구현해 어떤 상태일 때 Capture하고, sources 폴더의 setup.exe(Windows 설치 프로그램)을 시작할 지 구현하면 됩니다. 저는 아래와 같이 setup 파일 코드를 구현했습니다.

 

::CraXicS(TM) Windows Facelift Edition: Sysprep Start Setup Consol

::Copyleft 2016-2017, by CraXicS(TM)

 

::Main

@echo off

echo Initializing...

cd /d %~dp0

echo Mounting Y: Drive...

X:\Windows\MountPEmedia.exe -ini X:\Windows\MountPEmedia.ini

if not exist Y:\Y.MNT (

           echo Y: Drive Mount Failed.

)

call Y:\sources\switch.cmd

 

 여기서 저는 “MountPEmedia”라는 프로그램을 사용했는데요… 매번 수정이 있을 때마다 boot.wim을 마운트해서 수정하고 언마운트, Export…. 하기보다 주요 스크립트를 ISO 파일 안의 sources 폴더에 넣어 수정하기 편하도록 하기 위해서 WinPE 부팅 시 이 ISO 파일의 드라이브 문자를 Y로 고정하는 프로그램을 사용했습니다. MountPEmedia 프로그램을 사용하면 PE 부팅 후 Y 드라이브를 마운트하는데 약간의 시간이 소모됩니다. (약 30초 이하)

 

첨부: MountPEmedia.7z

 

 MountPEmedia.ini 파일을 열어보면 위와 같이 기존의 “CdUSB.Y”이라는 태그 파일명을 변경할 수 있습니다. 저는 “Y.MNT”(빈 텍스트 파일을 생성하고 파일명과 확장자를 변경해 줍니다.)파일로 정했습니다. 이 배치 파일을 Bat to Exe Converter를 통해 setup.exe 실행 파일로 컴파일합니다. 그리고 마운트된 boot.wim의 루트에 setup.exe 파일을 덮어씁니다.

 

이제 ISO 파일 안에 들어갈 저 switch.cmd 파일을 구현해봅니다.

 

제가 예시로 작성한 switch 배치 소스는 다음과 같습니다.

 

::CraXicS(TM) Windows Facelift Edition: Sysprep Switch Console

::Copyleft 2016-2017, by CraXicS(TM)

 

::Define Var

@echo off

setlocal

set strTitle=CraXicS(TM) Windows Facelift Edition: Sysprep Switch Console

set nVersion=2017_57

set strTargetDrive=NULL

set strDestDrive=NULL

 

::Init UI

prompt $T //

cd /d %~dp0

title %strTitle% %nVersion%

 

::Output Info

echo.

echo %strTitle%

echo Copyleft 2016-2017, by CraXicS(TM).

echo Script Version:        %nVersion%

 

::Main

for %%a in (A: B: C: D: E: F: G: H: I: J: K: L: M: N: O: P: Q: R: S: T: U: V: W: Z:) do (

           if exist %%a\Windows\ (

                     set strTargetDrive=%%a

           )

)

for %%a in (A: B: C: D: E: F: G: H: I: J: K: L: M: N: O: P: Q: R: S: T: U: V: W: Z:) do (

           if exist %%a\CAPTURE_READY (

                     set strDestDrive=%%a

                     goto G_CAPTURE

           )

)

 

:G_INST

X:\sources\setup.exe /unattend:Y:\sources\AutoAudit.xml

pause

 

:G_CAPTURE

X:\sources\imagex /capture %strTargetDrive% %strDestDrive%\install_Sysprep.wim /compress max "Sysprep" /verify

goto G_QUIT

 

:G_QUIT

echo Completed!

echo Windows PE will be shutdown.

wpeutil shutdown

pause

 

주요 실행 과정을 설명하자면 A~Z까지(X, Y 제외) Windows 폴더가 있는지 확인하고 변수에 저장합니다. 또 ”CAPTURE_READY”(빈 파일) 파일이 있는 지 확인합니다. 이 파일은 우리가 VM에서 Sysprep 일반화 과정을 실행하기 전, install.wim 파일이 저장될 드라이브를 지정하기 위해 생성하는 태그 파일입니다. PE로 부팅했는데 이 파일이 존재한다는 것은 Sysprep를 완료했고 이제 캡쳐만 하면 된다는 뜻이므로 goto 문을 통해 imagex를 바로 실행합니다. 위와 같은 명령어를 사용하려면 imagex 파일을 boot.wim 안에 복사해야 겠죠? 만약 CAPTURE_READY 파일이 존재하지 않는다면 Windows를 자동으로 설치합니다. 저 setup.exe에 /noreboot 인수를 붙여주면 자동으로 재부팅되지 않습니다. 이렇게 해서 WinPE를 그냥 종료시키면 OEM PC 처럼 구입 후 첫 부팅 시 OOBE 과정이 나오는 화면이 나타나죠.

 

2-2. 응답 파일 구현

이제 저 AutoAudit.xml 응답 파일을 설명합니다.

 

첨부: AutoAudit.xml

 

위 응답 파일을 열어보면 알겠지만 amd64 버전을 설치하려면 최소 25GB는 있어야 20GB를 Windows 설치에 쓰고 나머지 공간을 install.wim 저장하는데 쓰겠죠? VM을 만들 때 지정한 크기 이상으로 만들어야 응답 파일 오류도 나지 않습니다. 또한 커스텀 PE에서는 “디스크 관리”나 “diskpart” 등 드라이브를 수정하는 프로그램 실행 후 Windows 설치 프로그램을 실행하면 오류가 나더라구요. 그럴땐 디스크의 모든 파티션을 할당 해제하고(파티션이 없는 상태) PE를 재부팅하고 바로 Windows 설치 프로그램을 실행해야 합니다. Windows 설치가 완료되면 OOBE 진입을 하고 바로 감사모드로 재부팅되어 진입됩니다. 그러면 VM에 스냅샷을 찍어두어 이 상태를 백업해두면 언제든지 이 상태로 되돌아 갈 수 있죠.

 

2-3. 파일 통합

이제 boot.wim 파일을 정리하고 ISO 파일에 필요한 파일들을 넣습니다. 이 상태로 그냥 설치 하면 Windows 8.1 설치 프로그램에서 라이센스 오류로 인해 설치가 실패하는데 sources 폴더에 “ei.cfg”라는 빈 텍스트 문서를 만들고 아래와 같이 입력하면 문제를 피할 수 있습니다.

 

[EditionID]

 

[Channel]

Retail    //WMC 에디션 설치 시 필요

[VL]

0

 

또는

 

[EditionID]

 

[Channel]

Volume

[VL]

1

 

ISO 파일을 보면 다음과 같은 파일 구조일겁니다.

 

│  Y.MNT

│  bootmgr

│ 

├─boot

│  │  bcd

│  │  boot.sdi

│  │  bootfix.bin

│  │  bootsect.exe

│  │  etfsboot.com

│  │  memtest.exe

│  │ 

│  ├─fonts

│  │      kor_boot.ttf

│  │      malgun_boot.ttf

│  │      malgunn_boot.ttf

│  │      meiryo_boot.ttf

│  │      meiryon_boot.ttf

│  │      msjh_boot.ttf

│  │      msjhn_boot.ttf

│  │      msyh_boot.ttf

│  │      msyhn_boot.ttf

│  │      segmono_boot.ttf

│  │      segoe_slboot.ttf

│  │      segoen_slboot.ttf

│  │      wgl4_boot.ttf

│  │     

│  ├─ko-kr

│  │      bootsect.exe.mui

│  │     

│  └─resources

│          bootres.dll

│         

└─sources

        AutoAudit.xml

        boot.wim

        ei.cfg

        install.wim          //아까 배치 파일로 통합한 install.wim 파일입니다.

        setup.exe

        switch.cmd

 

이제 이 ISO를 VM에 넣고 첫번째 부팅 항목으로 부팅시킵니다.

 

[이미지-08]

이미지-08.png

 

 

[이미지-09]

이미지-09.png

 

감사모드로 부팅되었으니 스냅샷 찍은 후 수동 업데이트, 유틸리티 설치, 하고 싶은 설정 등을 합니다. 여기에서도 배치 파일을 써먹으면 좀 더 빠른 설정이 가능하죠. 서비스 설정, 그룹 정책, 레지스트리 설정, 작업 스케줄러 설정 등등의 설정 사항을 배치 파일로 구현해 놓고 ISO 파일에 포함시켜두면 감사모드 진입 후 이 배치 파일을 실행시키면 좀 더 시간을 단축시킬 수 있습니다. 그리고 배치 파일로 백업 드라이브를 포맷하고 문자 할당 뒤 CAPTURE_READY 파일을 만들어 주면 좋겠죠?

 

마무리로 임시 파일 최적화 등을 한 뒤 마지막 스냅샷을 찍은 후 Sysprep 일반화 명령을 내립니다. 사용자 계정의 개인 설정 까지 봉인하려면 Sysprep.exe의 명령줄 옵션에 Unattend가 있는데 링크: Sysprep의 사용자 계정 설정 봉인 작업에서 추가 정보를 참조하여 구성하면 %windir%\System32\Sysprep\sysprep.exe /oobe /generalize /shutdown /unattend:[응답 파일의 경로] 이렇게 명령을 내리면 되겠죠?

 

참고: 일반적인 응답 파일은 Windows 설치 프로그램에서 사용자 입력을 미리 지정된 값으로 대체하여 자동 설치를 구현하기 위해 사용합니다. 이 응답 파일은 이미지 Apply가 끝난 후 OOBE에서의 작업을 위해 Windows가 적용된 드라이브의 \Windows\Panther\ 디렉터리에 unattend.xml 파일로 저장됩니다. 그리고 재부팅 후 이 응답 파일을 사용하여 OOBE 작업도 진행합니다. 여기서 응용해보면, install.wim을 마운트 해서 저 경로에 특정 unattend.xml 파일(예를 들어 OOBE를 스킵한다던지, 특정 계정에 특정 암호(평문으로 저장되지 않습니다.)가 저장 된)을 넣어두면 이 이미지를 설치할 때 마다 따로 응답 파일을 주지 않는 한 저 unattend.xml이 항상 실행됩니다. 그러므로 위에서 응답 파일을 활용한 감사모드 자동 진입 방식 말고 diskpart로 디스크 할당 후 DISM으로 Apply 및 감사 모드 진입 응답 파일을 Panther 폴더에 넣어주는 것 만으로도 감사모드 자동 진입이 가능하죠. 하지만 Sysprep 일반화 시 unattend 파일을 인수로 사용했다면 그 파일이 Panther 폴더에 있을텐데 그 파일의 CopyProfile 항목을 덮어쓸 xml 파일에 포함해야 CopyProfile 설정(개인 설정이 된 사용자 계정 프로필)이 그대로 적용됩니다.

 

이제 VM이 꺼졌을 겁니다. 이제 다시 부팅을 한 뒤 ISO로 부팅하면 Imagex가 캡쳐를 시작합니다. 그 뒤 PE가 종료되면 이제 VM 디스크를 맵핑해서 호스트 OS로 복사해오면 2/3 정도의 작업은 끝났습니다. 캡쳐된 install.wim에 드라이버를 설치한다던지, WIM 이미지 정보를 기입한다던지, ESD 파일로 압축한다던지 하는 작업도 배치파일로 대신 하면 편합니다.

 

3. 배포 ISO 구성

 이제 배포될 ISO 이미지를 구성할 차례입니다. 이 ISO도 한번 잘 만들어 놓으면 다음에 봉인 작업 시 install.wim 파일만 교체해 주면 됩니다. 이 ISO 파일도 마찬가지로 MSDN 뼈대에서 솎아낼 것 솎아내고 자신이 쓸 boot.wim 등을 넣고 구성해줍니다.

 

3-1. 다중 응답 파일 선택 모드

 기존의 Windows 설치 프로그램에서는 응답 파일을 사전에 미리 지정하는 방식을 사용했었는데요. 이 setup.exe의 unattend 인수를 이용해 여러 응답 파일을 Windows 설치 시 선택할 수 있게 하는 프로그램을 이용하는 방법도 있어 좀 더 유연하게 사용할 수 있습니다. 참조 게시글: 링크: https://windowsforum.kr/lecture/5899630 (대체 링크: https://www.coolrun.me/bbs/board.php?bo_table=pc_tip&wr_id=118)

 

여기 샘플 응답 파일을 올려둡니다.

 

첨부: unattend.7z

 

참고: 위 첨부 파일에서 제가 테스트 성공한 것은 x86 버전이였습니다. 아마 PE의 비트 버전이나 install.wim의 버전과 연관이 있거나 할 것 같은데 더 이상의 삽질은 너무 힘들어 추측으로만 끝냅니다.

 

$OEM$ 폴더의 setupcomplete.cmd 파일 또한 위의 방법처럼 배치 파일이나 EXE 파일의 실행을 유도하는 식으로 응용할 수 있습니다. 링크: Windows 설치 프로그램에 사용자 지정 스크립트 추가

 

3-2. 업데이트 숨기기 스크립트

 위에서 업데이트 각 항목의 설명을 보면 불필요한 업데이트들이 중요, 권장 업데이트로 선정되어 있습니다. OOBE에서 권장 업데이트나 중요 업데이트 설치 옵션을 선택하면 그 Windows에서는 자동으로 불필요한 업데이트들을 설치하게 되죠. 링크: 업데이트 제거하고 숨기기 테스트 이 글의 도움을 받아 지정한 업데이트를 숨기는 스크립트를 약간 수정해 만들어 봤습니다. $OEM$ 폴더에 넣어두고 Windows를 설치할 때마다 OOBE에서 사용자에게 불필요한 업데이트를 숨기는 작업을 예약할 것인지 물어봅니다. 아래는 제가 예시로 작성한 스크립트 파일입니다.

 

스크립트의 본체에 해당하는 이 부분은 제가 C언어로 컴파일 하느라 핵심 코드만 빼왔습니다. Setupcomplete.cmd라 생각하고 봐주세요.

 

Setupcomplete

system("schtasks /create /ru SYSTEM /sc ONSTART /tn \"Hide Unwanted Windows Updates\" /tr \"wscript %systemroot%\\setup\\scripts\\hideUpdates.vbs\" /F /RL HIGHEST");

system("schtasks /run /tn \"Hide Unwanted Windows Updates\"");

system("schtasks /create /ru SYSTEM /sc ONSTART /tn \"Delete OOBE Scripts\" /tr \"%systemroot%\\setup\\scripts\\DeleteScripts.cmd\" /F /RL HIGHEST");

 

배치 파일에 적용할 땐 명령 프롬프트에 “schtasks /?”를 입력하면 자세한 예시가 나와있습니다.

 

다음은 핵심 부분이죠. 업데이트를 숨기는 예시 스크립트입니다. *.vbs 파일로 저장해야되며 이 코드들도 업데이트를 확인한 뒤 숨기기 때문에 업데이트 지연 패치가 된 상태라면 약 10분 이하로 기다리면 숨겨집니다. 물론 인터넷에 연결되어 있어야겠죠.

 

HideUpdates.vbs

Dim hideupdates(22)

hideupdates(0) = "KB971033"                  ' Win7_amd64_Windows 정품 인증 기술 업데이트

hideupdates(1) = "KB3184143"                ' Win7_amd64_Windows 10 무료 업그레이드 관련 업데이트 제거

hideupdates(2) = "KB3080149"                ' Win7_amd64_기존의 장치에 대한 진단 및 원격 측정 서비스 업데이트 및 최신 Windows에 대한 정보 제공

hideupdates(3) = "KB3068708"                ' Win7_amd64_원격 진단 및 고객 만족에 대한 업데이트

hideupdates(4) = "KB3021917"                ' Win7_amd64_최신 Windows 설치 시 성능 문제가 발생할 수 있는지 결정하기 위해 진단 수행 및 정보 전송

hideupdates(5) = "KB2952664"                ' Win7_amd64_Windows 7 업그레이드에 대한 호환성 업데이트

hideupdates(6) = "KB2994290"                ' Win8.1_x86_amd64_37개 언어 인터페이스 팩 설치

hideupdates(7) = "KB3008242"                ' Win8.1_x86_amd64_KB2996799 설치 후 시스템 연결 대기 모드 진입 실패 현상 해결

hideupdates(8) = "KB3031044"                ' Win8.1_x86_amd64_2014년 11월 풀 미디어 리프레시 이미지로 제작된 OEM 버전에서 임베디드 락다운 매니저가 예상치 못하게 설치 될 수 있는 현상 해결

hideupdates(9) = "KB3044374"                ' Win8.1_x86_amd64_Windows 10으로 업그레이드 옵션 제공

hideupdates(10) = "KB2976978"               ' Win8.1_x86_amd64_CEIP(사용자 환경 개선 프로그램)에 참여하는 시스템에 대한 진단 수행

hideupdates(11) = "KB3013531"               ' Win8.1_x86_amd64_Windows에서 Windows Phone으로 *.mkv 파일 복사를 지원

hideupdates(12) = "KB3013816"               ' Win8.1_x86_amd64_2014년 12월 시스템 센터 모바일 장치 관리자 (MDM) 에이전트 기능 업데이트

hideupdates(13) = "KB3033446"               ' Win8.1_x86_amd64_Atom 칩의 CHT(Intel Cherry Trail) 플랫폼 시스템에서 Wi-Fi 연결 문제 또는 성능 저하 문제 해결

hideupdates(14) = "KB3045717"               ' Win8.1_x86_amd64_네레이터가 Crtl 키를 눌러도 읽기를 멈추지 않는 현상 해결

hideupdates(15) = "KB3054169"               ' Win8.1_x86_amd64_OCA(Online Crash Analysis) 서버의 분류를 도와주는 미니덤프 파일에 필요한 정보를 더 추가

hideupdates(16) = "KB3061493"               ' Win8.1_x86_amd64_새로운 장치를 지원하는 자기스트라이프 드라이버를 사용하는 업데이트

hideupdates(17) = "KB3080149"               ' Win8.1_x86_amd64_고객 경험 및 진단 원격 측정용 업데이트

hideupdates(18) = "KB3095701"               ' Win8.1_x86_amd64_TPM 2.0 장치를 인식할 수 없는 현상 해결

hideupdates(19) = "KB3133690"               ' Win8.1_amd64_Azure R2 Windows Server 2012 기반 게스트 가상머신에서 실행되는 개별 장치 할당 지원을 추가

hideupdates(20) = "KB3137061"               ' Win8.1_x86_amd64_Auzure 가상머신이 네트워크 끊김과 데이터 손상 이슈를 복구하지 않는 현상 해결

hideupdates(21) = "KB3137725"               ' Win8.1_x86_amd64_"Get-StorageReliabilityCounter"가 올바른 온도값을 보고하지 않는 현상 해결

hideupdates(22) = "KB3184143"               ' Win8.1_x86_amd64_Windows 10 무료 업그레이드 관련 업데이트 제거

 

set updateSession = createObject("Microsoft.Update.Session")

set updateSearcher = updateSession.CreateupdateSearcher()

Set searchResult = updateSearcher.Search("IsInstalled=0 and Type='Software'")

 

For i = 0 To searchResult.Updates.Count-1

           set update = searchResult.Updates.Item(i)

           For j = LBound(hideupdates) To UBound(hideupdates)

                     'MsgBox hideupdates(j)

                     if instr(1, update.Title, hideupdates(j), vbTextCompare) = 0 then

                                'Wscript.echo "No match found for " & hideupdates(j)

                     else

                                'Wscript.echo "Hiding " & hideupdates(j)

                                update.IsHidden = True

                     end if

           Next

Next

'Re-Search Updates for Refresh Hidden Updates List.

updateSearcher.Search("IsInstalled=0 and Type='Software'")

'Delete files....

Dim WshShell : Set WshShell = CreateObject("WScript.Shell")

WshShell.Run "schtasks /delete /tn ""Hide Unwanted Windows Updates"" /f"

 

Sub DEL (Execute)

set fso = CreateObject("Scripting.FileSystemObject")

fso.DeleteFile Execute

Set wshShell = Nothing

End Sub

 

set winsh = CreateObject("WScript.Shell")

set winenv = winsh.Environment("Process")

SYSTEMROOT = winenv("SYSTEMROOT")

DEL SYSTEMROOT & "\Setup\Scripts\HideUpdates.vbs"

 

맨 끝에 HideUpdates.vbs 파일을 삭제하는데 그래야 밑의 배치파일에서 업데이트 숨기기 작업이 완료되었다는 것을 알 수 있습니다.

 

DeleteScript.cmd

::CraXicS™ Integrated Windows Installation System

@echo off

pushd %~dp0

if exist %systemroot%\Setup\Scripts\HideUpdates.vbs (

           exit

) else (

           rd /s /q "%systemroot%\Setup\Scripts"

           schtasks /delete /tn "Delete OOBE Scripts" /f

           schtasks /delete /tn "Hide Unwanted Windows Updates" /f

           rd "%systemroot%\Setup\Scripts"

)

exit

 

위 배치 파일은 OOBE에서 작업 스케줄러에 등록되는데 매 부팅 때마다 업데이트 숨기기 작업이 다 끝났는지 확인하고 끝났다면 업데이트 숨기기 작업과 이 작업을 작업 스케줄러에서 삭제하고 Scripts 폴더 내의 모든 파일들을 삭제합니다. 굳이 작업 스케줄러를 이용한 이유는 사용자가 업데이트 숨기기 작업이 채 끝나지도 않았는데 컴퓨터를 종료하던가 네트워크 연결을 끊어버리면 작업이 도중에 중단되잖아요. 그러므로 매 부팅 시 이 작업을 실행시켜 줍니다.

 

거의 작업을 다 마쳤네요. 이제 수정할 것 수정하고 디버깅하면 끝입니다.

매번 작업 할 때마다 조금씩 생각을 바꿔서 시도해보면 이것보다 더 좋은 이미지를 만들 수 있을 것입니다.

 

제가 만들어 본 ISO 파일과 부팅 과정 입니다.

 

[이미지-10]

이미지-10.png

 

[이미지-11~20]

이미지-11.png

 

이미지-12.png

 

이미지-13.png

 

이미지-14.png

 

이미지-15.png

 

이미지-16.png

 

이미지-17.png

 

이미지-18.png

 

이미지-19.png

 

이미지-20.png

 

 

 

이로써 허둥지둥 쓴 게시 글 하나 마쳤네요. 짧은 시간에 짬짬이 쓴 것이라 읽기가 불편하실 텐데 긴 글 읽어주셔서 감사합니다. 그리고 링크로 걸어두었던 각종 게시글들 작성자님들께도 감사의 말을 남깁니다.

 

 

 

 

 

 

 

 

 

번호 제목 글쓴이 조회 추천 등록일
[공지] 강좌 작성간 참고해주세요 gooddew - - -
» 윈 도 우| Windows Sysprep 팁 [25] CraXicS 10394 15 01-18
3081 윈 도 우| 윈도우10 IDE 모드 와 AHCI 모드 상호 전환하기 [22] gooddew 13084 19 01-08
3080 윈 도 우| 의심스러운 프로세스 검사하기 [4] gooddew 5468 5 01-06
3079 윈 도 우| bootice gpt 파티설 설정 및 WinNTsetup 설치 [9] nhk 4107 2 01-05
3078 기 타| 이번에 인스타그램만큼이나 어렵게 암호화된 트위터도 제가... [4] Star★Bros 3508 4 12-31
3077 윈 도 우| 윈도우 오피스 전화인증을 웹으로... [12] 유랑천하 9305 2 12-29
3076 윈 도 우| OS MIGRATION - Mini Tool PartitionWizard [10] gooddew 5284 10 12-26
3075 소프트웨어| 크롬브라우저에 비밀번호 백업및 복원 기능이 있을줄이야 ★★ [8] Star★Bros 4690 3 12-24
3074 하드웨어| 커넥터 파손 하드 디스크 데이터 복구 [5] gooddew 5222 2 12-22
3073 소프트웨어| IMDISK vmware VMDK 간편하게 마운트 하기 [10] 입니다 3975 3 12-19
3072 소프트웨어| 크로미엄 55 버전에서 플래시 사용설정 [10] 스마트(SMART 2584 2 12-15
3071 윈 도 우| 비밀번호로 폴더 공유하기 [2] DOS 4797 2 12-14
3070 서버 / IT| 페이스북이 버벅이거나 동영상이 끊어진다면 ★ [5] Star★Bros 2718 4 12-13
3069 윈 도 우| 윈도우10 최근문서 및 사용한 파일 설정 방법 ezue56 6911 1 12-06
3068 윈 도 우| 윈도우 설치 후 첫 업데이트가 아주 오래걸리는 증상 해결 [7] 오호라7 6947 3 12-04
3067 윈 도 우| windows10 업데이트 끄기 [4] 은방 9260 1 12-02
3066 윈 도 우| 윈도우 업데이트 확인중 무반응- 내용 수정 [10] cline 6313 5 11-30
3065 소프트웨어| * Premiere 강좌 29 Track Select Tool로 타임라인의 모든... murimgasa 2161 1 11-21
3064 소프트웨어| *Premiere 강좌 28. 사진과 영상의 속성을 복사하기, 클맆 ... murimgasa 2073 1 11-21
3063 소프트웨어| *Premiere 강좌 27 프로젝트와 시퀀스 초간단 설정법 murimgasa 1660 0 11-21
XE1.11.6 Layout1.4.8