그룹 정책 개체는 Windows Server 인프라를 관리하는 데 핵심적인 요소입니다. 심각한 서비스 문제가 발생하지 않도록 관리자는 GPO를 신중하게 구성해야 하며, 변경하기 전에 백업해 두고 필요 시 변경 사항을 빠르게 되돌릴 준비가 되어 있어야 합니다.
Group Policy Refresher
그룹 정책 개체(Group Policy object) 백업 및 복구를 자세히 살펴보기 전에, GPO가 어떻게 생성되고 사용되는지에 대한 몇 가지 중요한 세부 정보를 먼저 확인해 보겠습니다.
GPO 구성 요소
새 Group Policy 개체가 생성되면 고유 식별자(GUID)가 할당됩니다. 각 GPO는 두 부분으로 구성됩니다:
- 그룹 정책 템플릿(Group Policy template, GPT) — GPT는 SYSVOL 파일 공유의 폴더 집합으로 구성됩니다(“C:\WindowsSYSVOLdomainPolicies{GUID}”). 이러한 폴더는 템플릿, 설정, 스크립트 및 MSI 패키지에 대한 세부 정보를 포함하여 Group Policy 개체 콘텐츠의 대부분을 저장하는 데 사용됩니다. GPT는 Windows 버전에 따라 File Replication Services(FRS) 또는 Distributed File System Replication(DFSR)에 의해 해당 도메인의 모든 DC에 복제됩니다. 실제로 SYSVOL은 도메인 내에서만 복제되므로, GPO는 사실상 도메인 전용처럼 동작합니다.
- 그룹 정책 컨테이너(Group Policy container, GPC) — GPC는 CN=System,CN=Policies 아래의 도메인 명명 컨텍스트(domain naming context)에 있는 groupPolicyContainer 개체입니다. 이 AD 개체의 속성은 GPO와 관련된 참조 정보를 저장하는 데 사용됩니다. 특히 여기에는 SYSVOL에서 GPO의 GPT로 연결되는 경로를 포함하는 gPCFileSysPath 속성이 포함됩니다. GPT와 달리 GPC는 구성된 복제 비용, 스케줄 및 간격에 따라 Active Directory Domain 서비스에 의해 복제됩니다.
GPO 연결
GPO가 생성되면 하나 또는 여러 Active Directory 개체(조직 구성 단위, OU, 도메인, 사이트)와 연결할 수 있습니다. 이 연결은 GPO가 관리하는 것이 아니라 연결된 각 AD 개체가 gPLink 특성에서 유지합니다. 개체의 gPLink 특성 값은 해당 개체가 연결된 각 GPO의 GPC 경로 목록입니다. GPO와 개체 간의 연결이 생성되거나 삭제될 때는, 영향을 받는 개체의 gPLink 특성 값만 수정됩니다.
중요한 점은 SYSVOL의 복제가 사실상 GPO를 도메인 전용으로 만든다는 점이지만, GPO를 사이트 개체에 연결할 수 있다는 사실 때문에 GPO 관련 정보가 반드시 도메인에만 국한되는 것은 아니라는 것입니다. 사이트 개체는 Active Directory 구성 파티션에 저장되며, 이 파티션은 포리스트의 모든 도메인 컨트롤러에 복제됩니다. 그 결과, gPLink 특성에 포함된 그룹 정책 개체의 GPC 경로가 Active Directory 복제 과정에서 도메인을 “몰래” 빠져나가는 현상이 발생할 수 있습니다.
그룹 정책 처리 순서
Active Directory는 다음 순서로 GPO를 적용합니다.
- 로컬 GPO
- 사이트 연결 GPO
- 도메인 연결 GPO
- OU 연결 GPO(루트부터 처리하므로, 하위 OU에 연결된 GPO가 상위 OU에 연결된 GPO보다 우선 적용됩니다)
마지막에 적용된 정책이 “우선” 적용됩니다(“Enforce” 옵션을 사용하면, 이후에 적용되는 정책이 해당 정책을 덮어쓰지 못하게 됩니다).
사용자 및 컴퓨터 구성
마지막으로 알아둘 점은 GPO에 컴퓨터 구성과 사용자 구성이 모두 포함된다는 것입니다. 이 하위 그룹에는 거의 동일한 정책 설정 세트가 들어 있지만, GPO 설정이 적용되는 시점은 서로 다릅니다.
컴퓨터 구성 설정은 부팅 중에 컴퓨터에 적용되고, 사용자 구성 설정은 로그온 중에 적용됩니다. 즉, 컴퓨터 구성의 옵션은 연결된 컴퓨터에 항상 강제 적용되지만, 사용자 구성의 옵션은 연결된 사용자 계정이 컴퓨터에 로그인할 때만 강제 적용됩니다.
사용자가 컴퓨터에 로그온했을 때 컴퓨터 구성 설정과 사용자 구성 설정 사이에 충돌이 발생하면, 컴퓨터 구성 설정이 항상 우선 적용됩니다.
PowerShell을 사용한 GPO 백업 및 복원 프로세스
이 핵심 개념을 충분히 이해했다면, 이제 GPO 백업 및 복원으로 넘어갈 수 있습니다.
먼저 Microsoft의 Windows 원격 서버 관리 도구에 포함된 관련 Group Policy PowerShell cmdlet 두 가지부터 살펴보겠습니다:
- Backup-GPO — 이 cmdlet을 사용하면 한 도메인의 모든 Group Policy 개체 또는 단일 지정 GPO의 스냅샷을 매우 쉽게 만들 수 있습니다.
- Restore-GPO — 이 cmdlet은 Backup-GPO cmdlet으로 생성된 백업에 캡처된 상태로 Group Policy 개체를 복원할 수 있습니다.
모든 GPO의 백업 생성
다음 PowerShell 스크립트는 Backup-GPO cmdlet의 -All 매개 변수를 사용하여 지정한 DC를 사용해 지정된 도메인의 모든 GPO를 백업합니다:
$BackupPath = '\HOSTNAMEGPOBackup'
$Domain = 'domain.local'
$DomainController = 'DC.domain.local'
$BackupFolder = New-Item -Path $BackupPath -Name (Get-Date -format yyyyMMddTHHmmss) -ItemType Directory
Backup-GPO -All -Domain $Domain -Server $DomainController -Path $BackupFolder
Backup-GPO cmdlet의 출력은 각 GPO의 백업 정보에 대해 각각 별도의 하위 폴더와, 각 하위 폴더를 해당 GPO에 연결하는 데 필요한 정보를 포함하는 manifest.xml 파일로 구성됩니다:
하위 폴더 중 하나를 살펴보면, 각 백업은 폴더와 세 개의 XML 파일로 구성되어 있음을 확인할 수 있습니다:
폴더에는 그룹 정책 개체의 GPT 사본이 들어 있으며, XML 파일에는 그룹 정책의 GPC에서 가져온 데이터, 백업 실행에 고유한 정보, 그리고 GPO의 내용을 설명하는 보고서가 포함되어 있습니다.
Netwrix Identity Recovery
단일 스냅샷으로 AD 및 Group Policy 개체를 백업하고 복구
백업 버전 관리
그룹 정책 개체를 한 위치에 반복적으로 백업하는 것은 지원되지만, 이 스크립트를 실행할 때마다 출력용으로 고유한 하위 폴더가 생성됩니다. 하위 폴더의 이름은 cmdlet 실행 중에 생성되는 백업 전용 GUID를 사용해 지정되므로, 단일 위치에 반복 백업을 수행할 때 이름 충돌이 발생할 가능성이 거의 사라집니다.
각 실행의 출력값을 고유한 폴더로 분리하는 것은 엄격히 필수는 아니지만, Restore-GPO cmdlet의 동작은 이를 수행할 경우 이점이 생기게 합니다. Restore-GPO cmdlet은 한 번에 모든 GPO를 복원할 수 있게 해주지만, manifest.xml에 표시된 각 그룹 정책 개체의 가장 최근 백업을 사용합니다. 각 백업 세트를 각자의 폴더로 분리하면, 각 백업 세트에 고유한 manifest.xml이 할당되도록 보장할 수 있습니다. 이를 통해 이러한 백업 세트 중 어느 것이든 해당 세트에 포함된 모든 GPO를 단일 작업으로 복원할 수 있습니다.
Backup-GPO cmdlet의 -All 매개 변수를 사용하는 데는 단점이 있습니다. 이 매개 변수를 실행할 때마다 변경된 것만이 아니라 도메인의 모든 그룹 정책 개체를 백업하기 때문입니다. 이러한 문제를 해결하는 한 가지 방법은 아래와 같은 스크립트를 사용하는 것입니다. 이 스크립트는 Backup-GPO cmdlet이 업데이트 폴더에 스크립트가 생성하는 파일을 사용하도록 강제하여, 스크립트의 마지막 실행 시간에 대한 타임스탬프를 유지합니다. 파일이 존재하면, 스크립트는 파일에 기록된 타임스탬프 이후에 수정된 도메인의 모든 GPO를 백업합니다. 파일이 존재하지 않으면, 스크립트가 파일을 생성하고 타임스탬프를 설정한 뒤 도메인의 모든 GPO를 백업합니다.
$BackupPath = '\DCGPOBackup'
$Domain = 'domain.local'
$DomainController = 'DC.domain.local'
$BackupPathTracker = "$BackupPathLastBackup.txt"
if((Test-Path "$BackupPathTracker")) {
$LastBackup = Get-Date (Get-Content -Path "$BackupPathTracker")
Set-Content -Path "$BackupPathTracker" -Value (Get-Date)
$GPOs = Get-GPO -All -Domain $Domain -Server $DomainController
$GPOs | Where-Object { $_.ModificationTime -gt $LastBackup } | ForEach-Object {
Backup-GPO -Guid $_.Id -Domain $Domain -Server $DomainController -Path $BackupPath
}
} else {
Set-Content -Path "$BackupPathTracker" -Value (Get-Date)
Backup-GPO -All -Domain $Domain -Server $DomainController -Path $BackupPath
}
이 방식은 불필요한 백업을 제한함으로써 공간을 절약할 수 있지만, 실제로 수행하는 백업이 모두 동일한 폴더에 저장되므로 특정 시점으로 그룹 정책 개체를 복원하기가 어렵습니다.
이 두 스크립트 각각에서 사용한 접근 방식을 결합하면, 우리의 모든 문제가 해결되겠죠?
BackupPath = '\HOSTNAMEGPOBackup'
$Domain = 'domain.local'
$DomainController = 'DC.domain.local'
$BackupPathTracker = "$BackupPathLastBackup.txt"
$BackupFolder = New-Item -Path $BackupPath -Name (Get-Date -format yyyyMMddTHHmmss) -ItemType Directory
if((Test-Path "$BackupPathTracker")) {
$LastBackup = Get-Content -Path "$BackupPathTracker"
Set-Content -Path "$BackupPathTracker" -Value (Get-Date)
$GPOs = Get-GPO -All -Domain $Domain -Server $DomainController
$GPOs | Where-Object { $_.ModificationTime -gt $LastBackup } | ForEach-Object {
Backup-GPO -Guid $_.Id -Domain $Domain -Server $DomainController -Path $BackupFolder
}
}
else {
Set-Content -Path "$BackupPathTracker" -Value (Get-Date)
Backup-GPO -All -Domain $Domain -Server $DomainController -Path $BackupFolder
}
결론적으로, 각 차등 백업 결과를 각각의 폴더로 분리하는 것은 오히려 모든 상황을 훨씬 더 나쁘게 만듭니다. 이 방식은 또한 각 manifest.xml 파일을 각자만의 폴더에 격리하게 만들어, 한 번에 모든 GPO를 복원할 수 있는 기능을 사실상 없애는 동시에 특정 Group Policy 개체와 연결된 백업을 찾는 일도 매우 어렵게 만듭니다.
백업에서 GPO 복원
실제로 이러한 접근 방식은 Restore-GPO cmdlet의 한계에 부딪힙니다. Restore-GPO는 manifest.xml 파일에 참조된 가장 최근 백업 또는 지정된 백업에서 특정 Group Policy 개체를 복원할 수 있습니다. 하지만 도메인의 모든 GPO를 한 번에 복원하는 기능은 지정된 manifest.xml 파일에 있는 가장 최근 백업을 사용하는 경우로 제한됩니다.
# Restore a single GPO from its most recent backup
Restore-GPO -Name 'GpoName' -Path '\HOSTNAMEGPOBackup' -Domain 'domain.local' -Server 'DC.domain.local'
# Restore a single GPO from a specific backup
Restore-GPO -BackupId 12345678-09ab-cdef-1234-567890abcdef -Path '\HOSTNAMEGPOBackup' -Domain 'domain.local' -Server 'DC.domain.local'
# Restore all of a domain’s GPOs from their most recent backup
Restore-GPO -All -Path '\HOSTNAMEGPOBackup' -Domain 'domain.local' -Server 'DC.domain.local'
백업에서 Group Policy 개체를 복원하면, 복원 과정의 일부로 GPO의 버전이 증가합니다. 이렇게 하면 복제(replication)가 복원된 GPO 사본을 우선하도록 강제할 수 있습니다.
버전 번호가 동기화되지 않는 이유
Restore-GPO cmdlet의 출력에는 두 세트의 버전 번호가 포함됩니다. 하나는 컴퓨터 구성용이고 다른 하나는 사용자 구성용입니다.
GPT와 GPC는 각각 자체 버전 번호를 유지하는 역할을 담당하며, 별도의 UserVersion 값과 ComputerVersion 값은 각각 사용자 구성 버전과 컴퓨터 구성 버전 번호를 기반으로 계산됩니다. 이는 버전 번호가 증가하는 방식 덕분에 가능합니다. GPO의 컴퓨터 구성은 수정될 때마다 1씩 증가하며, 사용자 구성은 수정될 때마다 65536씩 증가합니다.
이 모든 것이 필요한 이유는 앞서 설명한 것처럼, 그룹 정책 개체의 GPT와 GPC는 서로 다른 서비스에 의해 각각 별도로 복제되기 때문입니다. 그 결과 특정 도메인 컨트롤러에서 GPO의 GPT와 GPC에 해당하는 버전 번호가 동기화되지 않을 수 있으며, 그러면 해당 GPO가 처리되지 않습니다.
삭제된 GPO 복원
Restore-GPO cmdlet의 문서화된 제한 사항 중 하나는 삭제된 Group Policy 개체를 복구하는 데 사용할 수 없다는 점입니다. 이는 Active Directory에서 GPO의 GPC 구성 요소를 찾을 수 없기 때문입니다. 삭제된 GPO를 복구하려고 하면 다음과 같은 오류가 발생합니다:
하지만 먼저 GPC를 복구할 수 있다면, Restore-GPO를 사용해 삭제된 GPO를 복구할 수 있습니다. 이를 위해 Restore-ADObject cmdlet을 사용하여 Active Directory의 Active Directory Recycle Bin에서 GPO의 Active Directory 구성 요소를 완전히 복구한 다음, Restore-GPO cmdlet이 GPO를 복원할 수 있습니다:
이 프로세스는 삭제된 GPO를 복구할 수는 있지만, GPO가 삭제되기 전 존재하던 gPLink 값은 복원할 수 없습니다. 이는 해당 값들이 연결된 개체(connected objects)에서만 존재했기 때문입니다. 이 제한 사항을 안전하게 우회하는 유일한 방법은 gPLink 값을 포함하는 Active Directory의 외부 백업을 활용하는 것입니다.
GPMC 및 AGPM을 사용한 GPO 백업 및 복원
Group Policy PowerShell cmdlet만이 GPO 백업 및 복원의 유일한 옵션은 아닙니다. Microsoft는 또한 Group Policy Management 콘솔(GPMC)도 제공합니다. 이는 Group Policy 개체를 백업하고 복원하는 데 사용할 수 있는 MMC 스냅인입니다. Backup-GPO cmdlet과 마찬가지로, 단일 지정 GPO 또는 도메인의 모든 GPO를 백업할 수 있습니다. Restore-GPO cmdlet과 달리, 한 번에 한 개의 GPO만 복원할 수 있습니다.
GPMC는 백업에서 삭제된 GPO를 복원하는 방법을 제공하긴 하지만, 실제로 삭제된 GPO를 복구하는 것은 아닙니다. 실제로는 새 GPO를 생성한 뒤 백업에 들어 있는 정보를 사용해 해당 GPO를 채우는 방식입니다.
GPMC의 또 다른 장점은 GPO 백업의 내용에 대한 가시성이 향상된다는 점입니다. 다만, 백업에 있는 설정을 현재 실행 중인(라이브) GPO의 설정과 비교하는 것은 여전히 어렵습니다.
Microsoft Desktop Optimization Pack의 일부로 제공되는 Microsoft의 Advanced Group Policy Management (AGPM) 도구는 버전 관리 기능으로 GPMC를 확장하여 백업의 내용을 보고 이해하는 데 도움을 줍니다. 하지만 AGPM의 이점은 대체로 두 가지 요인에 의해 상쇄되는 경향이 있습니다. 첫째, 제대로 유지 관리되는 것 같지 않고, 둘째, 다른 제품들과 잘 “어울리지” 않는다는 평판이 있습니다(예: AGPM으로 관리되는 GPO를 AGPM 외부에서 수정하면 AGPM 데이터베이스가 손상될 수 있습니다). 그렇다고 해서 꼭 나쁜 도구라는 뜻은 아닙니다. 다만 운영 환경에 배포하기 전에 실험실 환경에서 충분히 이것저것 테스트해 보시길 권합니다.
Netwrix는 어떻게 도와드릴 수 있나요?
Netwrix Identity Recovery 는 단일 스냅샷에서 Active Directory 개체와 그룹 정책(Group Policy) 개체를 모두 백업할 수 있는 통합 웹 인터페이스를 제공하며, 백업을 검색하고 관리하고, 라이브 개체에 대한 속성 변경 사항을 롤백할 수 있고, 삭제된 GPO 및 연결된 gPLinks까지 복구할 수 있습니다.
자주 묻는 질문(FAQ)
백업에서 GPO를 복원하려면 어떤 명령을 사용할 수 있나요?
Windows PowerShell cmdlet Restore-GPO 는 단일 GPO 또는 모든 GPO를 원래 도메인으로 복원합니다.
파일에서 GPO를 가져오려면 어떻게 해야 하나요?
Advanced Group Policy Management (AGPM)에서 관리자 권한으로 필요한 권한이 있고 GPO를 CAB 파일로 내보냈다면, 제공된 단계를 따라 새 GPO 또는 기존 GPO에 GPO 설정을 가져올 수 있습니다 여기.
공유하기
더 알아보기
저자 소개
Joe Dibley
보안 연구원
Netwrix의 보안 연구원이며 Netwrix Security Research Team의 일원입니다. Joe는 Active Directory, Windows 및 다양한 엔터프라이즈 소프트웨어 플랫폼과 기술 분야의 전문가로, 새로운 보안 위험, 복잡한 공격 기법, 그리고 이에 대한 대응(완화)과 탐지 방법을 연구합니다.