Lý Thuyết Cốt Lõi
1. Tạo và Quản Lý User Account
Entra ID hỗ trợ ba loại user chính: cloud-only (tạo trực tiếp trong Entra ID), synced (đồng bộ từ on-prem AD qua Entra Connect), và guest (B2B từ tenant bên ngoài). Mỗi loại có nguồn gốc danh tính (source of authority) khác nhau — ảnh hưởng đến nơi quản lý mật khẩu và thuộc tính.
- • User Principal Name (UPN): định danh đăng nhập, dạng
[email protected] - • Display Name: tên hiển thị trong M365 và Azure Portal
- • Mail: địa chỉ email thực, có thể khác UPN
- • Job Title / Department: dùng cho dynamic group rules
- • Usage Location: bắt buộc khi gán M365 license
- • Account enabled: true/false — disable không xóa user
- • Disable: block sign-in, giữ nguyên tất cả data và licenses
- • Delete: đưa vào Deleted Users 30 ngày, có thể restore
- • Restore: khôi phục trong 30 ngày, sau đó xóa vĩnh viễn
- • Reset password: Admin tự reset hoặc user dùng SSPR
- • Revoke sessions: logout tất cả thiết bị ngay lập tức
- • License assignment: gán trực tiếp hoặc qua group
2. Tạo User Hàng Loạt — Bulk Import CSV
Khi cần tạo nhiều user cùng lúc (onboarding nhân viên mới, tạo tài khoản lab, v.v.), dùng tính năng Bulk create trong Entra ID Portal hoặc lệnh az ad user create lặp với CSV. File CSV theo chuẩn Microsoft với các cột bắt buộc.
version:v1.0
Name [displayName] Required,User name [userPrincipalName] Required,Initial password [passwordProfile/password] Required,Block sign in (Yes/No) [accountEnabled] Required,First name [givenName],Last name [surname],Job title [jobTitle],Department [department],Usage location [usageLocation],Mobile phone [mobile]
Nguyen Van An,[email protected],TempP@ss2024!,No,An,Nguyen,Developer,IT,VN,0912345678
Tran Thi Binh,[email protected],TempP@ss2024!,No,Binh,Tran,Designer,Marketing,VN,0987654321
Le Van Cuong,[email protected],TempP@ss2024!,No,Cuong,Le,Manager,HR,VN,0934567890
- Entra ID → Users → Bulk operations → Bulk create
- Download CSV template để đảm bảo đúng format
- Điền dữ liệu, save file UTF-8 (không có BOM)
- Upload file → Validate → Submit
- Theo dõi trạng thái trong Bulk operation results
- • UPN đã tồn tại trong tenant → đổi UPN duy nhất
- • Password không đáp ứng complexity policy → tối thiểu 8 ký tự, chứa uppercase, lowercase, number/symbol
- • Usage location trống khi gán license → điền ISO country code (VN, US, SG...)
- • File encoding sai → dùng UTF-8, không có BOM
3. Loại Group — Security Group vs Microsoft 365 Group
Entra ID có hai loại group chính với mục đích hoàn toàn khác nhau. Chọn sai loại group sẽ dẫn đến không thể dùng cho mục đích mong muốn.
| Tiêu chí | Security Group | Microsoft 365 Group |
|---|---|---|
| Mục đích chính | Kiểm soát quyền truy cập (RBAC, app access, Azure resource) | Cộng tác (Teams, SharePoint, Planner, Outlook shared mailbox) |
| Members có thể là | Users, devices, service principals, groups (nested) | Users only (không nested group, không device) |
| Dynamic membership | Có (cần P1) | Có (cần P1) |
| Gán Azure RBAC role | Có | Không |
| Shared mailbox / calendar | Không | Có |
| Microsoft Teams | Không tạo được Teams | Mỗi Team có 1 M365 Group |
4. Dynamic Membership — Tự Động Quản Lý Thành Viên Nhóm
Dynamic membership (cần Entra ID P1) tự động thêm/xóa thành viên dựa trên thuộc tính của user hoặc device. Không cần quản trị viên can thiệp thủ công khi nhân viên đổi phòng ban hoặc vai trò.
- • Processing time: thay đổi membership có thể mất 5–60 phút để đồng bộ
- • Không thể mixed: một group chỉ dùng hoặc Assigned hoặc Dynamic — không kết hợp được
- • Validate rules: dùng "Validate rules" trong Portal để test rule trước khi lưu
- • Operators: -eq, -ne, -startsWith, -endsWith, -contains, -match, -in, -notIn, -any, -all
- • Device dynamic: có thể dùng device.deviceOSType, device.deviceManagementAppId cho dynamic device groups
department để trống, user sẽ không khớp rule user.department -eq "IT" dù họ là nhân viên IT.
Bài Tập Thực Hành (Lab)
Tạo Resource Group và Users đơn lẻ bằng Azure CLI
# Tạo Resource Group cho module 02
az group create \
--name rg-az104-m02 \
--location southeastasia \
--tags Module=02 Course=AZ-104 Environment=Lab
# Lấy domain mặc định của tenant
DOMAIN=$(az ad signed-in-user show --query userPrincipalName -o tsv | cut -d'@' -f2)
echo "Domain: $DOMAIN"
# Tạo user Developer
az ad user create \
--display-name "Dev User M02" \
--user-principal-name "devuser.m02@$DOMAIN" \
--password "Az104Lab@2024!" \
--force-change-password-next-sign-in false
# Update extended attributes qua Graph API
az rest --method PATCH \
--uri "https://graph.microsoft.com/v1.0/users/devuser.m02@$DOMAIN" \
--body '{"jobTitle":"Developer","department":"IT","city":"Hanoi"}'
# ============================================================
# Tạo user HR Manager
# ============================================================
az ad user create \
--display-name "HR Manager M02" \
--user-principal-name "hrmanager.m02@$DOMAIN" \
--password "Az104Lab@2024!" \
--force-change-password-next-sign-in false
az rest --method PATCH \
--uri "https://graph.microsoft.com/v1.0/users/hrmanager.m02@$DOMAIN" \
--body '{"jobTitle":"Manager","department":"HR","city":"Ho Chi Minh"}'
# ============================================================
# Tạo user Marketing
# ============================================================
az ad user create \
--display-name "Marketing User M02" \
--user-principal-name "marketing.m02@$DOMAIN" \
--password "Az104Lab@2024!" \
--force-change-password-next-sign-in false
az rest --method PATCH \
--uri "https://graph.microsoft.com/v1.0/users/marketing.m02@$DOMAIN" \
--body '{"jobTitle":"Designer","department":"Marketing","city":"Hanoi"}'
# Liệt kê users vừa tạo
az ad user list --filter "startswith(userPrincipalName,'devuser.m02') or startswith(userPrincipalName,'hrmanager.m02') or startswith(userPrincipalName,'marketing.m02')" \
--query '[].{UPN:userPrincipalName, Name:displayName, Dept:department}' -o table
Bulk Import Users từ CSV bằng script PowerShell & Azure CLI
DOMAIN=$(az ad signed-in-user show --query userPrincipalName -o tsv | cut -d'@' -f2)
# Tạo file CSV với dữ liệu bulk users
cat > /tmp/bulk-users-m02.csv << EOF
displayName,userPrincipalName,password,department,jobTitle,city
"Finance User 01","finance01.m02@$DOMAIN","Az104Lab@2024!","Finance","Accountant","Hanoi"
"Finance User 02","finance02.m02@$DOMAIN","Az104Lab@2024!","Finance","Analyst","Hanoi"
"Sales User 01","sales01.m02@$DOMAIN","Az104Lab@2024!","Sales","Executive","Ho Chi Minh"
"Sales User 02","sales02.m02@$DOMAIN","Az104Lab@2024!","Sales","Manager","Ho Chi Minh"
"IT User 01","ituser01.m02@$DOMAIN","Az104Lab@2024!","IT","Engineer","Hanoi"
EOF
echo "CSV created. Processing bulk users..."
# Đọc CSV và tạo từng user
tail -n +2 /tmp/bulk-users-m02.csv | while IFS=',' read -r displayName upn password dept title city; do
# Loại bỏ dấu nháy kép bao quanh nếu có
displayName=$(echo $displayName | tr -d '"')
upn=$(echo $upn | tr -d '"')
dept=$(echo $dept | tr -d '"')
title=$(echo $title | tr -d '"')
city=$(echo $city | tr -d '"')
echo "Creating: $displayName ($upn)..."
az ad user create \
--display-name "$displayName" \
--user-principal-name "$upn" \
--password "$password" \
--force-change-password-next-sign-in false \
--department "$dept" \
--job-title "$title" \
--city "$city" \
2>&1 | grep -E '"id"|"error"' | head -1
done
echo "Bulk import complete."
# Đếm số user có UPN chứa .m02@
az ad user list --query "[?contains(userPrincipalName,'.m02@')].userPrincipalName" -o tsv | wc -l
Tạo Security Group với Dynamic Membership Rule
TOKEN=$(az account get-access-token \
--resource https://graph.microsoft.com \
--query accessToken -o tsv)
# Tạo Security Group (Assigned) — cho RBAC
az ad group create \
--display-name "SG-IT-Department-M02" \
--mail-nickname "sg-it-department-m02" \
--description "Security Group - IT Department Lab M02"
# Lấy Object ID của group vừa tạo
SG_IT=$(az ad group show --group "SG-IT-Department-M02" --query id -o tsv)
echo "Security Group ID: $SG_IT"
# Thêm devuser và ituser01 vào group thủ công
DEV_ID=$(az ad user show --id "devuser.m02@$(az ad signed-in-user show --query userPrincipalName -o tsv | cut -d'@' -f2)" --query id -o tsv)
IT01_ID=$(az ad user show --id "ituser01.m02@$(az ad signed-in-user show --query userPrincipalName -o tsv | cut -d'@' -f2)" --query id -o tsv)
az ad group member add --group "SG-IT-Department-M02" --member-id $DEV_ID
az ad group member add --group "SG-IT-Department-M02" --member-id $IT01_ID
# Tạo Dynamic Security Group qua Graph API (cần P1 license)
curl -s -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"displayName": "SG-Finance-Dynamic-M02",
"description": "Dynamic group - tự động gồm tất cả user thuộc Finance department",
"mailEnabled": false,
"mailNickname": "sg-finance-dynamic-m02",
"securityEnabled": true,
"groupTypes": ["DynamicMembership"],
"membershipRule": "(user.department -eq \"Finance\")",
"membershipRuleProcessingState": "On"
}' \
"https://graph.microsoft.com/v1.0/groups" \
| python3 -c "import json,sys; d=json.load(sys.stdin); print(f'Dynamic Group created: {d[\"id\"]} | {d[\"displayName\"]}')"
# Xem thành viên group (có thể mất vài phút để dynamic rule xử lý)
echo "Waiting 60s for dynamic membership to process..."
sleep 60
FINANCE_GID=$(az ad group show --group "SG-Finance-Dynamic-M02" --query id -o tsv 2>/dev/null)
if [ -n "$FINANCE_GID" ]; then
az ad group member list --group "SG-Finance-Dynamic-M02" \
--query '[].{Name:displayName, Dept:department}' -o table
fi
(user.department -eq "Finance"). Vào Members → sau 5–10 phút phải thấy finance01.m02 và finance02.m02 được tự động thêm vào.
Gán RBAC Role cho Security Group trên Resource Group
SUB_ID=$(az account show --query id -o tsv)
SG_IT=$(az ad group show --group "SG-IT-Department-M02" --query id -o tsv)
# Gán Contributor role cho IT Security Group trên RG az104-m02
az role assignment create \
--assignee-object-id $SG_IT \
--assignee-principal-type Group \
--role "Contributor" \
--scope "/subscriptions/$SUB_ID/resourceGroups/rg-az104-m02"
# Xác nhận role assignment
az role assignment list \
--scope "/subscriptions/$SUB_ID/resourceGroups/rg-az104-m02" \
--query "[?principalType=='Group'].{Principal:principalName, Role:roleDefinitionName, Scope:scope}" \
-o table
# Kiểm tra quyền hiệu lực của một user cụ thể
DOMAIN=$(az ad signed-in-user show --query userPrincipalName -o tsv | cut -d'@' -f2)
DEV_ID=$(az ad user show --id "devuser.m02@$DOMAIN" --query id -o tsv)
az role assignment list --assignee $DEV_ID -o table
Cleanup — Dọn dẹp tài nguyên lab
DOMAIN=$(az ad signed-in-user show --query userPrincipalName -o tsv | cut -d'@' -f2)
# Xóa tất cả users .m02
for UPN in devuser.m02 hrmanager.m02 marketing.m02 finance01.m02 finance02.m02 sales01.m02 sales02.m02 ituser01.m02; do
echo "Deleting $UPN@$DOMAIN ..."
az ad user delete --id "$UPN@$DOMAIN" 2>/dev/null && echo " Deleted." || echo " Not found, skipping."
done
# Xóa Security Groups
az ad group delete --group "SG-IT-Department-M02" 2>/dev/null && echo "SG-IT-Department-M02 deleted."
az ad group delete --group "SG-Finance-Dynamic-M02" 2>/dev/null && echo "SG-Finance-Dynamic-M02 deleted."
# Xóa Resource Group
az group delete --name rg-az104-m02 --yes --no-wait
echo "Resource group rg-az104-m02 deletion initiated (async)."
Kết Quả Đầu Ra
Thành thạo tạo user qua CLI với đầy đủ thuộc tính; bulk create từ CSV script tự động hóa
Disable, delete, restore user; reset password; thu hồi session; hiểu 30-day soft delete
Chọn đúng Security Group (RBAC/quyền) vs M365 Group (cộng tác Teams/SharePoint)
Viết dynamic rule dựa trên department/jobTitle/city; hiểu processing delay và validate rule
Gán role cho group thay vì từng user riêng lẻ — scalable, dễ quản lý, best practice
Tạo dynamic group qua Microsoft Graph REST API; hiểu token-based authentication
Ứng Dụng Thực Tế
Tình huống 1: Tập đoàn sản xuất — Onboarding 200 nhân viên mới mỗi quý
HR gửi file Excel danh sách nhân viên mới, IT cần tạo tài khoản, gán quyền và license trong 1 ngày làm việc.
HR export file Excel → IT convert sang CSV chuẩn Microsoft → chạy script bash bulk create → Dynamic Group tự động gán license theo department. Toàn bộ 200 user tạo xong trong 15 phút.
Dynamic Security Group theo department → gán license group (Microsoft 365 Business Premium cho Management; Standard cho nhân viên sản xuất). Bulk create CSV với force-change-password → nhân viên tự đổi mật khẩu lần đầu đăng nhập.
Giảm thời gian onboarding từ 2 ngày xuống 15 phút. Không sai sót do thao tác thủ công. Dynamic group tự động cập nhật khi nhân viên chuyển phòng ban.
Tình huống 2: Công ty thương mại điện tử — Phân quyền theo vai trò tự động
Nhân viên Sales cần truy cập Power BI dashboard doanh thu; khi thăng chức lên Manager, cần thêm quyền Cost Management. Quản trị viên không muốn can thiệp thủ công mỗi lần thăng chức.
Tạo 2 dynamic group: SG-Sales-Staff (rule: jobTitle -eq "Executive") và SG-Sales-Manager (rule: jobTitle -eq "Manager" AND department -eq "Sales"). Khi HR cập nhật jobTitle trong AD → Entra Connect sync → dynamic group tự cập nhật.
Gán Power BI Pro license cho SG-Sales-Staff. Gán Reader role trên Azure Cost Management subscription scope cho SG-Sales-Manager. Quyền kế thừa — Manager có cả 2 nhóm quyền.
Zero-touch provisioning khi thăng chức. IT không nhận ticket "cấp thêm quyền" từ HR. License được thu hồi tự động khi nhân viên nghỉ việc (disable account → rời khỏi dynamic group).
Tình huống 3: Ngân hàng — Offboarding nhân viên nhanh và an toàn
Nhân viên nghỉ việc cần thu hồi toàn bộ quyền truy cập ngay lập tức, bao gồm M365, Azure, và ứng dụng SSO — trong khi vẫn giữ data để bàn giao.
Runbook offboarding: (1) Disable account → block sign-in ngay; (2) Revoke all refresh tokens; (3) Remove từ tất cả Assigned groups; (4) Thu hồi license; (5) Forward email về manager 30 ngày; (6) Sau 30 ngày: delete user.
az ad user update --id UPN --account-enabled false → az rest --method POST .../revokeSignInSessions. Dynamic group: khi account disabled → user.accountEnabled = false → tự rời dynamic groups có rule user.accountEnabled -eq true.
Toàn bộ access bị thu hồi trong <5 phút. Đáp ứng yêu cầu audit của ngân hàng. Data không bị mất trong 30 ngày chờ bàn giao. Dynamic group tự động — không cần IT can thiệp thủ công.