Windows PowerShell셸 사용 권한

Don Jones

이 기사의 코드 다운로드: PowerShell2008_02.exe (151KB)

Windows PowerShell에 대해 이야기하다 보면 사용 권한에 대해, 특히 셸을 통해 사용 권한 변경을 자동화할 수 있는지 여부와 그 방법에 대한 질문을 자주 받습니다. 파일 사용 권한에 대한 질문이 가장 많고 디렉터리와 레지스트리 사용 권한에 대한 질문도 꽤 많습니다. 사용 권한 그리고 거의 모든

명령줄 또는 스크립팅 인터페이스(Windows PowerShellTM과 VBScript 포함)에 대해 제가 드릴 수 있는 이야기에는 긍정적인 점도 있고 부정적인 점도 있습니다.

부정적인 점은 Windows®의 사용 권한은 태생적으로 복잡하며 Windows PowerShell에서 이를 해결할 수 있는 부분이 많지 않다는 점입니다. Windows 운영 체제에는 파일 시스템, Active Directory®, 레지스트리 및 거의 모든 부분에 사용 권한과 관련된 여러 개의 개체가 있다는 점에서 문제가 시작됩니다.

우선 디렉터리 개체, 파일 또는 폴더와 같은 리소스가 있습니다. 다음으로는 리소스에 연결되는 ACL(액세스 제어 목록) 개체가 있습니다. ACL은 하나 이상의 ACE(액세스 제어 항목) 개체로 구성됩니다. ACE는 기본적으로 보안 주체(또 다른 개체인 사용자 또는 그룹)를 사용 권한(예: 읽기 또는 모든 권한) 및 허용 또는 거부 상태와 연결합니다. 따라서 리소스, ACL, ACE, 주체 및 사용 권한 등 다섯 개의 개체가 있는 셈입니다.

또한 리소스 유형마다 사용 권한 유형이 다르다는 점 때문에 사용 권한은 더욱 복잡해집니다. 예를 들어 디렉터리 개체에는 개별 개체 특성에 대한 액세스를 제어하는 복잡한 사용 권한이 있습니다. 이에 비하면 파일 사용 권한은 비교적 덜 복잡합니다.

또한 기술적으로 볼 때 감사의 측면에서는 이러한 복잡함이 배가됩니다. 실제로 각 리소스에는 두 개의 ACL이 있습니다. 우선 리소스에 대한 액세스를 제어하는 DACL(임의 ACL)이 있습니다. 그리고 리소스에 대한 감사를 제어하는 SACL(보안 ACL)도 있습니다. 이러한 사용 권한을 다루려면 꽤 복잡해 보이는 여러 프로그래밍 개체를 다뤄야 하며 이 작업을 단순화할 수 있는 방법은 Windows PowerShell과 같은 셸을 이용하는 방법뿐입니다.

.NET Framework에 의한 제한

추가 정보

검색 가능한 cmdlet 라이브러리를 포함하여 Windows PowerShell에 대한 추가적인 리소스를 보고 Don Jones 및 다른 Windows PowerShell 전문가의 의견을 들어 보려면 www.PowerShellCommunity.org를 방문하십시오.

Windows PowerShell의 특성 때문에 상황은 조금 더 복잡해집니다. Microsoft® .NET Framework를 기반으로 하는 Windows PowerShell에서는 .NET Framework의 기본 클래스를 사용하여 사용 권한을 나타내고 관련 작업을 처리합니다. 이러한 기본 .NET Framework 클래스는 소프트웨어 개발자에게 세밀하고 정확한 사용 권한 제어 기능을 제공하도록 설계되었습니다. 물론 "세밀하고 정확한"이라는 말은 정보가 매우 많다는 것을 의미하며 "매우 복잡하다"는 의미가 되기도 합니다.

또한 .NET Framework에서 모든 Windows 리소스 유형의 사용 권한을 나타내는 클래스를 제공하는 것은 아닙니다. 예를 들어 .NET Framework에서는 파일 보안을 조작할 수 있는 클래스를 제공하지만 공유 폴더의 보안을 다룰 수 있는 클래스는 제공하지 않습니다. 따라서 Windows 리소스 유형의 사용 권한 중에는 Windows PowerShell에서 조작할 수 없는 것이 있습니다. 요약하자면 Windows PowerShell의 기능은 .NET Framework에서 제공하는 기능으로 제한됩니다.

셸의 사용 권한

Windows PowerShell에서의 사용 권한 관리는 Get-ACL 및 Set-ACL의 두 cmdlet에서 파생됩니다. Get-ACL은 리소스에서 ACL을 가져옵니다. 그런 다음에는 필요에 따라 ACL을 수정하고 Set-ACL을 사용하여 이를 다시 리소스에 쓸 수 있습니다. 두 cmdlet 모두 제네릭이며 PSDrive 공급자의 Windows PowerShell 시스템에 의존합니다. 따라서 해당 리소스 유형을 인식할 수 있고 해당 리소스 유형의 사용 권한을 수정할 수 있는 PSDrive 공급자가 있으면 이 두 ACL cmdlet은 이론적으로 모든 리소스 유형을 다룰 수 있습니다. Windows PowerShell에 포함된 FileSystem 및 Registry PSDrive 공급자는 두 ACL cmdlet을 통한 사용 권한 관리를 지원합니다. 다른 PSDrive 공급자는 이를 지원하지 않을 수 있습니다.

그림 1의 샘플 스크립트를 사용하여 시작 디렉터리, 보안 주체 및 사용 권한을 지정할 수 있습니다. 그런 다음 스크립트는 해당 주체에 대해 지정된 사용 권한을 지정된 디렉터리 내의 모든 파일과 폴더에 적용합니다. 스크립트는 하위 디렉터리에서도 같은 작업을 반복합니다.

Figure 1 디렉터리의 파일 및 폴더에 주체에 대한 사용 권한 적용

#ChangeACL.ps1
$Right="FullControl"

#The possible values for Rights are 
# ListDirectory, ReadData, WriteData 
# CreateFiles, CreateDirectories, AppendData 
# ReadExtendedAttributes, WriteExtendedAttributes, Traverse
# ExecuteFile, DeleteSubdirectoriesAndFiles, ReadAttributes 
# WriteAttributes, Write, Delete 
# ReadPermissions, Read, ReadAndExecute 
# Modify, ChangePermissions, TakeOwnership
# Synchronize, FullControl

$StartingDir=Read-Host "What directory do you want to start at?"
$Principal=Read-Host "What security principal do you want to grant" `
"$Right to? `n Use format domain\username or domain\group"

#define a new access rule.
#note that the $rule line has been artificially broken for print purposes.
#it needs to be one line. the online version of the script is properly
#formatted.
$rule=new-object System.Security.AccessControl.FileSystemAccessRule
($Principal,$Right,"Allow")

foreach ($file in $(Get-ChildItem $StartingDir -recurse)) {
  $acl=get-acl $file.FullName
 
  #Add this access rule to the ACL
  $acl.SetAccessRule($rule)
  
  #Write the changes to the object
  set-acl $File.Fullname $acl
  }

이 스크립트의 핵심은 변수 $rule에 새 액세스 규칙을 정의하는 데 있습니다. 이렇게 하기 위해 필자는 Windows PowerShell에서의 사용 권한 관리 중 가장 복잡한 부분 중 하나인 "원시" .NET Framework 클래스를 사용합니다. 그런 후 스크립트는 Get-ACL을 사용하여 각 파일과 폴더에서 차례로 ACL을 가져오고, ACL의 SetAccessRule 메서드를 사용하여 새 규칙을 적용하고, Set-ACL을 사용하여 수정된 ACL을 다시 리소스에 씁니다.

ACL에서 ACE를 제거하는 등의 더 복잡한 작업이 더 필요하기는 하지만 이 부분은 실제로 그렇게 복잡하지 않습니다. 필자 생각으로는 ACL을 가져오고, 규칙을 정의하고, ACL을 수정하고, ACL을 쓰는 등의 많은 단계가 수반된다는 점 때문에 복잡해 보이는 것 같습니다. 하나의 명령으로 한 번에 모든 작업을 깔끔하게 처리할 수는 없지요. 또한 여러 파일의 ACL을 수정하려고 하기 때문에 모든 파일과 폴더에 실제로 액세스하기 위한 Get-ChildItem을 사용하여 모든 단계를 foreach 루프에 래핑해야 했습니다.

가장 쉬운 방법

이달의 Cmdlet: Get-QADUser

Active Directory를 관리한다면 이 cmdlet이 반드시 필요합니다. 이 cmdlet은 Windows PowerShell에서 기본적으로 제공되지는 않지만 무료로 다운로드할 수 있는 Quest Software의 ActiveRoles Management Shell for Active Directory에 포함되어 있습니다(www.quest.com/activeroles-server/arms.aspx).

스냅인을 설치한 뒤에는 Get-QADUser를 사용하여 디렉터리에서 사용자 개체를 가져올 수 있습니다. 물론 cmdlet을 실행하기만 하면 모든 사용자가 반환되지만 이 기능은 대부분의 관리 작업에서 그다지 쓸모가 없습니다. 하지만 이 cmdlet을 사용할 때 필터링 조건을 지정할 수 있습니다. 이 조건은 도메인 컨트롤러에 적용되어 실제로 원하는 사용자만 Windows PowerShell에 반환되도록 합니다. 먼저 모든 사용자를 가져온 다음 이를 Where-Object cmdlet으로 필터링하는 방법보다 훨씬 빠른 방법입니다. 예를 들어 Get-QADUser -l Redmond를 지정하면 "l" 특성에 "Redmond"가 포함된 사용자만 반환됩니다. 여기서 "l" 특성은 위치(locality)를 의미하며 GUI에서 도시로 나열됩니다. 이렇게 한 다음 이 사용자들을 다른 cmdlet으로 파이핑하여 HTML 보고서를 생성하거나, 그룹에 배치하거나, 삭제할 수 있습니다.

필자는 이 예제가 복잡하지 않다고 생각하지만 대다수 관리자는 더 간단하게 사용 권한을 다룰 수 있는 방법을 선호한다는 점을 알고 있습니다. 아마도 폴더 집합에서 특정 사용자 그룹을 한 번에 제거하고 싶지만 그림 1에 보이는 다단계 스크립트를 작성하고 싶지 않을 것입니다.

다행히 Windows PowerShell에서는 사용 권한을 다룰 수 있는 좀 더 간단한 방법을 제공하며 이 방법에 이미 익숙한 사람도 많을 것입니다.

Windows PowerShell을 이용하면 시행 착오 때문에 지쳐서 포기할 일은 없습니다. 다양한 유형의 사용 권한을 더 간단하게 다루기 위한 방법을 제공하기 위해 설계된 Dsacls.exe, Cacls.exe 및 Xcacls.exe와 같은 명령줄 도구를 사용할 수 있습니다. 이러한 명령줄 유틸리티는 구문이 Windows PowerShell cmdlet에서 사용되는 표준화된 구문과 완전히 다르지만 더 이상 이전 cmd.exe 셸에서 사용할 때처럼 명령줄에서 특별한 방식으로 사용할 필요가 없습니다. 또한 Windows PowerShell을 사용하여 이들 유틸리티를 자동화할 수 있습니다.

Windows PowerShell 내에서 구식의 명령줄 유틸리티를 사용하는 것은 잘못되었다고 주장하는 사람들이 있습니다. 필자는 이들을 "순수주의자"라고 부르겠습니다. 필자는 이런 논리에 그다지 동의하지 않습니다. 필자에게는 원하는 작업을 수행하는 것이 중요하며 이를 할 수 있는 가장 쉬운 방법이 10년 된 명령줄 유틸리티를 사용하는 것이라면 기꺼이 사용하겠습니다. "더 순수"한 것처럼 보인다는 이유만으로 특정한 방법으로 작업하기 위해 시간을 더 투자하고 싶지는 않습니다. Microsoft Windows PowerShell 팀도 이와 비슷한 태도를 취합니다. 기존 도구가 작업에 적합하다면 Windows PowerShell의 셸 안에서 해당 도구를 사용할 수 있습니다. 이미 있는 도구를 활용하지 않을 이유가 없기 때문입니다.

그림 2의 스크립트는 필자의 책인 Windows PowerShell: TFM(SAPIEN Press, 2006)에서 발췌한 것으로 Windows PowerShell을 사용하여 Cacls.exe를 자동화합니다. 이 스크립트는 설명을 위해 보여 드리는 것이며, 실제 자동화 도구에 이용하려면 적절하게 조정을 해야 합니다. 하지만 이 스크립트는 Windows PowerShell 스크립트로 정보를 수집하고 이 정보를 사용하여 Cacls.exe를 "네이티브" Windows PowerShell 명령처럼 시작하는 방법을 보여 줍니다. 이 스크립트에서는 사용자에게 요청하여 정보를 수집하지만 파일이나 데이터베이스에서 매개 변수를 읽을 수도 있습니다.

Figure 2 Cacls.exe 자동화

#SetPermsWithCACLS.ps1
# CACLS rights are usually
# F = FullControl
# C = Change
# R = Readonly
# W = Write

$StartingDir=Read-Host "What directory do you want to start at?"
$Right=Read-Host "What CACLS right do you want to grant? Valid choices are F, C, R or W"
Switch ($Right) {
  "F" {$Null}
  "C" {$Null}
  "R" {$Null}
  "W" {$Null}
  default {
    Write-Host -foregroundcolor "Red" `
    `n $Right.ToUpper() " is an invalid choice. Please Try again."`n
    exit
  }
}

$Principal=Read-Host "What security principal do you want to grant?" `
"CACLS right"$Right.ToUpper()"to?" `n `
"Use format domain\username or domain\group"

$Verify=Read-Host `n "You are about to change permissions on all" `
"files starting at"$StartingDir.ToUpper() `n "for security"`
"principal"$Principal.ToUpper() `
"with new right of"$Right.ToUpper()"."`n `
"Do you want to continue? [Y,N]"

if ($Verify -eq "Y") {

 foreach ($file in $(Get-ChildItem $StartingDir -recurse)) {
  #display filename and old permissions
  write-Host -foregroundcolor Yellow $file.FullName
  #uncomment if you want to see old permissions
  #CACLS $file.FullName
  
  #ADD new permission with CACLS
  CACLS $file.FullName /E /P "${Principal}:${Right}" >$NULL
  
  #display new permissions
  Write-Host -foregroundcolor Green "New Permissions"
  CACLS $file.FullName
 }
}

성공적인 사용 권한 다루기

Windows PowerShell에서는 단순한 범용 사용 권한 관리 기능을 제공하는 네이티브 cmdlet을 제공하지 못하기 때문에 한계가 있다는 의견을 들은 적이 있습니다. 필자는 여기에 동의하지 않습니다. 우선 이것은 강력한 UNIX 환경을 사용하는 관리자의 의견인 경우가 많으며, Windows 사용 권한 시스템은 실제로 UNIX에서 사용하는 것보다 훨씬 복잡하다는 점 때문입니다. 이러한 시스템에서는 Windows PowerShell도 복잡해집니다. 하지만 이것은 Windows PowerShell의 문제가 아닙니다.

또한 Windows PowerShell에서는 앞서 언급한 것처럼 오래되었지만 우수한 명령줄 유틸리티의 형식으로 단순화된 도구를 사용할 수 있습니다. 물론 전체 Windows 플랫폼의 사용 권한 관리를 보다 완벽하게 처리하려면 .NET Framework에 어느 정도의 확장이 필요한 것도 사실입니다. 하지만 전체적으로 보면 Windows PowerShell은 단순화된 사용 권한 관리 기능과 세밀하고 정밀한 관리 도구를 모두 제공합니다.

Don JonesTechNet Magazine의 객원 편집자이자 Windows PowerShell: TFM(SAPIEN Press, 2007)의 공동 저자입니다. Windows PowerShell 강사(www.ScriptingTraining.com 참조)이기도 한 그는 웹 사이트 www.ScriptingAnswers.com을 통해 연락할 수 있습니다.

© 2008 Microsoft Corporation 및 CMP Media, LLC. All rights reserved. 이 문서의 전부 또는 일부를 무단으로 복제하는 행위는 금지됩니다..