-
Notifications
You must be signed in to change notification settings - Fork 406
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Added support folder with troubleshooting scripts * reworked readme Co-authored-by: Robin Meure <[email protected]>
- Loading branch information
1 parent
15cef76
commit f2fd855
Showing
4 changed files
with
416 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
<# | ||
.SYNOPSIS | ||
Script to test if the Applications can get an access token using the stored secrets | ||
.DESCRIPTION | ||
To make sure that the configuration which is stored in the keyvault is correct this script will | ||
1. Fetch the applicationId's from the Application Registrations | ||
2. Fetch the application secrets from the KeyVault | ||
3. Try to fetch an acces token using the combination of the AppId and AppSecret | ||
.PARAMETER ConfigFile | ||
Path to where the parameters.json is stored which was used to deploy the application. | ||
.PARAMETER TenantId | ||
TenantId (see the Azure Portal to retrieve this GUID, this is also known as the DirectoryId which can be found in the Application Registration as well) | ||
.PARAMETER BaseResourceName | ||
"Base" name of the resources (e.g. how all the resources are named) in the Resource Group, this is the same name as in the parameters.json file | ||
See https://github.com/OfficeDev/microsoft-teams-apps-company-communicator/wiki/Deployment-guide step 5), this name is used in the script to find all the components in the Resource Group | ||
.NOTES | ||
Author: Robin Meure MSFT | ||
ChangeLog: | ||
1.0.0 - Robin Meure, 2022-Feb-23 - First Release. | ||
Make sure that the account which is used to connect to the Azure environment has read access on the KeyVault secrets. | ||
Azure Portal -> Company Communicator Resource Group -> KeyVault > Access policies -> Add user to read the secrets | ||
See https://docs.microsoft.com/en-us/azure/key-vault/general/assign-access-policy?tabs=azure-portal for more information. | ||
#> | ||
|
||
[CmdletBinding(DefaultParametersetName="Variables")] | ||
Param | ||
( | ||
[Parameter( ValueFromPipeline=$true, | ||
ValueFromPipelineByPropertyName=$true, | ||
ParameterSetName="ConfigFile", | ||
HelpMessage="Load the configfile of the deployment folder.")] | ||
[switch]$ConfigFile, | ||
|
||
[Parameter( ParameterSetName="ConfigFile", | ||
HelpMessage="The path where the parameters.json which is used for the deployment is located.")] | ||
[string]$configFilePath, | ||
|
||
[Parameter( ParameterSetName="Variables", | ||
HelpMessage="The TenantId where the application is deployed.")] | ||
[string]$tenantId, | ||
[Parameter( ParameterSetName="Variables", | ||
HelpMessage="'Base' name of the resources (e.g. how all the resources are named) in the Resource Group.")] | ||
[string]$baseName | ||
) | ||
|
||
Function Get-AccessToken | ||
{ | ||
param( | ||
[Parameter(Mandatory = $true, HelpMessage = "ApplicationId")] | ||
[string] | ||
$appId, | ||
[Parameter(Mandatory = $true, HelpMessage = "ApplicationSecret")] | ||
[string] | ||
$appSecret, | ||
[Parameter(Mandatory = $true, HelpMessage = "Resource to authenticate against (e.g. https://graph.microsoft.com)")] | ||
[string] | ||
$resource, | ||
[Parameter(Mandatory = $true, HelpMessage = "Authority to receive the token from (e.g. 'https://login.microsoftonline.com/tenant/oauth2/v2.0/token'))")] | ||
$authority | ||
) | ||
|
||
$body = [string]::Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=https%3A%2F%2F{2}%2F.default", $appId, $appSecret, $resource) | ||
|
||
Write-Output ("Fetching access token using for Application: {0}." -f $appId) | ||
$token = Invoke-RestMethod -Uri $authority -Method Post -Body $body | ||
|
||
if ($token.access_token -ne $null) | ||
{ | ||
Write-Output ("Got an access token") | ||
} | ||
else | ||
{ | ||
Write-Output ("Failed to retrieve an access token") | ||
} | ||
} | ||
|
||
# check if we have a config file we're using and need to parse | ||
if ($ConfigFile) | ||
{ | ||
if ([string]::IsNullOrEmpty($configFilePath)) | ||
{ | ||
Write-Output ("No config file is set, trying to fetch the configuration from the deployment folder.") | ||
$config = Get-Content '..\deployment\parameters.json' | Out-String | ConvertFrom-Json | ||
Write-Verbose ("Found following configuration: {0}." -f $config) | ||
} | ||
else | ||
{ | ||
Write-Output ("FilePath set, trying to fetch the configuration from the specified folder.") | ||
$config = Get-Content -Path $configFilePath | Out-String | ConvertFrom-Json | ||
} | ||
# Fetching the configuration of the deployment | ||
$tenantId = $config.tenantId.Value | ||
$baseName = $config.baseResourceName.Value | ||
} | ||
|
||
|
||
|
||
# Connecting to the Azure Portal, please make sure you're connecting using the same account as for the deployment | ||
$connectionSucceeded = $false | ||
try{ | ||
$connectionSucceeded = Connect-AzAccount -Tenant $tenantId | ||
} | ||
catch{ | ||
$connectionSucceeded = $false | ||
} | ||
|
||
# if we could successfully connect to Azure, then we're going to try to fetch the App Registrations and secrets from the KeyVault | ||
if ($connectionSucceeded) | ||
{ | ||
# Fetching the App registrations with their Id's | ||
$applications = Get-AzADApplication -DisplayNameStartWith $baseName | Select-Object ApplicationId, DisplayName | ||
$graphAppId = $applications | Where-Object { $_.DisplayName -eq $baseName}| Select-Object ApplicationId -ExpandProperty ApplicationId | ||
$userAppId = $applications | Where-Object { $_.DisplayName -eq [string]::Format("{0}-users",$baseName)} | Select-Object ApplicationId -ExpandProperty ApplicationId | ||
$authorAppId = $applications | Where-Object { $_.DisplayName -eq [string]::Format("{0}-authors",$baseName)}| Select-Object ApplicationId -ExpandProperty ApplicationId | ||
|
||
# setting up keyvaultName | ||
$keyVaultName = [string]::Format("{0}{1}", $baseName,"vault") | ||
|
||
# Defining the secretNames to retrieve the actual secrets from the Keyvault | ||
$graphAppSecretName = [string]::Format("{0}{1}", $keyVaultName, "GraphAppPassword") | ||
$userAppSecretName = [string]::Format("{0}{1}", $keyVaultName, "UserAppPassword") | ||
$authorAppSecretName = [string]::Format("{0}{1}", $keyVaultName, "AuthorAppPassword") | ||
|
||
# Fetch the secrets from the KeyVault | ||
$graphAppSecret = Get-AzKeyVaultSecret -VaultName $keyVaultName -Name $graphAppSecretName -AsPlainText | ||
$userAppSecret = Get-AzKeyVaultSecret -VaultName $keyVaultName -Name $userAppSecretName -AsPlainText | ||
$authorAppSecret = Get-AzKeyVaultSecret -VaultName $keyVaultName -Name $authorAppSecretName -AsPlainText | ||
|
||
# First check the Graph App | ||
$graphAuthorityUrl = [string]::Format("https://login.microsoftonline.com/{0}/oauth2/v2.0/token", $tenantId) | ||
$graphResource = "graph.microsoft.com" | ||
|
||
Get-AccessToken -appId $graphAppId -appSecret $graphAppSecret -authority $graphAuthorityUrl -resource $graphResource | ||
|
||
# Checking the User and Author Apps | ||
$botAuthorityUrl = [string]::Format("https://login.microsoftonline.com/{0}/oauth2/v2.0/token", "botframework.com") | ||
$botResource = "api.botframework.com" | ||
|
||
Get-AccessToken -appId $userAppId -appSecret $userAppSecret -authority $botAuthorityUrl -resource $botResource | ||
Get-AccessToken -appId $authorAppId -appSecret $authorAppSecret -authority $botAuthorityUrl -resource $botResource | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
<# | ||
.SYNOPSIS | ||
Script to test if the created Applications in the Application Registration work | ||
.DESCRIPTION | ||
To make sure that the AppReg itself is working, this script is meant to test the basic AppId + AppSecret combination to see if an access token is being returned. | ||
Also, this can be used to see the App has the proper permissions granted to lookup users and/our groups. | ||
.PARAMETER TenantId | ||
TenantId (see the Azure Portal to retrieve this GUID, this is also known as the DirectoryId which can be found in the Application Registration as well) | ||
.PARAMETER AppId | ||
ApplicationId of the Graph App (main application, not the user nor the author bot App registration) | ||
.PARAMETER AppSecret | ||
Secret of the Application | ||
.PARAMETER FetchDataFromGraph | ||
When supplied, a call is done to the Graph API using the App and the access token to retrieve O365 groups and/or users | ||
.NOTES | ||
Author: Robin Meure MSFT | ||
ChangeLog: | ||
1.0.0 - Robin Meure, 2022-Feb-23 - First Release. | ||
This script does not make use of any Graph libraries/SDK's but just 'simple' Invoke-RestMethod cmdlets, | ||
this to eliminate the dependencies and/or elevated powershell sessions to install these dependencies like MSGraph | ||
#> | ||
|
||
[CmdLetBinding()] | ||
param( | ||
[Parameter(Mandatory = $true, HelpMessage = "The TenantId where the application is deployed")] | ||
[string] | ||
$tenantId, | ||
[Parameter(Mandatory = $true, HelpMessage = "The ApplicationId of the application")] | ||
[string] | ||
$AppId, | ||
[Parameter(Mandatory = $true, HelpMessage = "The Application secret of the application.")] | ||
[string] | ||
$AppSecret, | ||
[Parameter(Mandatory = $false, HelpMessage = "When provided, will call into the graph using the access token.")] | ||
[switch] | ||
$FetchDataFromGraph | ||
) | ||
|
||
$graphAuthorityUrl = [string]::Format("https://login.microsoftonline.com/{0}/oauth2/v2.0/token", $tenantId) | ||
$graphResource = "graph.microsoft.com" | ||
|
||
$body = [string]::Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=https%3A%2F%2F{2}%2F.default", $AppId, $AppSecret, $graphResource) | ||
$token = Invoke-RestMethod -Uri $graphAuthorityUrl -Method Post -Body $body | ||
|
||
if (!$token) | ||
{ | ||
Write-Warning ("No token received") | ||
} | ||
else { | ||
Write-Output ("Fetched access token using for Application: {0}." -f $appId) | ||
$graphAccessToken = $token.access_token | ||
} | ||
|
||
|
||
if ($FetchDataFromGraph) | ||
{ | ||
# This is fetching O365 groups when drafting a message as option 4 to send the message to. | ||
# https://graph.microsoft.com/v1.0/groups?$filter=groupTypes/any(c:c+eq+'Unified') | ||
|
||
# GroupMember.Read.All check | ||
$fetchGroupsUrl = [string]::Format("https://graph.microsoft.com/v1.0/groups?`$filter=groupTypes/any(c:c+eq+'Unified')") | ||
$fetchGroupsResponse = Invoke-RestMethod -Uri $fetchGroupsUrl -Headers @{Authorization = "Bearer $graphAccessToken"} -ContentType "application/json" -Method Get | ||
if ($fetchGroupsResponse -ne $null) | ||
{ | ||
Write-Output ("Fetched o365 groups using graph API for Application: {0}." -f $appId) | ||
$fetchGroupsResponse.value | Select-Object DisplayName, Id | ||
Write-Output ("---------------------------------------------------------") | ||
} | ||
|
||
# This is fetching users from AAD (e.g. used to send a message to all users (option 3 in the message ux)) | ||
# https://graph.microsoft.com/v1.0/users | ||
|
||
# User.Read.All check | ||
$fetchUsersUrl = [string]::Format("https://graph.microsoft.com/v1.0/users") | ||
$fetchUsersResponse = Invoke-RestMethod -Uri $fetchUsersUrl -Headers @{Authorization = "Bearer $graphAccessToken"} -ContentType "application/json" -Method Get | ||
if ($fetchUsersResponse -ne $null) | ||
{ | ||
Write-Output ("Fetched AAD users using graph API for Application: {0}." -f $appId) | ||
$fetchUsersResponse.value | Select-Object DisplayName, Id | ||
} | ||
} |
Oops, something went wrong.