Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get-Tenants update and bugfixes #414

Merged
merged 4 commits into from
Aug 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 14 additions & 13 deletions ExecExtensionMapping/run.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,17 @@ if ($Request.Query.List) {
$Tenants = Get-Tenants
#Get available halo clients
$Table = Get-CIPPTable -TableName Extensionsconfig
$Configuration = ((Get-AzDataTableEntity @Table).config | ConvertFrom-Json).HaloPSA
$Token = Get-HaloToken -configuration $Configuration
$i = 1
$RawHaloClients = do {
$Result = Invoke-RestMethod -Uri "$($Configuration.ResourceURL)/Client?page_no=$i&page_size=999&pageinate=true" -ContentType 'application/json' -Method GET -Headers @{Authorization = "Bearer $($token.access_token)" }
$Result.clients | Select-Object * -ExcludeProperty logo
$i++
$pagecount = [Math]::Ceiling($Result.record_count / 999)
} while ($i -le $pagecount)
try {
$Configuration = ((Get-AzDataTableEntity @Table).config | ConvertFrom-Json -ErrorAction Stop).HaloPSA
$Token = Get-HaloToken -configuration $Configuration
$i = 1
$RawHaloClients = do {
$Result = Invoke-RestMethod -Uri "$($Configuration.ResourceURL)/Client?page_no=$i&page_size=999&pageinate=true" -ContentType 'application/json' -Method GET -Headers @{Authorization = "Bearer $($token.access_token)" }
$Result.clients | Select-Object * -ExcludeProperty logo
$i++
$pagecount = [Math]::Ceiling($Result.record_count / 999)
} while ($i -le $pagecount)
} catch { $RawHaloClients = @() }
$HaloClients = $RawHaloClients | ForEach-Object {
[PSCustomObject]@{
label = $_.name
Expand Down Expand Up @@ -59,12 +61,11 @@ try {
'HaloPSAName' = "$($mapping.value.label)"
}
Add-AzDataTableEntity @Table -Entity $AddObject -Force
Write-LogMessage -API $APINAME -user $request.headers.'x-ms-client-principal' -message "Added mapping for $($mapping.name)." -Sev 'Info'
Write-LogMessage -API $APINAME -user $request.headers.'x-ms-client-principal' -message "Added mapping for $($mapping.name)." -Sev 'Info'
}
$body = [pscustomobject]@{'Results' = "Successfully edited mapping table." }
$body = [pscustomobject]@{'Results' = 'Successfully edited mapping table.' }
}
}
catch {
} catch {
Write-LogMessage -API $APINAME -user $request.headers.'x-ms-client-principal' -message "mapping API failed. $($_.Exception.Message)" -Sev 'Error'
$body = [pscustomobject]@{'Results' = "Failed. $($_.Exception.Message)" }
}
Expand Down
50 changes: 40 additions & 10 deletions GraphHelper.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ function New-GraphGetRequest {
[switch]$CountOnly
)

if ((Get-AuthorisedRequest -Uri $uri -TenantID $tenantid) -or $NoAuthCheck) {
if ($NoAuthCheck -or (Get-AuthorisedRequest -Uri $uri -TenantID $tenantid)) {
if ($scope -eq 'ExchangeOnline') {
$AccessToken = Get-ClassicAPIToken -resource 'https://outlook.office365.com' -Tenantid $tenantid
$headers = @{ Authorization = "Bearer $($AccessToken.access_token)" }
Expand Down Expand Up @@ -211,7 +211,7 @@ function New-GraphGetRequest {
}

function New-GraphPOSTRequest ($uri, $tenantid, $body, $type, $scope, $AsApp, $NoAuthCheck) {
if ((Get-AuthorisedRequest -Uri $uri -TenantID $tenantid) -or $NoAuthCheck) {
if ($NoAuthCheck -or (Get-AuthorisedRequest -Uri $uri -TenantID $tenantid)) {
$headers = Get-GraphToken -tenantid $tenantid -scope $scope -AsApp $asapp
Write-Verbose "Using $($uri) as url"
if (!$type) {
Expand Down Expand Up @@ -414,17 +414,46 @@ function Get-Tenants {
}
$IncludedTenantsCache = Get-AzDataTableEntity @TenantsTable -Filter $Filter

$LastRefresh = ($IncludedTenantsCache | Where-Object { $_.customerId } | Sort-Object LastRefresh -Descending | Select-Object -First 1).LastRefresh | Get-Date
if ($LastRefresh -lt (Get-Date).Addhours(-24).ToUniversalTime()) {
if (($IncludedTenantsCache | Measure-Object).Count -gt 0) {
try {
$LastRefresh = ($IncludedTenantsCache | Where-Object { $_.customerId } | Sort-Object LastRefresh -Descending | Select-Object -First 1).LastRefresh | Get-Date -ErrorAction Stop
} catch { $LastRefresh = $false }
} else {
$LastRefresh = $false
}
if (!$LastRefresh -or $LastRefresh -lt (Get-Date).Addhours(-24).ToUniversalTime()) {
try {
Write-Host "Renewing. Cache not hit. $LastRefresh"
$TenantList = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/tenantRelationships/managedTenants/tenants?`$top=999" -tenantid $env:TenantID ) | Select-Object id, @{l = 'customerId'; e = { $_.tenantId } }, @{l = 'DefaultdomainName'; e = { [string]($_.contract.defaultDomainName) } } , @{l = 'MigratedToNewTenantAPI'; e = { $true } }, DisplayName, domains, tenantStatusInformation | Where-Object -Property defaultDomainName -NotIn $SkipListCache.defaultDomainName

} catch {
Write-Host 'probably no license for Lighthouse. Using old API.'
Write-Host "Get-Tenants - Lighthouse Error, using contract/delegatedAdminRelationship calls. Error: $($_.Exception.Message)"
[System.Collections.Generic.List[PSCustomObject]]$BulkRequests = @(
@{
id = 'Contracts'
method = 'GET'
url = "/contracts?`$top=999"
},
@{
id = 'GDAPRelationships'
method = 'GET'
url = '/tenantRelationships/delegatedAdminRelationships'
}
)

$BulkResults = New-GraphBulkRequest -Requests $BulkRequests -tenantid $TenantFilter -NoAuthCheck:$true
$Contracts = Get-GraphBulkResultByID -Results $BulkResults -ID 'Contracts' -Value
$GDAPRelationships = Get-GraphBulkResultByID -Results $BulkResults -ID 'GDAPRelationships' -Value

$ContractList = $Contracts | Select-Object id, customerId, DefaultdomainName, DisplayName, domains, @{l = 'MigratedToNewTenantAPI'; e = { $true } }, @{ n = 'delegatedPrivilegeStatus'; exp = { $CustomerId = $_.customerId; if (($GDAPRelationships | Where-Object { $_.customer.tenantId -EQ $CustomerId -and $_.status -EQ 'active' } | Measure-Object).Count -gt 0) { 'delegatedAndGranularDelegetedAdminPrivileges' } else { 'delegatedAdminPrivileges' } } } | Where-Object -Property defaultDomainName -NotIn $SkipListCache.defaultDomainName

$GDAPOnlyList = $GDAPRelationships | Where-Object { $_.status -eq 'active' -and $Contracts.customerId -notcontains $_.customer.tenantId } | Select-Object id, @{l = 'customerId'; e = { $($_.customer.tenantId) } }, @{l = 'defaultDomainName'; e = { (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/tenantRelationships/findTenantInformationByTenantId(tenantId='$($_.customer.tenantId)')" -noauthcheck $true -asApp:$true -tenant $env:TenantId).defaultDomainName } }, @{l = 'MigratedToNewTenantAPI'; e = { $true } }, @{n = 'displayName'; exp = { $_.customer.displayName } }, domains, @{n = 'delegatedPrivilegeStatus'; exp = { 'granularDelegatedAdminPrivileges' } } | Where-Object -Property defaultDomainName -NotIn $SkipListCache.defaultDomainName | Sort-Object -Property customerId -Unique

$TenantList = @($ContractList) + @($GDAPOnlyList)
}
if (!$TenantList.customerId) {
<#if (!$TenantList.customerId) {
$TenantList = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/contracts?`$top=999" -tenantid $env:TenantID ) | Select-Object id, customerId, DefaultdomainName, DisplayName, domains | Where-Object -Property defaultDomainName -NotIn $SkipListCache.defaultDomainName
}
}#>
$IncludedTenantsCache = [system.collections.generic.list[hashtable]]::new()
if ($env:PartnerTenantAvailable) {
$IncludedTenantsCache.Add(@{
Expand All @@ -450,7 +479,7 @@ function Get-Tenants {
customerId = [string]$Tenant.customerId
defaultDomainName = [string]$Tenant.defaultDomainName
displayName = [string]$Tenant.DisplayName
delegatedPrivilegeStatus = [string]$Tenant.tenantStatusInformation.delegatedPrivilegeStatus
delegatedPrivilegeStatus = [string]$Tenant.delegatedPrivilegeStatus
domains = ''
Excluded = $false
ExcludeUser = ''
Expand Down Expand Up @@ -694,7 +723,7 @@ function New-GraphBulkRequest {
$Requests
)

if ((Get-AuthorisedRequest -Uri $uri -TenantID $tenantid) -or $NoAuthCheck) {
if ($NoAuthCheck -or (Get-AuthorisedRequest -Uri $uri -TenantID $tenantid)) {
$headers = Get-GraphToken -tenantid $tenantid -scope $scope -AsApp $asapp

$URL = 'https://graph.microsoft.com/beta/$batch'
Expand All @@ -720,7 +749,8 @@ function New-GraphBulkRequest {
}

foreach ($MoreData in $ReturnedData.Responses | Where-Object { $_.body.'@odata.nextLink' }) {
$AdditionalValues = New-GraphGetRequest -ComplexFilter -uri $MoreData.body.'@odata.nextLink' -tenantid $TenantFilter
Write-Host 'Getting more'
$AdditionalValues = New-GraphGetRequest -ComplexFilter -uri $MoreData.body.'@odata.nextLink' -tenantid $TenantFilter -NoAuthCheck:$NoAuthCheck
$NewValues = [System.Collections.Generic.List[PSCustomObject]]$MoreData.body.value
$AdditionalValues | ForEach-Object { $NewValues.add($_) }
$MoreData.body.value = $NewValues
Expand Down
6 changes: 5 additions & 1 deletion ListExtensionsConfig/run.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ $APIName = $TriggerMetadata.FunctionName
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug'

$Table = Get-CIPPTable -TableName Extensionsconfig
$Body = (Get-AzDataTableEntity @Table).config | ConvertFrom-Json -Depth 10
try {
$Body = (Get-AzDataTableEntity @Table).config | ConvertFrom-Json -Depth 10 -ErrorAction Stop
} catch {
$Body = @{}
}
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = [HttpStatusCode]::OK
Expand Down
14 changes: 9 additions & 5 deletions ListNotificationConfig/run.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,23 @@ Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -m

$Table = Get-CIPPTable -TableName SchedulerConfig
$Filter = "RowKey eq 'CippNotifications' and PartitionKey eq 'CippNotifications'"
$Config = Get-AzDataTableEntity @Table -Filter $Filter | ConvertTo-Json -Depth 10 | ConvertFrom-Json -Depth 10
$config | Add-Member -NotePropertyValue @() -NotePropertyName 'logsToInclude' -Force
$Config = Get-AzDataTableEntity @Table -Filter $Filter
if ($Config) {
$Config = $Config | ConvertTo-Json -Depth 10 | ConvertFrom-Json -Depth 10 -AsHashtable
} else {
$Config = @{}
}
#$config | Add-Member -NotePropertyValue @() -NotePropertyName 'logsToInclude' -Force
$config.logsToInclude = @(([pscustomobject]$config | Select-Object * -ExcludeProperty schedule, type, tenantid, onepertenant, sendtoIntegration, partitionkey, rowkey, tenant, ETag, email, logsToInclude, Severity, Alert, Info, Error, timestamp, webhook).psobject.properties.name)
if (!$config.logsToInclude) {
$config.logsToInclude = @('None')
}
if (!$config.Severity) {
$config.Severity = @('Alert')
}
else {
} else {
$config.Severity = $config.Severity -split ','
}
$body = $Config
$body = [PSCustomObject]$Config

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
Expand Down
27 changes: 15 additions & 12 deletions Modules/CippExtensions/Private/Get-GradientToken.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,22 @@ function Get-GradientToken {
param(
$Configuration
)
$null = Connect-AzAccount -Identity
$partnerApiKey = (Get-AzKeyVaultSecret -VaultName $ENV:WEBSITE_DEPLOYMENT_ID -Name "Gradient" -AsPlainText)
$authorizationToken = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("$($configuration.vendorKey):$($partnerApiKey)"))
if ($Configuration.vendorKey) {
$null = Connect-AzAccount -Identity
$partnerApiKey = (Get-AzKeyVaultSecret -VaultName $ENV:WEBSITE_DEPLOYMENT_ID -Name 'Gradient' -AsPlainText)
$authorizationToken = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("$($configuration.vendorKey):$($partnerApiKey)"))

$headers = [hashtable]@{
'Accept' = 'application/json'
'GRADIENT-TOKEN' = $authorizationToken
}
$headers = [hashtable]@{
'Accept' = 'application/json'
'GRADIENT-TOKEN' = $authorizationToken
}

try {
return [hashtable]$headers
}
catch {
Write-Error $_.Exception.Message
try {
return [hashtable]$headers
} catch {
Write-Error $_.Exception.Message
}
} catch {
throw 'No Gradient configuration'
}
}
23 changes: 13 additions & 10 deletions Modules/CippExtensions/Private/Get-HaloToken.ps1
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
function Get-HaloToken {
[CmdletBinding()]
param (
$Configuration
$Configuration
)
$null = Connect-AzAccount -Identity
$body = @{
grant_type = 'client_credentials'
client_id = $Configuration.ClientId
client_secret = (Get-AzKeyVaultSecret -VaultName $ENV:WEBSITE_DEPLOYMENT_ID -Name "HaloPSA" -AsPlainText)
scope = 'all'
if ($Configuration.ClientId) {
$null = Connect-AzAccount -Identity
$body = @{
grant_type = 'client_credentials'
client_id = $Configuration.ClientId
client_secret = (Get-AzKeyVaultSecret -VaultName $ENV:WEBSITE_DEPLOYMENT_ID -Name 'HaloPSA' -AsPlainText)
scope = 'all'
}
$token = Invoke-RestMethod -Uri "$($Configuration.AuthURL)/token?tenant=$($Configuration.tenant)" -Method Post -Body $body -ContentType 'application/x-www-form-urlencoded'
return $token
} else {
throw 'No Halo configuration'
}
$token = Invoke-RestMethod -Uri "$($Configuration.AuthURL)/token?tenant=$($Configuration.tenant)" -Method Post -Body $body -ContentType 'application/x-www-form-urlencoded'
return $token

}
14 changes: 8 additions & 6 deletions profile.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,26 @@
# Authenticate with Azure PowerShell using MSI.
# Remove this if you are not planning on using MSI or Azure PowerShell.
Import-Module .\GraphHelper.psm1
Import-Module Az.KeyVault
Import-Module Az.Accounts
try {
Import-Module Az.KeyVault -ErrorAction Stop
} catch { $_.Exception.Message }
try {
Import-Module Az.Accounts
} catch { $_.Exception.Message }
Import-Module GraphRequests
Import-Module CippExtensions
Import-Module CippCore

try {
Disable-AzContextAutosave -Scope Process | Out-Null
}
catch {}
} catch {}

try {
if (!$ENV:SetFromProfile) {
Write-Host "We're reloading from KV"
$Auth = Get-CIPPAuthentication
}
}
catch {
} catch {
Write-LogMessage -message "Could not retrieve keys from Keyvault: $($_.Exception.Message)" -Sev 'CRITICAL'
}

Expand Down