본문 바로가기
기술자료 (KB)/Power Platform

PowerApps - [진행절차-초기] 4. Entra ID 부서에 직원 추가

by 이완주 2025. 6. 3.

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
 

 

댓글