# Modules\ShareSyncService.ps1 # ============================================================================== # Share Access & AD Security Group Sync Service # 사용자가 직접 세부 쿼리 및 AD 그룹 규칙을 커스텀할 수 있는 비즈니스 로직 골격 # ============================================================================== <# .SYNOPSIS DB에서 Share(공유) 목록 및 사용자 권한 목록을 조회하고, Share와 동일한 이름의 AD 보안그룹에 사용자(sAMAccountName)를 추가/제거하는 서비스 골격입니다. #> # 1. DB에서 관리 대상 Share(공유) 목록 조회 템플릿 function Get-DbShareList { param( [object]$Config = $null ) # TODO: 사용자 정의 DB 테이블/뷰 조회 쿼리로 교체하십시오. # 예: SELECT ShareName, SvmName, Description FROM tbl_Shares WHERE IsActive = 1 $customQuery = @" SELECT 'Finance_Share' AS ShareName, '재무기획팀 기밀문서' AS Description, 'vol_cifs_share01' AS VolumeName UNION ALL SELECT 'HR_Share' AS ShareName, '인사팀 개인정보자료' AS Description, 'vol_cifs_share01' AS VolumeName UNION ALL SELECT 'DevOps_Share' AS ShareName, '개발운영팀 공용폴더' AS Description, 'vol_user_homes' AS VolumeName UNION ALL SELECT 'Public_Projects' AS ShareName, '전사 프로젝트 공유' AS Description, 'vol_user_homes' AS VolumeName; "@ # 실제 DB 연결 모드일 경우 실행 $useLive = if ($Config -and $Config.MsSql) { [bool]$Config.MsSql.UseLive } else { $false } if ($useLive) { try { $timeout = if ($Config.MsSql.ConnectionTimeout) { [int]$Config.MsSql.ConnectionTimeout } else { 3 } $connStr = Build-SqlConnectionString -Server $Config.MsSql.Server -AuthType $Config.MsSql.AuthType -Username $Config.MsSql.Username -Password $Config.MsSql.Password -Timeout $timeout $conn = New-Object System.Data.SqlClient.SqlConnection($connStr) $conn.Open() $cmd = $conn.CreateCommand() $cmd.CommandText = $customQuery $adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd) $table = New-Object System.Data.DataTable $adapter.Fill($table) | Out-Null $conn.Close() $list = [System.Collections.Generic.List[PSCustomObject]]::new() foreach ($row in $table.Rows) { $list.Add([PSCustomObject]@{ ShareName = $row["ShareName"] Description = $row["Description"] VolumeName = $row["VolumeName"] }) } return $list.ToArray() } catch { Write-Warning "DB Share 조회 실패: $($_.Exception.Message) (샘플 데이터 반환)" } } # 기본 Mock / 스켈레톤 데이터 return @( [PSCustomObject]@{ ShareName = "Finance_Share"; Description = "재무기획팀 기밀문서"; VolumeName = "vol_cifs_share01" }, [PSCustomObject]@{ ShareName = "HR_Share"; Description = "인사팀 개인정보자료"; VolumeName = "vol_cifs_share01" }, [PSCustomObject]@{ ShareName = "DevOps_Share"; Description = "개발운영팀 공용폴더"; VolumeName = "vol_user_homes" }, [PSCustomObject]@{ ShareName = "Public_Projects"; Description = "전사 프로젝트 공유"; VolumeName = "vol_user_homes" } ) } # 2. 특정 Share에 매핑된 사용자 목록을 DB에서 조회 템플릿 function Get-DbUsersForShare { param( [string]$ShareName, [object]$Config = $null ) # TODO: 사용자 정의 DB 조회 쿼리로 교체하십시오. # 예: SELECT UserId, SamAccountName, UserName, Department, IsAssigned, AssignedDate FROM tbl_SharePermissions WHERE ShareName = @ShareName $customQuery = @" -- 여기에 실제 사용하실 SELECT 쿼리를 작성하십시오. -- 파라미터: '$ShareName' SELECT 'gdhong' AS SamAccountName, '홍길동' AS UserName, '클라우드인프라팀' AS Department, 1 AS IsAssigned, '2026-09-01' AS AssignedDate UNION ALL SELECT 'cskim' AS SamAccountName, '김철수' AS UserName, '데이터플랫폼팀' AS Department, 1 AS IsAssigned, '2026-09-10' AS AssignedDate UNION ALL SELECT 'yylee' AS SamAccountName, '이영희' AS UserName, '보안관제팀' AS Department, 0 AS IsAssigned, NULL AS AssignedDate UNION ALL SELECT 'mschoi' AS SamAccountName, '최민수' AS UserName, '개발운영팀' AS Department, 0 AS IsAssigned, NULL AS AssignedDate UNION ALL SELECT 'jhbak' AS SamAccountName, '박지훈' AS UserName, '시스템관리팀' AS Department, 1 AS IsAssigned, '2026-10-01' AS AssignedDate; "@ # 실제 DB 연결 모드일 경우 실행 $useLive = if ($Config -and $Config.MsSql) { [bool]$Config.MsSql.UseLive } else { $false } if ($useLive) { try { $timeout = if ($Config.MsSql.ConnectionTimeout) { [int]$Config.MsSql.ConnectionTimeout } else { 3 } $connStr = Build-SqlConnectionString -Server $Config.MsSql.Server -AuthType $Config.MsSql.AuthType -Username $Config.MsSql.Username -Password $Config.MsSql.Password -Timeout $timeout $conn = New-Object System.Data.SqlClient.SqlConnection($connStr) $conn.Open() $cmd = $conn.CreateCommand() $cmd.CommandText = $customQuery $adapter = New-Object System.Data.SqlClient.SqlDataAdapter($cmd) $table = New-Object System.Data.DataTable $adapter.Fill($table) | Out-Null $conn.Close() $list = [System.Collections.Generic.List[PSCustomObject]]::new() foreach ($row in $table.Rows) { $isAssigned = [bool]$row["IsAssigned"] $list.Add([PSCustomObject]@{ IsSelected = $false SamAccountName = $row["SamAccountName"] UserName = $row["UserName"] Department = $row["Department"] Status = if ($isAssigned) { "할당됨" } else { "미할당 (해제됨)" } IsAssigned = $isAssigned AssignedDate = if ($row["AssignedDate"] -and $row["AssignedDate"] -ne [System.DBNull]::Value) { $row["AssignedDate"].ToString() } else { "-" } }) } return $list.ToArray() } catch { Write-Warning "DB 사용자 권한 조회 실패: $($_.Exception.Message) (샘플 데이터 반환)" } } # 목업 및 DB 결과 파싱 return @( [PSCustomObject]@{ IsSelected = $false; SamAccountName = "gdhong"; UserName = "홍길동"; Department = "클라우드인프라팀"; Status = "할당됨"; IsAssigned = $true; AssignedDate = "2026-09-01" }, [PSCustomObject]@{ IsSelected = $false; SamAccountName = "cskim"; UserName = "김철수"; Department = "데이터플랫폼팀"; Status = "할당됨"; IsAssigned = $true; AssignedDate = "2026-09-10" }, [PSCustomObject]@{ IsSelected = $false; SamAccountName = "yylee"; UserName = "이영희"; Department = "보안관제팀"; Status = "미할당 (해제됨)"; IsAssigned = $false; AssignedDate = "-" }, [PSCustomObject]@{ IsSelected = $false; SamAccountName = "mschoi"; UserName = "최민수"; Department = "개발운영팀"; Status = "미할당 (해제됨)"; IsAssigned = $false; AssignedDate = "-" }, [PSCustomObject]@{ IsSelected = $false; SamAccountName = "jhbak"; UserName = "박지훈"; Department = "시스템관리팀"; Status = "할당됨"; IsAssigned = $true; AssignedDate = "2026-10-01" } ) } # 3. Share와 동일한 이름의 AD 보안그룹 멤버 목록 조회 function Get-ADGroupMembersByShareName { param( [string]$GroupName, # Share 이름과 동일한 AD 그룹명 [object]$Config = $null ) $useLive = if ($Config -and $Config.ActiveDirectory) { [bool]$Config.ActiveDirectory.UseLive } else { $false } if ($useLive) { try { $dc = $Config.ActiveDirectory.DomainController $user = $Config.ActiveDirectory.Username $pass = $Config.ActiveDirectory.Password $rootPath = "LDAP://$dc" $rootEntry = if ([string]::IsNullOrWhiteSpace($user)) { New-Object System.DirectoryServices.DirectoryEntry($rootPath) } else { New-Object System.DirectoryServices.DirectoryEntry($rootPath, $user, $pass) } # 그룹 찾기 $searcher = New-Object System.DirectoryServices.DirectorySearcher($rootEntry) $searcher.Filter = "(&(objectCategory=group)(sAMAccountName=$GroupName))" $groupResult = $searcher.FindOne() if ($groupResult) { $groupEntry = $groupResult.GetDirectoryEntry() $members = [System.Collections.Generic.List[PSCustomObject]]::new() foreach ($memberDn in $groupEntry.Properties["member"]) { # 멤버 DN에서 SamAccountName 추출 또는 파싱 $memberEntry = New-Object System.DirectoryServices.DirectoryEntry("LDAP://$dc/$memberDn", $user, $pass) $sam = $memberEntry.Properties["sAMAccountName"].Value $disp = $memberEntry.Properties["displayName"].Value $dept = $memberEntry.Properties["department"].Value $members.Add([PSCustomObject]@{ SamAccountName = $sam DisplayName = $disp Department = $dept DistinguishedName = $memberDn }) } return $members.ToArray() } } catch { Write-Warning "실제 AD 그룹 조회 실패: $($_.Exception.Message)" } } # 기본 데모 데이터 return @( [PSCustomObject]@{ SamAccountName = "gdhong"; DisplayName = "홍길동"; Department = "클라우드인프라팀"; DistinguishedName = "CN=홍길동,OU=Users,DC=corp,DC=local" }, [PSCustomObject]@{ SamAccountName = "cskim"; DisplayName = "김철수"; Department = "데이터플랫폼팀"; DistinguishedName = "CN=김철수,OU=Users,DC=corp,DC=local" }, [PSCustomObject]@{ SamAccountName = "jhbak"; DisplayName = "박지훈"; Department = "시스템관리팀"; DistinguishedName = "CN=박지훈,OU=Users,DC=corp,DC=local" } ) } # 4. 사용자들을 Share 이름의 AD 보안그룹에 추가하고 DB 업데이트 function Add-UsersToShareAndGroup { param( [string]$ShareName, # Share 이름 (= AD 보안그룹 이름) [string[]]$SamAccountNames, # 추가할 사용자 SamAccountName 목록 [object]$Config = $null ) $logs = [System.Collections.Generic.List[string]]::new() $logs.Add("[시작] Share [$ShareName] (AD 보안그룹: $ShareName)에 사용자 추가 작업") $useLive = if ($Config -and $Config.ActiveDirectory) { [bool]$Config.ActiveDirectory.UseLive } else { $false } if ($useLive) { $logs.Add(" -> [Live Mode] 실제 AD 및 DB 인프라 반영 모드 활성화됨") } foreach ($sam in $SamAccountNames) { # --- (A) AD 보안그룹에 사용자 객체 추가 로직 --- # TODO: 사용자의 실제 AD 환경에 맞게 추가 구현 또는 보완하십시오. # Live 모드일 경우: # $groupEntry.Properties["member"].Add($userDn) # $groupEntry.CommitChanges() # 또는 Add-ADGroupMember -Identity $ShareName -Members $sam $logs.Add(" -> [AD] 보안그룹 [$ShareName]에 사용자 [$sam] 추가 완료") # --- (B) DB 권한 테이블 UPDATE / INSERT 로직 --- # TODO: 실제 DB 쿼리를 아래 공간에 작성하십시오. # 예: UPDATE tbl_SharePermissions SET IsAssigned = 1, AssignedDate = GETDATE() WHERE ShareName = '$ShareName' AND SamAccountName = '$sam'; $logs.Add(" -> [DB] Share 권한 테이블에 [$sam] 할당 상태 갱신 완료") } $logs.Add("[완료] 총 $($SamAccountNames.Count)명 사용자 추가 및 동기화 처리 완료") return [PSCustomObject]@{ Success = $true Logs = $logs.ToArray() Message = "[$ShareName] 그룹 및 DB에 총 $($SamAccountNames.Count)명의 사용자가 추가되었습니다." } } # 5. 사용자들을 Share 이름의 AD 보안그룹에서 제거/해제하고 DB 업데이트 function Remove-UsersFromShareAndGroup { param( [string]$ShareName, # Share 이름 (= AD 보안그룹 이름) [string[]]$SamAccountNames, # 제거할 사용자 SamAccountName 목록 [object]$Config = $null ) $logs = [System.Collections.Generic.List[string]]::new() $logs.Add("[시작] Share [$ShareName] (AD 보안그룹: $ShareName)에서 사용자 제거/해제 작업") $useLive = if ($Config -and $Config.ActiveDirectory) { [bool]$Config.ActiveDirectory.UseLive } else { $false } if ($useLive) { $logs.Add(" -> [Live Mode] 실제 AD 및 DB 인프라 반영 모드 활성화됨") } foreach ($sam in $SamAccountNames) { # --- (A) AD 보안그룹에서 사용자 객체 제거 로직 --- # TODO: 사용자의 실제 AD 환경에 맞게 추가 구현 또는 보완하십시오. # Live 모드일 경우: # $groupEntry.Properties["member"].Remove($userDn) # $groupEntry.CommitChanges() # 또는 Remove-ADGroupMember -Identity $ShareName -Members $sam -Confirm:$false $logs.Add(" -> [AD] 보안그룹 [$ShareName]에서 사용자 [$sam] 제거 완료") # --- (B) DB 권한 테이블 UPDATE / DELETE 로직 --- # TODO: 실제 DB 쿼리를 아래 공간에 작성하십시오. # 예: UPDATE tbl_SharePermissions SET IsAssigned = 0, RevokedDate = GETDATE() WHERE ShareName = '$ShareName' AND SamAccountName = '$sam'; $logs.Add(" -> [DB] Share 권한 테이블에서 [$sam] 해제 상태 갱신 완료") } $logs.Add("[완료] 총 $($SamAccountNames.Count)명 사용자 제거 및 동기화 처리 완료") return [PSCustomObject]@{ Success = $true Logs = $logs.ToArray() Message = "[$ShareName] 그룹 및 DB에서 총 $($SamAccountNames.Count)명의 사용자가 제거(해제)되었습니다." } }