|
| 1 | +param ( |
| 2 | + [string]$applicationName, # The desired name of the application for your workload |
| 3 | + [string]$workloadName, # The name of the workload |
| 4 | + [string]$tenantId # The ID of the tenant where the workload dev instance will be published |
| 5 | +) |
| 6 | + |
| 7 | +function PostAADRequest { |
| 8 | + param ( |
| 9 | + [string]$url, |
| 10 | + [string]$body |
| 11 | + ) |
| 12 | + |
| 13 | + return az rest --method POST --url $url --body $body --headers "Content-Type=application/json" |
| 14 | +} |
| 15 | + |
| 16 | +function PrintInfo { |
| 17 | + param ( |
| 18 | + [string]$key, |
| 19 | + [string]$value |
| 20 | + ) |
| 21 | + $boldText = [char]27 + "[1m" |
| 22 | + $resetText = [char]27 + "[0m" |
| 23 | + Write-Host ("${boldText}$key : ${resetText}" + $value) |
| 24 | +} |
| 25 | + |
| 26 | +$loginResult = az login --allow-no-subscriptions |
| 27 | + |
| 28 | +Write-Host "------------------------------------------------" |
| 29 | +Write-Host "------------------------------------------------" |
| 30 | +Write-Host "------------------------------------------------" |
| 31 | + |
| 32 | +if (-not $applicationName) { |
| 33 | + $applicationName = Read-Host "Enter the desired application name" |
| 34 | +} |
| 35 | +if (-not $workloadName) { |
| 36 | + $workloadName = Read-Host "Enter your workload name" |
| 37 | +} |
| 38 | +if (-not $tenantId) { |
| 39 | + $tenantId = Read-Host "Enter your tenant id (tenant id of the user you are using in Fabric to develop your workload)" |
| 40 | +} |
| 41 | + |
| 42 | +$redirectUri = "http://localhost:60006/close" |
| 43 | + |
| 44 | +$FabricWorkloadControlGuid = New-Guid |
| 45 | +$Item1ReadAllGuid = New-Guid |
| 46 | +$Item1ReadWriteAllGuid = New-Guid |
| 47 | +$FabricLakehouseReadAllGuid = New-Guid |
| 48 | +$FabricLakehouseReadWriteAllGuid = New-Guid |
| 49 | + |
| 50 | +## Generate URI |
| 51 | + |
| 52 | +$length = Get-Random -Minimum 1 -Maximum 6 # Generate a random length between 1 and 5 |
| 53 | + |
| 54 | +# Generate a random string for the audience (see below) |
| 55 | +$randomString = -join ((65..90) + (97..122) | Get-Random -Count $length | ForEach-Object { [char]$_ }) |
| 56 | + |
| 57 | +# Create an audience for the application that contains 4 parts: |
| 58 | +# 1. The audience should start with api://localdevinstance. |
| 59 | +# 2. The next part should be the tenantId where the workload dev instance will be published. |
| 60 | +# 3. After that should come the wokrload name. |
| 61 | +# 4. The last part is a random string - this is optional, but we add it everytime to avoid collisions as AAD does not allow 2 applications to have the same audience. |
| 62 | +$applicationIdUri = "api://localdevinstance/" + $tenantId + "/" + $workloadName + "/" + $randomString |
| 63 | + |
| 64 | +$application = @{ |
| 65 | + displayName = $applicationName |
| 66 | + signInAudience = "AzureADMultipleOrgs" |
| 67 | + optionalClaims = @{ |
| 68 | + accessToken = @( |
| 69 | + @{ |
| 70 | + essential = $false |
| 71 | + name = "idtyp" |
| 72 | + } |
| 73 | + ) |
| 74 | + } |
| 75 | + spa = @{ |
| 76 | + redirectUris = @( |
| 77 | + $redirectUri |
| 78 | + ) |
| 79 | + } |
| 80 | + identifierUris = @($applicationIdUri) |
| 81 | + api = @{ |
| 82 | + oauth2PermissionScopes = @( # Scopes |
| 83 | + @{ |
| 84 | + adminConsentDisplayName = "FabricWorkloadControl" |
| 85 | + adminConsentDescription = "FabricWorkloadControl" |
| 86 | + value = "FabricWorkloadControl" |
| 87 | + id = $FabricWorkloadControlGuid |
| 88 | + isEnabled = $true |
| 89 | + type = "Admin" |
| 90 | + }, |
| 91 | + @{ |
| 92 | + adminConsentDisplayName = "Item1.Read.All" |
| 93 | + adminConsentDescription = "Item1.Read.All" |
| 94 | + value = "Item1.Read.All" |
| 95 | + id = $Item1ReadAllGuid |
| 96 | + isEnabled = $true |
| 97 | + type = "Admin" |
| 98 | + }, |
| 99 | + @{ |
| 100 | + adminConsentDisplayName = "Item1.ReadWrite.All" |
| 101 | + adminConsentDescription = "Item1.ReadWrite.All" |
| 102 | + value = "Item1.ReadWrite.All" |
| 103 | + id = $Item1ReadWriteAllGuid |
| 104 | + isEnabled = $true |
| 105 | + type = "Admin" |
| 106 | + }, |
| 107 | + @{ |
| 108 | + adminConsentDisplayName = "FabricLakehouse.Read.All" |
| 109 | + adminConsentDescription = "FabricLakehouse.Read.All" |
| 110 | + value = "FabricLakehouse.Read.All" |
| 111 | + id = $FabricLakehouseReadAllGuid |
| 112 | + isEnabled = $true |
| 113 | + type = "Admin" |
| 114 | + }, |
| 115 | + @{ |
| 116 | + adminConsentDisplayName = "FabricLakehouse.ReadWrite.All" |
| 117 | + adminConsentDescription = "FabricLakehouse.ReadWrite.All" |
| 118 | + value = "FabricLakehouse.ReadWrite.All" |
| 119 | + id = $FabricLakehouseReadWriteAllGuid |
| 120 | + isEnabled = $true |
| 121 | + type = "Admin" |
| 122 | + } |
| 123 | + ) |
| 124 | + preAuthorizedApplications = @( # Preauthorize |
| 125 | + @{ |
| 126 | + appId = "871c010f-5e61-4fb1-83ac-98610a7e9110" |
| 127 | + delegatedPermissionIds = @( |
| 128 | + $Item1ReadAllGuid, $Item1ReadWriteAllGuid, $FabricLakehouseReadAllGuid, $FabricLakehouseReadWriteAllGuid |
| 129 | + ) |
| 130 | + } |
| 131 | + @{ |
| 132 | + appId = "00000009-0000-0000-c000-000000000000" |
| 133 | + delegatedPermissionIds = @( |
| 134 | + $FabricWorkloadControlGuid |
| 135 | + ) |
| 136 | + } |
| 137 | + ) |
| 138 | + } |
| 139 | + requiredResourceAccess = @( # API Permissions |
| 140 | + @{ |
| 141 | + resourceAppId = "e406a681-f3d4-42a8-90b6-c2b029497af1" # Azure Storage |
| 142 | + resourceAccess = @( |
| 143 | + @{ |
| 144 | + id = "03e0da56-190b-40ad-a80c-ea378c433f7f" # user_impersonation |
| 145 | + type = "Scope" |
| 146 | + } |
| 147 | + ) |
| 148 | + }, |
| 149 | + @{ |
| 150 | + resourceAppId = "00000003-0000-0000-c000-000000000000" # Graph |
| 151 | + resourceAccess = @( |
| 152 | + @{ |
| 153 | + id = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" # User.Read |
| 154 | + type = "Scope" |
| 155 | + } |
| 156 | + ) |
| 157 | + }, |
| 158 | + @{ |
| 159 | + resourceAppId = "00000009-0000-0000-c000-000000000000" # PBI Service |
| 160 | + resourceAccess = @( |
| 161 | + @{ |
| 162 | + id = "b2f1b2fa-f35c-407c-979c-a858a808ba85" # Workspace.Read.All |
| 163 | + type = "Scope" |
| 164 | + }, |
| 165 | + @{ |
| 166 | + id = "caf40b1a-f10e-4da1-86e4-5fda17eb2b07" # Item.Execute.ALL |
| 167 | + type = "Scope" |
| 168 | + }, |
| 169 | + @{ |
| 170 | + id = "d2bc95fc-440e-4b0e-bafd-97182de7aef5" # Item.Read.All |
| 171 | + type = "Scope" |
| 172 | + }, |
| 173 | + @{ |
| 174 | + id = "7a27a256-301d-4359-b77b-c2b759d2e362" # Item.ReadWrite.All |
| 175 | + type = "Scope" |
| 176 | + }, |
| 177 | + @{ |
| 178 | + id = "02e8d710-956c-4760-b996-2e83935c2cf5" # Item.Reshare.All |
| 179 | + type = "Scope" |
| 180 | + }, |
| 181 | + @{ |
| 182 | + id = "13060bfd-9305-4ec6-8388-8916580f4fa9" # Lakehouse.Read.All |
| 183 | + type = "Scope" |
| 184 | + } |
| 185 | + ) |
| 186 | + } |
| 187 | + ) |
| 188 | +} |
| 189 | + |
| 190 | +# Convert to valid json format (escape the '"') |
| 191 | +$applicationJson = ( $application | ConvertTo-Json -Compress -Depth 10) -replace '"','\"' |
| 192 | + |
| 193 | +# Create application |
| 194 | +$result = PostAADRequest -url https://graph.microsoft.com/v1.0/applications -body $applicationJson |
| 195 | + |
| 196 | +$resultObject = $result | ConvertFrom-Json |
| 197 | + |
| 198 | +$applicationObjectId = $resultObject.id |
| 199 | + |
| 200 | +if ($null -eq $applicationObjectId) { |
| 201 | + Write-Host "Failed to fetch id of application... exiting" |
| 202 | + Exit |
| 203 | +} |
| 204 | + |
| 205 | +$applicationId = $resultObject.appId |
| 206 | + |
| 207 | +# Add secret |
| 208 | +# Get dates for creation & experation |
| 209 | +$startUtcDateTimeString = [DateTime]::UtcNow |
| 210 | +$endUtcDateTimeString = $startUtcDateTimeString.AddDays(180) |
| 211 | + |
| 212 | +$startUtcDateTimeString = $startUtcDateTimeString.ToString('u') -replace ' ', 'T' |
| 213 | +$endUtcDateTimeString = $endUtcDateTimeString.ToString('u') -replace ' ', 'T' |
| 214 | + |
| 215 | +$passwordCreds = @{ |
| 216 | + passwordCredential = @{ |
| 217 | + displayName = "SampleSecret" |
| 218 | + endDateTime = $endUtcDateTimeString |
| 219 | + startDateTime = $startUtcDateTimeString |
| 220 | + } |
| 221 | +} |
| 222 | + |
| 223 | +# Convert to valid json format (escape the '"') |
| 224 | +$passwordCredsJson = ( $passwordCreds | ConvertTo-Json -Compress -Depth 10) -replace '"','\"' |
| 225 | + |
| 226 | +$addPasswordResult = PostAADRequest -url ("https://graph.microsoft.com/v1.0/applications/" + $applicationObjectId + "/addPassword") -body $passwordCredsJson |
| 227 | +$addPasswordObject = ($addPasswordResult | ConvertFrom-Json) |
| 228 | +$secret = $addPasswordObject.secretText |
| 229 | + |
| 230 | +if ($null -eq $secret) { |
| 231 | + Write-Host "Failed to add secret, please add it manually..." |
| 232 | +} |
| 233 | + |
| 234 | +# Result |
| 235 | +$greenColor = [char]27 + "[32m" |
| 236 | + |
| 237 | +Write-Host "${greenColor}All set! Here's what you need:" |
| 238 | +Write-Host "------------------------------------------------" |
| 239 | +PrintInfo -key "ApplicationIdUri / Audience" -value $applicationIdUri |
| 240 | +PrintInfo -key "RedirectURI" -value $redirectUri |
| 241 | +PrintInfo -key "Application Id" -value $applicationId |
| 242 | +PrintInfo -key "secret" -value $secret |
| 243 | + |
| 244 | +Write-Host "------------------------------------------------" |
| 245 | +Write-Host "You can see the application here:" ("https://ms.portal.azure.com/#view/Microsoft_AAD_RegisteredApps/ApplicationMenuBlade/~/Overview/appId/" + $applicationId + "/isMSAApp~/false") |
| 246 | +Write-Host "------------------------------------------------" |
| 247 | +Write-Host ("You can consent for the application for your tenant (Valid from tenant admin only) here, wait a minute before navigating: " + "https://login.microsoftonline.com/" + $tenantId + "/adminconsent?client_id=" + $applicationId) |
0 commit comments