-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathSet-ServicePrincipalRoleInAllWorkspaces.ps1
159 lines (130 loc) · 4.77 KB
/
Set-ServicePrincipalRoleInAllWorkspaces.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
<#
.SYNOPSIS
Adds or removes a Service Principal to/from all active Workspaces in the Fabric/Power BI tenant.
.DESCRIPTION
This script adds or removes a Service Principal to/from all active Workspaces in the Fabric/Power BI tenant.
It uses the Power BI REST API to perform the operations.
.PARAMETER Action
Specifies whether to add or remove the Service Principal. Valid values are 'Add' or 'Remove'.
Default value is 'Add'.
.PARAMETER Role
Specifies the role to assign to the Service Principal. Valid values are 'Admin', 'Member', or 'Contributor'.
Default value is 'Member'.
.PARAMETER ServicePrincipalObjectId
The Object ID of the Service Principal to add or remove. The default value is retrieved from the Config.json file.
.PARAMETER WorkspaceFilter
The filter expression for which Workspaces to target. Default value is '(type eq ''Workspace'') and (state eq ''Active'')'.
.INPUTS
None - Pipeline input is not accepted.
.OUTPUTS
None - Pipeline output is not produced.
.EXAMPLE
.\Set-ServicePrincipalRoleInAllWorkspaces.ps1 -Action Add -Role Member
Adds the Service Principal as a Member to all active Workspaces.
.EXAMPLE
.\Set-ServicePrincipalRoleInAllWorkspaces.ps1 -Action Remove
Removes the Service Principal from all active Workspaces.
.LINK
[Source code](https://github.com/JamesDBartlett3/Fabric-Archive-Bot)
.LINK
[Follow the author's blog](https://datavolume.xyz)
.LINK
[Follow the author on GitHub](https://github.com/JamesDBartlett3)
.LINK
[Follow the author on LinkedIn](https://www.linkedin.com/in/jamesdbartlett3/)
.LINK
[Follow the author on Mastodon](https://techhub.social/@JamesDBartlett3)
.LINK
[Follow the author on BlueSky](https://bsky.app/profile/jamesdbartlett3.bsky.social)
#>
param (
[string][ValidateSet('Add', 'Remove')]$Action = 'Add',
[string][ValidateSet('Admin', 'Member', 'Contributor')]$Role = 'Member',
[string]$ServicePrincipalObjectId = ((Get-Content -Path (Join-Path -Path $PSScriptRoot -ChildPath 'Config.json') | ConvertFrom-Json).ServicePrincipal.ObjectId),
[string]$WorkspaceFilter = '(type eq ''Workspace'') and (state eq ''Active'')'
)
# Load Power BI Management module
if (-not (Get-Module -Name MicrosoftPowerBIMgmt.Profile)) {
Install-Module -Name MicrosoftPowerBIMgmt.Profile -Scope CurrentUser
}
Import-Module MicrosoftPowerBIMgmt.Profile
[string]$baseUrl = 'https://api.powerbi.com/v1.0/myorg/admin/groups'
$headers = $null
# Authenticate to Power BI
try {
$headers = Get-PowerBIAccessToken
}
catch {
Write-Host '🔒 Power BI Access Token required. Launching Azure Active Directory authentication dialog...'
Start-Sleep -s 1
Connect-PowerBIServiceAccount -WarningAction SilentlyContinue | Out-Null
$headers = Get-PowerBIAccessToken
if ($headers) {
Write-Host '🔑 Power BI Access Token acquired. Proceeding...'
}
else {
Write-Host '❌ Power BI Access Token not acquired. Exiting...'
exit
}
}
# Function to get all workspaces
function Get-AllWorkspaces {
param(
$Headers,
$WorkspaceFilter
)
[guid[]]$workspaceIds = @()
[int]$skip = 0
[int]$batchSize = 5000
do {
[string]$batchUri = $baseUrl + '?$filter={0}&$top={1}&$skip={2}' -f $WorkspaceFilter, $batchSize, $skip
$batch = Invoke-RestMethod -Uri $batchUri -Method GET -Headers $headers
$workspaceIds += $batch.value | Select-Object -ExpandProperty id
$skip += $batchSize
} while ($batch.value.Count -eq $batchSize)
return $workspaceIds
}
# Function to add Service Principal to a workspace
function Add-ServicePrincipalToWorkspace {
param (
[string]$WorkspaceId,
[string]$ObjectId,
[string]$Role,
$Headers
)
$url = "$baseUrl/$WorkspaceId/users"
$body = @{
identifier = $ObjectId
principalType = "App"
groupUserAccessRight = $Role
}
Invoke-RestMethod -Uri $url -Headers $Headers -Method POST -Body $body
}
# Function to remove Service Principal from a workspace
function Remove-ServicePrincipalFromWorkspace {
param (
[string]$WorkspaceId,
[string]$ObjectId,
$Headers
)
$url = "$baseUrl/$workspaceId/users/$ObjectId"
Invoke-RestMethod -Uri $url -Headers $Headers -Method DELETE
}
# Get all workspaces
$workspaces = Get-AllWorkspaces -Headers $headers -WorkspaceFilter $WorkspaceFilter
# Perform the selected action on each workspace
# TODO: Add rate limit handling
foreach ($workspace in $workspaces) {
if ($Action -eq 'Add') {
Write-Host "Adding Service Principal to workspace $workspace..."
Add-ServicePrincipalToWorkspace -WorkspaceId $workspace -ObjectId $ServicePrincipalObjectId -Role $Role -Headers $headers
}
elseif ($Action -eq 'Remove') {
Write-Host "Removing Service Principal from workspace $workspace..."
Remove-ServicePrincipalFromWorkspace -WorkspaceId $workspace -ObjectId $ServicePrincipalObjectId -Headers $headers
}
else {
Write-Error "Invalid action: $Action. Exiting..."
exit
}
}