Power Apps 으로 만든 조직도 앱과 Entra ID를 동기화 해서 사용자 및 그룹 정보를 업데이트 하려고 한다.
아래 진행절차는 아직 구현하지 않은 상태 이며 추후 필요시 내용이 수정 될 수 있다.
진행 절차를 정리하고 차례대로 구현 예정 이다.
여기서는 아래 [진행절차-초기] 4. Entra ID 부서에 직원 추가 를 구현했다.
[진행절차 - 초기]
1. Entra ID의 그룹 정보를 가져오기
2. Entra ID 그룹 만들기
Entra ID의 그룹과 조직도 앱의 그룹의 메일 주소가 같은지 확인 - Entra ID에는 그룹 이름이 존재 할 수 있음.
3. 선택한 직원의 모든 부서 확인
4. 3번에서 확인한 Entra ID 부서에 직원 추가
[진행절차 - 입사]
1. 직원의 소속그룹을 확인하여 그룹 멤버 추가
[진행절차 - 조직 변경]
1. 조직 부서 이름이 변경되면 Entra ID 그룹의 이름이 변경
2. 직원의 소속그룹을 변경하면 기존 그룹에서 멤버 제거, 선택된 그룹에 멤버 추가
[진행절차 - 퇴사]
1. 기존 그룹에서 멤버를 제거한다.
위에 단계에서 Entra ID에 그룹을 만들고 사용자가 소속될 그룹을 확인 하는 작업을 수행했다.
여기서는 Entra ID 에 만들어진 그룹에 사용자를 멤버로 추가하는 것을 정리하도록 하겠다.
초기 작업이라 그룹을 만들고 멤버가 없다는 가정하에 일괄 등록하는 과정을 기술한다.
사용자를 그룹에 넣기 위해서는 아래 형식으로 입력하면 그룹에 사용자를 추가할 수 있다.
Office365그룹.AddMemberToGroup(GroupID,추가할 멤버의 Mail);
이제 위에서 만든 그룹과 사용자를 확인하여 일괄 등록하도록 하겠다.
사전 준비 사항으로 Entra ID에 그룹을 조직도에 맞게 만들어 놓아야 한다.
조직도에 회사 와 부서 컬렉션이 준비 되어 있다면 두개를 하나의 컬렉션으로 만들어 그룹 한번에 만들기 버튼으로 쉽게 만들 수 있다.
그룹 리스트 만들기 - 회사 컬렉션과 부서 컬렉션을 합치는 방법
ClearCollect(col_AllGrouplists,col_CreateCompany);
Collect(col_AllGrouplists,col_CreateDepartment);
아래 단계별로 정리해 보았다.

1. Entra ID 에 그룹 만들기 - 부서 정보를 가져와 한번에 그룹을 만들 수 있다.
ForAll(
col_CreateDepartment, // col_CreateGroups 컬렉션의 각 항목을 반복
IfError( // 에러가 발생할 수 있는 작업을 실행하고, 에러 시 대체 동작 수행
MicrosoftEntraID.CreateGroup( // Microsoft Entra ID에 그룹을 생성
Name, // 그룹의 표시 이름 (예: "영업 1팀")
Description, // 그룹 설명 (예: "영업본부/영업 1팀")
mailNickname, // 메일 닉네임 (예: "PA-Sales1Team")
["Unified"], // 그룹 유형: "Unified"는 Microsoft 365 그룹을 의미
true, // MailEnabled: 메일 기능 사용 (Microsoft 365 그룹은 true)
true // SecurityEnabled: 보안 기능 사용 (Microsoft 365 그룹은 true여야 함)
),
Blank() // 에러 발생 시 아무 동작도 하지 않고 조용히 넘어감
)
)
2. Entra ID 그룹 정보 가져오기
Entra ID의 그룹 정보를 가져오려면 한번에 100개까지만 가져올 수 있다.
100개 이상을 가져오기 위해 Timer를 사용하여 반복하여 값을 가져옴
// 모든 그룹 데이터를 저장할 컬렉션을 초기화
Clear(col_groups);
// 첫 번째 페이지의 그룹 데이터 요청
Set(var_response, Office365그룹.ListGroups());
// 첫 번째 페이지의 데이터를 컬렉션에 저장
Collect(col_groups, var_response.value);
// 다음 페이지가 있을 경우, skip token 추출하여 저장
Set(
var_nextSkipToken,
If(
!IsBlank(var_response.'@odata.nextLink'), // 다음 페이지 링크가 존재하는 경우
Last(Split(var_response.'@odata.nextLink', "=")).Value, // 링크에서 토큰 값 추출
Blank() // 다음 페이지가 없으면 빈 값
)
);
// 자동 반복 플래그 설정 (true로 설정하여 반복 로직이 실행되도록)
Set(var_loadingMoreGroups, true);
// 다음 페이지가 존재하면 다음 페이지 요청 및 데이터 추가 수집
If(
!IsBlank(var_nextSkipToken),
// 다음 페이지 그룹 데이터 요청
Set(
var_response,
Office365그룹.ListGroups({ '$skiptoken': var_nextSkipToken })
);
// 가져온 그룹 데이터를 기존 컬렉션에 추가
Collect(col_groups, var_response.value);
// 다음 페이지 링크가 있는 경우 skip token 갱신, 없으면 Blank로 설정
Set(
var_nextSkipToken,
If(
!IsBlank(var_response.'@odata.nextLink'),
Last(Split(var_response.'@odata.nextLink', "=")).Value,
Blank()
)
)
,
// 다음 페이지가 없으면 자동 반복 종료
Set(var_loadingMoreGroups, false)
);
// 이 아래는 다음 페이지가 있을 때만 수동으로 호출되는 부분
// 다음 페이지 토큰이 존재할 경우에만 실행
If(
!IsBlank(var_nextSkipToken),
// 다음 페이지의 그룹 데이터를 가져옴
Set(
var_response,
Office365그룹.ListGroups({ '$skiptoken': var_nextSkipToken })
);
// 응답으로 받은 그룹 데이터를 기존 그룹 목록에 추가
Collect(col_groups, var_response.value);
// 다음 페이지가 있는 경우 skip token을 갱신, 없으면 빈 값으로 설정
Set(
var_nextSkipToken,
If(
!IsBlank(var_response.'@odata.nextLink'), // 다음 페이지 링크가 있는지 확인
Last(Split(var_response.'@odata.nextLink', "=")).Value, // 링크에서 skiptoken 추출
Blank() // 다음 페이지가 없으면 종료
)
)
)
Timer 컨트롤 설정
| Duration | 200 (0.2초) |
| Repeat | true |
| AutoStart | false |
| Start | var_loadingMoreGroups |
3. PA- 그룹 가져오기
- Entra ID의 그룹 정보 중 mailNickname이 PA- 로 시작하는 그룹 정보만 컬렉션으로 저장
ClearCollect(col_CreatedEntraIDGroup,Filter(col_groups,StartsWith(mailNickname,"PA-")))
4. 모든 그룹 정보의 mailNickname
- 사용자의 정보를 가져와 모든 소속 그룹의 mailNickname을 사용자 별로 정리
ClearCollect(
col_UserGroups, // 최종적으로 사용자와 소속 그룹 정보를 담을 컬렉션을 초기화 및 생성
ForAll(
col_employee, // 모든 사용자에 대해 반복
With(
{
empMail: mail, // 현재 사용자의 이메일 저장
empDept: Department, // 현재 사용자의 부서명 저장
currentDept: LookUp(col_CreateDepartment, Name = Department), // 부서명으로 해당 부서 정보 조회
deptLevel: LookUp(col_CreateDepartment, Name = Department).Level // 해당 부서의 계층 레벨 (1~6) 조회
},
With(
{
levels: Sequence(deptLevel, 1, 1)
// 해당 부서의 레벨 수만큼 시퀀스 생성 (예: Level 4라면 [1,2,3,4])
},
AddColumns(
levels, // 시퀀스 [1,2,...]을 기반으로 각각의 레벨에 대해 행 추가
Mail, empMail, // 현재 사용자 이메일을 각 행에 추가
GroupMailNickname,
LookUp(
col_CreateDepartment, // 부서 목록 중에서
StartsWith(
OrderNo,
Left(
currentDept.OrderNo,
2 + 5 * (Value - 1) // OrderNo 앞부분으로 상위 부서들 식별
)
) && Level = Value, // 현재 반복 중인 레벨 값과 같은 부서만 추출
mailNickname // 해당 부서의 mailNickname 추출
)
)
)
)
)
)
5. 사용자를 Office365 그룹에 넣기
- 사용자가 소속된 mailNickname 값으로 그룹에 넣기
// 중첩 테이블 접근 예시
ForAll(
col_UserGroups,
ForAll(
Value, // Value는 내부 테이블
With(
{
userRecord: LookUp(Office365사용자.SearchUser({searchTerm: Mail}), Mail = Mail),
groupID: LookUp(
col_CreatedEntraIDGroup,
mailNickname = GroupMailNickname
).id
},
If(
!IsBlank(userRecord) && !IsBlank(groupID),
Office365그룹.AddMemberToGroup(groupID, Mail)
)
)
)
)
스크린 코드 - 화면 전체 코드 정리
Screens:
EntraID Add group members:
Properties:
Fill: =RGBA(255, 255, 255, 1)
LoadingSpinnerColor: =RGBA(0, 120, 212, 1)
Children:
- gal_SearchGroupLists_3:
Control: Gallery@2.15.0
Variant: BrowseLayout_Vertical_TwoTextOneImageVariant_ver5.0
Properties:
BorderColor: =RGBA(245, 245, 245, 1)
Height: =672
Items: |+
=col_CreatedEntraIDGroup
TemplateSize: =106
Width: =359
X: =474
Y: =77
Children:
- lbl_SG_Name_3:
Control: Label@2.5.1
Properties:
BorderColor: =RGBA(0, 0, 0, 1)
Color: =RGBA(96, 94, 92, 1)
DisabledColor: =RGBA(161, 159, 157, 1)
Font: =Font.'Segoe UI'
FontWeight: =If(ThisItem.IsSelected, FontWeight.Semibold, FontWeight.Normal)
Height: =21
OnSelect: =Select(Parent)
PaddingBottom: =0
PaddingLeft: =12
PaddingRight: =0
PaddingTop: =0
Size: =12
Text: =ThisItem.displayName
VerticalAlign: =VerticalAlign.Top
Width: =227
X: =4
Y: =19
- rec_SG_Separator_3:
Control: Rectangle@2.3.0
Properties:
BorderColor: =RGBA(0, 0, 0, 0)
Fill: =RGBA(255, 255, 255, 1)
Height: =8
OnSelect: =Select(Parent)
Width: =Parent.TemplateWidth
Y: =Parent.TemplateHeight - Self.Height
- rec_SG_Selected_3:
Control: Rectangle@2.3.0
Properties:
BorderColor: =RGBA(0, 0, 0, 0)
Fill: =RGBA(0, 120, 212, 1)
Height: =Parent.TemplateHeight - rec_SG_Separator_3.Height
OnSelect: =Select(Parent)
Visible: =ThisItem.IsSelected
Width: =4
- lbl_SG_ID_3:
Control: Label@2.5.1
Properties:
BorderColor: =RGBA(0, 0, 0, 1)
Color: =RGBA(96, 94, 92, 1)
DisabledColor: =RGBA(161, 159, 157, 1)
Font: =Font.'Segoe UI'
FontWeight: =If(ThisItem.IsSelected, FontWeight.Semibold, FontWeight.Normal)
Height: =33
OnSelect: =Select(Parent)
PaddingBottom: =0
PaddingLeft: =12
PaddingRight: =0
PaddingTop: =0
Size: =12
Text: =ThisItem.id
VerticalAlign: =VerticalAlign.Top
Width: =359
Y: =73
- lbl_SG_mail_3:
Control: Label@2.5.1
Properties:
BorderColor: =RGBA(0, 0, 0, 1)
Color: =RGBA(96, 94, 92, 1)
DisabledColor: =RGBA(161, 159, 157, 1)
Font: =Font.'Segoe UI'
FontWeight: =If(ThisItem.IsSelected, FontWeight.Semibold, FontWeight.Normal)
Height: =70
OnSelect: =Select(Parent)
PaddingBottom: =0
PaddingLeft: =0
PaddingRight: =0
PaddingTop: =0
Size: =12
Text: =ThisItem.mail
VerticalAlign: =VerticalAlign.Top
Width: =163
X: =196
Y: =3
- lbl_SG_securityEnabled_3:
Control: Label@2.5.1
Properties:
BorderColor: =RGBA(0, 0, 0, 1)
Color: =RGBA(96, 94, 92, 1)
DisabledColor: =RGBA(161, 159, 157, 1)
Font: =Font.'Segoe UI'
FontWeight: =If(ThisItem.IsSelected, FontWeight.Semibold, FontWeight.Normal)
Height: =28
OnSelect: =Select(Parent)
PaddingBottom: =0
PaddingLeft: =0
PaddingRight: =0
PaddingTop: =0
Size: =12
Text: =ThisItem.mailNickname
VerticalAlign: =VerticalAlign.Top
Width: =158
X: =20
Y: =42
- btn_CreateGroups_3:
Control: Classic/Button@2.2.0
Properties:
BorderColor: =RGBA(0, 0, 0, 0)
BorderStyle: =BorderStyle.None
Color: =RGBA(255, 255, 255, 1)
DisabledBorderColor: =RGBA(0, 0, 0, 0)
DisabledColor: =RGBA(161, 159, 157, 1)
DisabledFill: =RGBA(242, 242, 241, 0)
Fill: =RGBA(0, 120, 212, 1)
Font: =Font.'Segoe UI'
Height: =37
HoverBorderColor: =RGBA(0, 0, 0, 0)
HoverColor: =RGBA(255, 255, 255, 1)
HoverFill: =RGBA(16, 110, 190, 1)
OnSelect: =ClearCollect(col_CreatedEntraIDGroup,Filter(col_groups,StartsWith(mailNickname,"PA-")))
PressedBorderColor: =RGBA(0, 69, 120, 1)
PressedColor: =RGBA(255, 255, 255, 1)
PressedFill: =RGBA(16, 110, 190, 1)
RadiusBottomLeft: =0
RadiusBottomRight: =0
RadiusTopLeft: =0
RadiusTopRight: =0
Size: =13
Text: ="PA- 그룹 가져오기"
Width: =238
X: =474
Y: =22
- btn_CreateCollect_8:
Control: Classic/Button@2.2.0
Properties:
BorderColor: =RGBA(0, 0, 0, 0)
BorderStyle: =BorderStyle.None
Color: =RGBA(255, 255, 255, 1)
DisabledBorderColor: =RGBA(0, 0, 0, 0)
DisabledColor: =RGBA(161, 159, 157, 1)
DisabledFill: =RGBA(242, 242, 241, 0)
Fill: =RGBA(0, 120, 212, 1)
Font: =Font.'Segoe UI'
Height: =39
HoverBorderColor: =RGBA(0, 0, 0, 0)
HoverColor: =RGBA(255, 255, 255, 1)
HoverFill: =RGBA(16, 110, 190, 1)
OnSelect: |-
=ClearCollect(col_employee,
{name:"이 완주",mail:"wjlee@globalsoft.co.kr",Department:"영업본부", Company:"글로벌소프트"},
{name:"홍 길동",mail:"gdhong-1@globalsoft.co.kr",Department:"영업1팀", Company:"글로벌소프트"},
{name:"홍 길순",mail:"gshong-3@globalsoft.co.kr",Department:"영업1파트", Company:"글로벌소프트"},
{name:"김 영업",mail:"yuKim@globalsoft.co.kr",Department:"영업1파트-1-1-1", Company:"글로벌소프트"}
)
PressedBorderColor: =RGBA(0, 69, 120, 1)
PressedColor: =RGBA(255, 255, 255, 1)
PressedFill: =RGBA(16, 110, 190, 1)
RadiusBottomLeft: =0
RadiusBottomRight: =0
RadiusTopLeft: =0
RadiusTopRight: =0
Size: =13
Text: ="사용자 컬렉션 만들기"
Width: =212
X: =7
Y: =22
- Gallery2_1:
Control: Gallery@2.15.0
Variant: BrowseLayout_Vertical_TwoTextOneImageVariant_ver5.0
Properties:
BorderColor: =RGBA(245, 245, 245, 1)
Height: =186
Items: =col_employee
TemplateSize: =96
Width: =348
X: =7
Y: =72
Children:
- Title2_14:
Control: Label@2.5.1
Properties:
BorderColor: =RGBA(0, 0, 0, 1)
Color: =RGBA(50, 49, 48, 1)
DisabledColor: =RGBA(161, 159, 157, 1)
Font: =Font.'Segoe UI'
FontWeight: =If(ThisItem.IsSelected, FontWeight.Semibold, FontWeight.Normal)
Height: =Self.Size * 1.8
OnSelect: =Select(Parent)
PaddingBottom: =0
PaddingLeft: =12
PaddingRight: =0
PaddingTop: =0
Size: =14
Text: =ThisItem.name
VerticalAlign: =VerticalAlign.Top
Width: =Parent.TemplateWidth - 173
X: =39
Y: =12
- Subtitle2_9:
Control: Label@2.5.1
Properties:
BorderColor: =RGBA(0, 0, 0, 1)
Color: =RGBA(96, 94, 92, 1)
DisabledColor: =RGBA(161, 159, 157, 1)
Font: =Font.'Segoe UI'
FontWeight: =If(ThisItem.IsSelected, FontWeight.Semibold, FontWeight.Normal)
Height: =Self.Size * 1.8
OnSelect: =Select(Parent)
PaddingBottom: =0
PaddingLeft: =12
PaddingRight: =0
PaddingTop: =0
Size: =12
Text: =ThisItem.mail
VerticalAlign: =VerticalAlign.Top
Width: =Title2_14.Width
X: =39
Y: =37
- Separator2_6:
Control: Rectangle@2.3.0
Properties:
BorderColor: =RGBA(0, 0, 0, 0)
Fill: =RGBA(255, 255, 255, 1)
Height: =8
OnSelect: =Select(Parent)
Width: =Parent.TemplateWidth
Y: =Parent.TemplateHeight - Self.Height
- Rectangle2_6:
Control: Rectangle@2.3.0
Properties:
BorderColor: =RGBA(0, 0, 0, 0)
Fill: =RGBA(0, 120, 212, 1)
Height: =Parent.TemplateHeight - Separator2_6.Height
OnSelect: =Select(Parent)
Visible: =ThisItem.IsSelected
Width: =4
- Title2_15:
Control: Label@2.5.1
Properties:
BorderColor: =RGBA(0, 0, 0, 1)
Color: =RGBA(50, 49, 48, 1)
DisabledColor: =RGBA(161, 159, 157, 1)
Font: =Font.'Segoe UI'
FontWeight: =If(ThisItem.IsSelected, FontWeight.Semibold, FontWeight.Normal)
Height: =25
OnSelect: =Select(Parent)
PaddingBottom: =0
PaddingLeft: =12
PaddingRight: =0
PaddingTop: =0
Size: =14
Text: =ThisItem.Department
VerticalAlign: =VerticalAlign.Top
Width: =193
X: =185
Y: =12
- Button5:
Control: Classic/Button@2.2.0
Properties:
BorderColor: =RGBA(0, 0, 0, 0)
BorderStyle: =BorderStyle.None
Color: =RGBA(255, 255, 255, 1)
DisabledBorderColor: =RGBA(0, 0, 0, 0)
DisabledColor: =RGBA(161, 159, 157, 1)
DisabledFill: =RGBA(242, 242, 241, 0)
Fill: =RGBA(0, 120, 212, 1)
Font: =Font.'Segoe UI'
HoverBorderColor: =RGBA(0, 0, 0, 0)
HoverColor: =RGBA(255, 255, 255, 1)
HoverFill: =RGBA(16, 110, 190, 1)
OnSelect: "=ClearCollect(\r\n col_UserGroups, // 최종적으로 사용자와 소속 그룹 정보를 담을 컬렉션을 초기화 및 생성\r\n\r\n ForAll(\r\n col_employee, // 모든 사용자에 대해 반복\r\n\r\n With(\r\n {\r\n empMail: mail, // 현재 사용자의 이메일 저장\r\n empDept: Department, // 현재 사용자의 부서명 저장\r\n currentDept: LookUp(col_CreateDepartment, Name = Department), // 부서명으로 해당 부서 정보 조회\r\n deptLevel: LookUp(col_CreateDepartment, Name = Department).Level // 해당 부서의 계층 레벨 (1~6) 조회\r\n },\r\n\r\n With(\r\n {\r\n levels: Sequence(deptLevel, 1, 1) \r\n // 해당 부서의 레벨 수만큼 시퀀스 생성 (예: Level 4라면 [1,2,3,4])\r\n },\r\n\r\n AddColumns(\r\n levels, // 시퀀스 [1,2,...]을 기반으로 각각의 레벨에 대해 행 추가\r\n\r\n Mail, empMail, // 현재 사용자 이메일을 각 행에 추가\r\n\r\n GroupMailNickname, \r\n LookUp(\r\n col_CreateDepartment, // 부서 목록 중에서\r\n \r\n StartsWith(\r\n OrderNo, \r\n Left(\r\n currentDept.OrderNo, \r\n 2 + 5 * (Value - 1) // OrderNo 앞부분으로 상위 부서들 식별\r\n )\r\n ) && Level = Value, // 현재 반복 중인 레벨 값과 같은 부서만 추출\r\n\r\n mailNickname // 해당 부서의 mailNickname 추출\r\n )\r\n )\r\n )\r\n )\r\n )\r\n)\r\n"
PressedBorderColor: =RGBA(0, 69, 120, 1)
PressedColor: =RGBA(255, 255, 255, 1)
PressedFill: =RGBA(16, 110, 190, 1)
RadiusBottomLeft: =0
RadiusBottomRight: =0
RadiusTopLeft: =0
RadiusTopRight: =0
Size: =10
Text: ="사용자가 포함된 그룹의 mailNickname"
Width: =223
X: =998
Y: =459
- Button8:
Control: Classic/Button@2.2.0
Properties:
BorderColor: =RGBA(0, 0, 0, 0)
BorderStyle: =BorderStyle.None
Color: =RGBA(255, 255, 255, 1)
DisabledBorderColor: =RGBA(0, 0, 0, 0)
DisabledColor: =RGBA(161, 159, 157, 1)
DisabledFill: =RGBA(242, 242, 241, 0)
Fill: =RGBA(0, 120, 212, 1)
Font: =Font.'Segoe UI'
HoverBorderColor: =RGBA(0, 0, 0, 0)
HoverColor: =RGBA(255, 255, 255, 1)
HoverFill: =RGBA(16, 110, 190, 1)
OnSelect: "=// 중첩 테이블 접근 예시\r\nForAll(\r\n col_UserGroups,\r\n ForAll(\r\n Value, // Value는 내부 테이블\r\n With(\r\n {\r\n userRecord: LookUp(Office365사용자.SearchUser({searchTerm: Mail}), Mail = Mail),\r\n groupID: LookUp(\r\n col_CreatedEntraIDGroup,\r\n mailNickname = GroupMailNickname\r\n ).id\r\n },\r\n \r\n If(\r\n !IsBlank(userRecord) && !IsBlank(groupID),\r\n Office365그룹.AddMemberToGroup(groupID, Mail)\r\n )\r\n ) \r\n \r\n ) \r\n)\r\n\r\n\r\n/*\r\n// 중첩 테이블 접근 예시\r\nForAll(\r\n col_UserGroups,\r\n ForAll(\r\n Value, // Value는 내부 테이블\r\n With(\r\n {\r\n userRecord: LookUp(Office365사용자.SearchUser({searchTerm: Mail}), Mail = Mail),\r\n groupID: LookUp(\r\n col_CreatedEntraIDGroup,\r\n mailNickname = GroupMailNickname\r\n ).id\r\n },\r\n With({\r\n isAlreadyMember: !IsBlank(\r\n LookUp(\r\n Office365그룹.ListGroupMembers(groupID).value,\r\n Mail = Mail\r\n )\r\n )},\r\n If(\r\n !IsBlank(userRecord) && !IsBlank(groupID) && !isAlreadyMember,\r\n Office365그룹.AddMemberToGroup(groupID, Mail)\r\n )\r\n ) \r\n \r\n ) \r\n )\r\n)\r\n*/"
PressedBorderColor: =RGBA(0, 69, 120, 1)
PressedColor: =RGBA(255, 255, 255, 1)
PressedFill: =RGBA(16, 110, 190, 1)
RadiusBottomLeft: =0
RadiusBottomRight: =0
RadiusTopLeft: =0
RadiusTopRight: =0
Size: =10
Text: ="사용자를 그룹에 넣기"
Width: =223
X: =1001
Y: =596
- Label4:
Control: Label@2.5.1
Properties:
BorderColor: =RGBA(0, 0, 0, 0)
BorderStyle: =BorderStyle.None
BorderThickness: =2
Color: =RGBA(50, 49, 48, 1)
DisabledBorderColor: =RGBA(0, 0, 0, 0)
DisabledColor: =RGBA(161, 159, 157, 1)
FocusedBorderThickness: =4
Font: =Font.'Segoe UI'
Text: |+
=LookUp(col_CreatedEntraIDGroup,mailNickname="PA-Sales").id
Visible: =false
Width: =351
X: =937
Y: =688
- gal_Department_3:
Control: Gallery@2.15.0
Variant: BrowseLayout_Vertical_TwoTextOneImageVariant_ver5.0
Properties:
BorderColor: =RGBA(245, 245, 245, 1)
Height: =371
Items: =col_CreateDepartment
TemplateSize: =91
Width: =421
X: =7
Y: =357
Children:
- Title2_16:
Control: Label@2.5.1
Properties:
BorderColor: =RGBA(0, 0, 0, 1)
Color: =RGBA(50, 49, 48, 1)
DisabledColor: =RGBA(161, 159, 157, 1)
Font: =Font.'Segoe UI'
FontWeight: =If(ThisItem.IsSelected, FontWeight.Semibold, FontWeight.Normal)
Height: =25
OnSelect: =Select(Parent)
PaddingBottom: =0
PaddingLeft: =12
PaddingRight: =0
PaddingTop: =0
Size: =14
Text: =ThisItem.Name
VerticalAlign: =VerticalAlign.Top
Width: =157
X: =21
Y: =8
- Subtitle2_11:
Control: Label@2.5.1
Properties:
BorderColor: =RGBA(0, 0, 0, 1)
Color: =RGBA(96, 94, 92, 1)
DisabledColor: =RGBA(161, 159, 157, 1)
Font: =Font.'Segoe UI'
FontWeight: =If(ThisItem.IsSelected, FontWeight.Semibold, FontWeight.Normal)
Height: =21
OnSelect: =Select(Parent)
PaddingBottom: =0
PaddingLeft: =12
PaddingRight: =0
PaddingTop: =0
Size: =12
Text: =ThisItem.Level
VerticalAlign: =VerticalAlign.Top
Width: =139
X: =4
Y: =41
- Separator2_7:
Control: Rectangle@2.3.0
Properties:
BorderColor: =RGBA(0, 0, 0, 0)
Fill: =RGBA(255, 255, 255, 1)
Height: =8
OnSelect: =Select(Parent)
Width: =Parent.TemplateWidth
Y: =Parent.TemplateHeight - Self.Height
- Rectangle2_7:
Control: Rectangle@2.3.0
Properties:
BorderColor: =RGBA(0, 0, 0, 0)
Fill: =RGBA(0, 120, 212, 1)
Height: =Parent.TemplateHeight - Separator2_7.Height
OnSelect: =Select(Parent)
Visible: =ThisItem.IsSelected
Width: =4
- Title2_17:
Control: Label@2.5.1
Properties:
BorderColor: =RGBA(0, 0, 0, 1)
Color: =RGBA(50, 49, 48, 1)
DisabledColor: =RGBA(161, 159, 157, 1)
Font: =Font.'Segoe UI'
FontWeight: =If(ThisItem.IsSelected, FontWeight.Semibold, FontWeight.Normal)
Height: =25
OnSelect: =Select(Parent)
PaddingBottom: =0
PaddingLeft: =12
PaddingRight: =0
PaddingTop: =0
Size: =14
Text: =ThisItem.Description
VerticalAlign: =VerticalAlign.Top
Width: =272
X: =143
Y: =8
- Title2_18:
Control: Label@2.5.1
Properties:
BorderColor: =RGBA(0, 0, 0, 1)
Color: =RGBA(50, 49, 48, 1)
DisabledColor: =RGBA(161, 159, 157, 1)
Font: =Font.'Segoe UI'
FontWeight: =If(ThisItem.IsSelected, FontWeight.Semibold, FontWeight.Normal)
Height: =25
OnSelect: =Select(Parent)
PaddingBottom: =0
PaddingLeft: =12
PaddingRight: =0
PaddingTop: =0
Size: =14
Text: =ThisItem.mailNickname
VerticalAlign: =VerticalAlign.Top
Width: =397
X: =24
Y: =58
- Subtitle2_12:
Control: Label@2.5.1
Properties:
BorderColor: =RGBA(0, 0, 0, 1)
Color: =RGBA(96, 94, 92, 1)
DisabledColor: =RGBA(161, 159, 157, 1)
Font: =Font.'Segoe UI'
FontWeight: =If(ThisItem.IsSelected, FontWeight.Semibold, FontWeight.Normal)
Height: =23
OnSelect: =Select(Parent)
PaddingBottom: =0
PaddingLeft: =12
PaddingRight: =0
PaddingTop: =0
Size: =12
Text: =ThisItem.OrderNo
VerticalAlign: =VerticalAlign.Top
Width: =380
X: =35
Y: =39
- btn_CreateCollect_9:
Control: Classic/Button@2.2.0
Properties:
BorderColor: =RGBA(0, 0, 0, 0)
BorderStyle: =BorderStyle.None
Color: =RGBA(255, 255, 255, 1)
DisabledBorderColor: =RGBA(0, 0, 0, 0)
DisabledColor: =RGBA(161, 159, 157, 1)
DisabledFill: =RGBA(242, 242, 241, 0)
Fill: =RGBA(0, 120, 212, 1)
Font: =Font.'Segoe UI'
Height: =39
HoverBorderColor: =RGBA(0, 0, 0, 0)
HoverColor: =RGBA(255, 255, 255, 1)
HoverFill: =RGBA(16, 110, 190, 1)
OnSelect: |-
=ClearCollect(col_CreateDepartment,
{Name:"영업본부",mailNickname:"PA-Sales",Description : "영업본부", OrderNo: "10100030000000000000000000000000", Level:1},
{Name:"영업1팀",mailNickname:"PA-Sales-Sales1Team",Description : "영업본부/영업1팀", OrderNo: "10100031000400000000000000000000", Level:2},
{Name:"영업1파트",mailNickname:"PA-Sales-Sales1Team",Description : "영업본부/영업1팀/영업1파트", OrderNo: "10100031000410001000000000000000", Level:3},
{Name:"영업1파트-1",mailNickname:"PA-Sales-Sales1Team-Sales1",Description : "영업본부/영업1팀/영업1파트/영업1파트-1", OrderNo: "10100031000410001100010000000000", Level:4},
{Name:"영업1파트-1-1",mailNickname:"PA-Sales-Sales1Team-Sales1-1",Description : "영업본부/영업1팀/영업1파트/영업1파트-1/영업1파트-1-1", OrderNo: "10100031000410001100011000100000", Level:5},
{Name:"영업1파트-1-1-1",mailNickname:"PA-Sales-Sales1Team-Sales1-1-1",Description : "영업본부/영업1팀/영업1파트/영업1파트-1/영업1파트-1-1/영업1파트-1-1-1", OrderNo: "10100031000410001100011000110001", Level:6}
)
PressedBorderColor: =RGBA(0, 69, 120, 1)
PressedColor: =RGBA(255, 255, 255, 1)
PressedFill: =RGBA(16, 110, 190, 1)
RadiusBottomLeft: =0
RadiusBottomRight: =0
RadiusTopLeft: =0
RadiusTopRight: =0
Size: =13
Text: ="부서 컬렉션 만들기"
Width: =238
X: =7
Y: =303
- btn_CreateGroups_4:
Control: Classic/Button@2.2.0
Properties:
BorderColor: =RGBA(0, 0, 0, 0)
BorderStyle: =BorderStyle.None
Color: =RGBA(255, 255, 255, 1)
DisabledBorderColor: =RGBA(0, 0, 0, 0)
DisabledColor: =RGBA(161, 159, 157, 1)
DisabledFill: =RGBA(242, 242, 241, 0)
Fill: =RGBA(0, 120, 212, 1)
Font: =Font.'Segoe UI'
Height: =39
HoverBorderColor: =RGBA(0, 0, 0, 0)
HoverColor: =RGBA(255, 255, 255, 1)
HoverFill: =RGBA(16, 110, 190, 1)
OnSelect: |-
=ForAll(
col_CreateDepartment, // col_CreateGroups 컬렉션의 각 항목을 반복
IfError( // 에러가 발생할 수 있는 작업을 실행하고, 에러 시 대체 동작 수행
MicrosoftEntraID.CreateGroup( // Microsoft Entra ID에 그룹을 생성
Name, // 그룹의 표시 이름 (예: "영업 1팀")
Description, // 그룹 설명 (예: "영업본부/영업 1팀")
mailNickname, // 메일 닉네임 (예: "PA-Sales1Team")
["Unified"], // 그룹 유형: "Unified"는 Microsoft 365 그룹을 의미
true, // MailEnabled: 메일 기능 사용 (Microsoft 365 그룹은 true)
true // SecurityEnabled: 보안 기능 사용 (Microsoft 365 그룹은 true여야 함)
),
Blank() // 에러 발생 시 아무 동작도 하지 않고 조용히 넘어감
)
)
PressedBorderColor: =RGBA(0, 69, 120, 1)
PressedColor: =RGBA(255, 255, 255, 1)
PressedFill: =RGBA(16, 110, 190, 1)
RadiusBottomLeft: =0
RadiusBottomRight: =0
RadiusTopLeft: =0
RadiusTopRight: =0
Size: =10
Text: ="그룹 한번에 만들기"
Width: =223
X: =1000
Y: =59
- btn_100Over_4:
Control: Classic/Button@2.2.0
Properties:
BorderColor: =RGBA(0, 0, 0, 0)
BorderStyle: =BorderStyle.None
Color: =RGBA(255, 255, 255, 1)
DisabledBorderColor: =RGBA(0, 0, 0, 0)
DisabledColor: =RGBA(161, 159, 157, 1)
DisabledFill: =RGBA(242, 242, 241, 0)
Fill: =RGBA(0, 120, 212, 1)
Font: =Font.'Segoe UI'
HoverBorderColor: =RGBA(0, 0, 0, 0)
HoverColor: =RGBA(255, 255, 255, 1)
HoverFill: =RGBA(16, 110, 190, 1)
OnSelect: |
=// 모든 그룹 데이터를 저장할 컬렉션을 초기화
Clear(col_groups);
// 첫 번째 페이지의 그룹 데이터 요청
Set(var_response, Office365그룹.ListGroups());
// 첫 번째 페이지의 데이터를 컬렉션에 저장
Collect(col_groups, var_response.value);
// 다음 페이지가 있을 경우, skip token 추출하여 저장
Set(
var_nextSkipToken,
If(
!IsBlank(var_response.'@odata.nextLink'), // 다음 페이지 링크가 존재하는 경우
Last(Split(var_response.'@odata.nextLink', "=")).Value, // 링크에서 토큰 값 추출
Blank() // 다음 페이지가 없으면 빈 값
)
);
// 자동 반복 플래그 설정 (true로 설정하여 반복 로직이 실행되도록)
Set(var_loadingMoreGroups, true);
// 다음 페이지가 존재하면 다음 페이지 요청 및 데이터 추가 수집
If(
!IsBlank(var_nextSkipToken),
// 다음 페이지 그룹 데이터 요청
Set(
var_response,
Office365그룹.ListGroups({ '$skiptoken': var_nextSkipToken })
);
// 가져온 그룹 데이터를 기존 컬렉션에 추가
Collect(col_groups, var_response.value);
// 다음 페이지 링크가 있는 경우 skip token 갱신, 없으면 Blank로 설정
Set(
var_nextSkipToken,
If(
!IsBlank(var_response.'@odata.nextLink'),
Last(Split(var_response.'@odata.nextLink', "=")).Value,
Blank()
)
)
,
// 다음 페이지가 없으면 자동 반복 종료
Set(var_loadingMoreGroups, false)
);
// 이 아래는 다음 페이지가 있을 때만 수동으로 호출되는 부분
// 다음 페이지 토큰이 존재할 경우에만 실행
If(
!IsBlank(var_nextSkipToken),
// 다음 페이지의 그룹 데이터를 가져옴
Set(
var_response,
Office365그룹.ListGroups({ '$skiptoken': var_nextSkipToken })
);
// 응답으로 받은 그룹 데이터를 기존 그룹 목록에 추가
Collect(col_groups, var_response.value);
// 다음 페이지가 있는 경우 skip token을 갱신, 없으면 빈 값으로 설정
Set(
var_nextSkipToken,
If(
!IsBlank(var_response.'@odata.nextLink'), // 다음 페이지 링크가 있는지 확인
Last(Split(var_response.'@odata.nextLink', "=")).Value, // 링크에서 skiptoken 추출
Blank() // 다음 페이지가 없으면 종료
)
)
)
PressedBorderColor: =RGBA(0, 69, 120, 1)
PressedColor: =RGBA(255, 255, 255, 1)
PressedFill: =RGBA(16, 110, 190, 1)
RadiusBottomLeft: =0
RadiusBottomRight: =0
RadiusTopLeft: =0
RadiusTopRight: =0
Size: =10
Text: ="그룹 100개 이상"
Width: =145
X: =1000
Y: =182
- Timer_GroupLists_4:
Control: Timer@2.1.0
Properties:
AutoStart: =true
BorderColor: =RGBA(0, 120, 212, 1)
BorderStyle: =BorderStyle.None
Color: =RGBA(255, 255, 255, 1)
DisabledBorderColor: =RGBA(242, 242, 241, 0)
DisabledColor: =RGBA(161, 159, 157, 1)
DisabledFill: =RGBA(242, 242, 241, 0)
Duration: =200
Fill: =RGBA(0, 120, 212, 1)
Font: =Font.'Segoe UI'
Height: =43
HoverBorderColor: =RGBA(16, 110, 190, 1)
HoverColor: =RGBA(255, 255, 255, 1)
HoverFill: =RGBA(16, 110, 190, 1)
PressedBorderColor: =RGBA(16, 110, 190, 1)
PressedColor: =RGBA(255, 255, 255, 1)
PressedFill: =RGBA(16, 110, 190, 1)
Repeat: =true
Size: =10
Start: =var_loadingMoreGroups
Text: ="Timer"
Width: =65
X: =1157
Y: =179
- btn_CreateGroups_5:
Control: Classic/Button@2.2.0
Properties:
BorderColor: =RGBA(0, 0, 0, 0)
BorderStyle: =BorderStyle.None
Color: =RGBA(255, 255, 255, 1)
DisabledBorderColor: =RGBA(0, 0, 0, 0)
DisabledColor: =RGBA(161, 159, 157, 1)
DisabledFill: =RGBA(242, 242, 241, 0)
Fill: =RGBA(0, 120, 212, 1)
Font: =Font.'Segoe UI'
Height: =37
HoverBorderColor: =RGBA(0, 0, 0, 0)
HoverColor: =RGBA(255, 255, 255, 1)
HoverFill: =RGBA(16, 110, 190, 1)
OnSelect: =ClearCollect(col_CreatedEntraIDGroup,Filter(col_groups,StartsWith(mailNickname,"PA-")))
PressedBorderColor: =RGBA(0, 69, 120, 1)
PressedColor: =RGBA(255, 255, 255, 1)
PressedFill: =RGBA(16, 110, 190, 1)
RadiusBottomLeft: =0
RadiusBottomRight: =0
RadiusTopLeft: =0
RadiusTopRight: =0
Size: =10
Text: ="PA- 그룹 가져오기"
Width: =222
X: =1001
Y: =332
- Label6:
Control: Label@2.5.1
Properties:
BorderColor: =RGBA(0, 0, 0, 0)
BorderStyle: =BorderStyle.None
BorderThickness: =2
Color: =RGBA(50, 49, 48, 1)
DisabledBorderColor: =RGBA(0, 0, 0, 0)
DisabledColor: =RGBA(161, 159, 157, 1)
FocusedBorderThickness: =4
Font: =Font.'Segoe UI'
Height: =72
Size: =10
Text: |-
="Entra ID 에 그룹 만들기
- 부서 정보를 가져와 한번에 그룹을 만들 수 있다."
Width: =221
X: =1001
Y: =98
- Label6_1:
Control: Label@2.5.1
Properties:
BorderColor: =RGBA(0, 0, 0, 0)
BorderStyle: =BorderStyle.None
BorderThickness: =2
Color: =RGBA(50, 49, 48, 1)
DisabledBorderColor: =RGBA(0, 0, 0, 0)
DisabledColor: =RGBA(161, 159, 157, 1)
FocusedBorderThickness: =4
Font: =Font.'Segoe UI'
Height: =100
Size: =10
Text: |-
="Entra ID 그룹 정보 가져오기
- Entra ID의 그룹 정보를 가져오려면 한번에 100개까지만 가져올 수 있다.
100개 이상을 가져오기 위해 Timer를 사용하여 반복하여 값을 가져옴
"
Width: =221
X: =1000
Y: =223
- Label6_2:
Control: Label@2.5.1
Properties:
BorderColor: =RGBA(0, 0, 0, 0)
BorderStyle: =BorderStyle.None
BorderThickness: =2
Color: =RGBA(50, 49, 48, 1)
DisabledBorderColor: =RGBA(0, 0, 0, 0)
DisabledColor: =RGBA(161, 159, 157, 1)
FocusedBorderThickness: =4
Font: =Font.'Segoe UI'
Height: =80
Size: =10
Text: |-
="PA- 그룹 가져오기
- Entra ID의 그룹 정보 중 mailNickname이 PA- 로 시작하는 그룹 정보만 컬렉션으로 저장
"
Width: =221
X: =1002
Y: =370
- Label6_3:
Control: Label@2.5.1
Properties:
BorderColor: =RGBA(0, 0, 0, 0)
BorderStyle: =BorderStyle.None
BorderThickness: =2
Color: =RGBA(50, 49, 48, 1)
DisabledBorderColor: =RGBA(0, 0, 0, 0)
DisabledColor: =RGBA(161, 159, 157, 1)
FocusedBorderThickness: =4
Font: =Font.'Segoe UI'
Height: =80
Size: =10
Text: |-
="모든 그룹 정보의 mailNickname
- 사용자의 정보를 가져와 모든 소속 그룹의 mailNickname을 사용자 별로 정리
"
Width: =221
X: =998
Y: =502
- Label6_4:
Control: Label@2.5.1
Properties:
BorderColor: =RGBA(0, 0, 0, 0)
BorderStyle: =BorderStyle.None
BorderThickness: =2
Color: =RGBA(50, 49, 48, 1)
DisabledBorderColor: =RGBA(0, 0, 0, 0)
DisabledColor: =RGBA(161, 159, 157, 1)
FocusedBorderThickness: =4
Font: =Font.'Segoe UI'
Height: =80
Size: =10
Text: |-
="사용자를 Office365 그룹에 넣기
- 사용자가 소속된 mailNickname 값으로 그룹에 넣기
"
Width: =221
X: =1003
Y: =636
댓글