Skip to content

Commit

Permalink
Merge pull request #50 from KelvinTegelaar/master
Browse files Browse the repository at this point in the history
[pull] master from KelvinTegelaar:master
  • Loading branch information
pull[bot] authored Jan 3, 2024
2 parents 89e50aa + eef8ed8 commit 9ce75fe
Show file tree
Hide file tree
Showing 64 changed files with 2,080 additions and 888 deletions.
9 changes: 3 additions & 6 deletions ExecScheduledCommand/run.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ Write-Host 'started task'
try {
try {
$results = & $QueueItem.command @commandParameters
}
catch {
} catch {
$results = "Task Failed: $($_.Exception.Message)"

}
Expand All @@ -31,8 +30,7 @@ try {
if ($StoredResults.Length -gt 64000 -or $task.Tenant -eq 'AllTenants') {
$StoredResults = @{ Results = 'The results for this query are too long to store in this table, or the query was meant for All Tenants. Please use the options to send the results to another target to be able to view the results. ' } | ConvertTo-Json -Compress
}
}
catch {
} catch {
$errorMessage = $_.Exception.Message
if ($task.Recurrence -gt 0) { $State = 'Failed - Planned' } else { $State = 'Failed' }
Update-AzDataTableEntity @Table -Entity @{
Expand Down Expand Up @@ -71,8 +69,7 @@ if ($task.Recurrence -le '0' -or $task.Recurrence -eq $null) {
Results = "$StoredResults"
TaskState = 'Completed'
}
}
else {
} else {
$nextRun = (Get-Date).AddDays($task.Recurrence)
$nextRunUnixTime = [int64]($nextRun - (Get-Date '1/1/1970')).TotalSeconds
Update-AzDataTableEntity @Table -Entity @{
Expand Down
73 changes: 41 additions & 32 deletions Modules/CIPPCore/Public/Entrypoints/Invoke-AddAlert.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@ Function Invoke-AddAlert {
$APIName = $TriggerMetadata.FunctionName
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug'

$Tenants = ($Request.body | Select-Object Select_*).psobject.properties.value
$Tenants = $Request.body.tenantFilter
$Table = get-cipptable -TableName 'SchedulerConfig'

$Results = foreach ($Tenant in $tenants) {
try {
$TenantID = if ($tenant -ne 'AllTenants') {
(get-tenants | Where-Object -Property defaultDomainName -EQ $Tenant).customerId
}
else {
'AllTenants'
Write-Host "Working on $Tenant"
if ($tenant -ne 'AllTenants') {
$TenantID = (get-tenants | Where-Object -Property defaultDomainName -EQ $Tenant).customerId
} else {
$TenantID = 'AllTenants'
}
if ($Request.body.SetAlerts) {
$CompleteObject = @{
Expand Down Expand Up @@ -45,45 +47,52 @@ Function Invoke-AddAlert {
RowKey = $TenantID
PartitionKey = 'Alert'
}

$Table = get-cipptable -TableName 'SchedulerConfig'
Add-CIPPAzDataTableEntity @Table -Entity $CompleteObject -Force
}
$URL = ($request.headers.'x-ms-original-url').split('/api') | Select-Object -First 1
if ($Tenant -eq 'AllTenants') {
Get-Tenants | ForEach-Object {
foreach ($eventType in $Request.body.EventTypes.value) {
} else {
$URL = ($request.headers.'x-ms-original-url').split('/api') | Select-Object -First 1
if ($Tenant -eq 'AllTenants') {
Get-Tenants | ForEach-Object {
$params = @{
TenantFilter = $_.defaultDomainName
auditLogAPI = $true
operations = ($Request.body.Operations.value -join ',')
allowedLocations = ($Request.body.AllowedLocations.value -join ',')
BaseURL = $URL
EventType = $eventType
ExecutingUser = $Request.headers.'x-ms-client-principal'
TenantFilter = $_.defaultDomainName
auditLogAPI = $true
operations = 'Audit.AzureActiveDirectory,Audit.Exchange,Audit.SharePoint,Audit.General'
BaseURL = $URL
ExecutingUser = $Request.headers.'x-ms-client-principal'
}
Push-OutputBinding -Name Subscription -Value $Params
}
}
}
else {
foreach ($eventType in $Request.body.EventTypes.value) {
$CompleteObject = @{
tenant = 'AllTenants'
type = 'webhookcreation'
RowKey = 'AllTenantsWebhookCreation'
PartitionKey = 'webhookcreation'
}
Add-CIPPAzDataTableEntity @Table -Entity $CompleteObject -Force
} else {
$params = @{
TenantFilter = $tenant
auditLogAPI = $true
operations = ($Request.body.Operations.value -join ',')
allowedLocations = ($Request.body.AllowedLocations.value -join ',')
BaseURL = $URL
EventType = $eventType
ExecutingUser = $Request.headers.'x-ms-client-principal'
TenantFilter = $tenant
auditLogAPI = $true
operations = 'Audit.AzureActiveDirectory,Audit.Exchange,Audit.SharePoint,Audit.General'
BaseURL = $URL
ExecutingUser = $Request.headers.'x-ms-client-principal'
}
New-CIPPGraphSubscription @params
}
$CompleteObject = @{
Tenant = [string]$tenant
if = [string](ConvertTo-Json -Depth 10 -Compress -InputObject $Request.body.ifs)
execution = [string](ConvertTo-Json -Depth 10 -Compress -InputObject $Request.body.do)
type = 'WebhookAlert'
RowKey = [string](New-Guid)
PartitionKey = 'WebhookAlert'
}
Add-CIPPAzDataTableEntity @Table -Entity $CompleteObject -Force

}
"Successfully added Alert for $($Tenant) to queue."
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $tenant -message "Successfully added Alert for $($Tenant) to queue." -Sev 'Info'
}
catch {
} catch {
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -tenant $tenant -message "Failed to add Alert for for $($Tenant) to queue" -Sev 'Error'
"Failed to add Alert for for $($Tenant) to queue $($_.Exception.message)"
}
Expand Down
20 changes: 11 additions & 9 deletions Modules/CIPPCore/Public/Entrypoints/Invoke-ExecGDAPInvite.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ Function Invoke-ExecGDAPInvite {
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug'

$RoleMappings = $Request.body.gdapRoles
$Results = [System.Collections.Generic.List[string]]::new()

if ($RoleMappings.roleDefinitionId -contains '62e90394-69f5-4237-9190-012177145e10') {
$AutoExtendDuration = 'PT0S'
Expand Down Expand Up @@ -48,29 +47,32 @@ Function Invoke-ExecGDAPInvite {

if ($NewRelationshipRequest.action -eq 'lockForApproval') {
$InviteUrl = "https://admin.microsoft.com/AdminPortal/Home#/partners/invitation/granularAdminRelationships/$($NewRelationship.id)"
$Uri = ([System.Uri]$TriggerMetadata.Headers.referer)
$OnboardingUrl = $Uri.AbsoluteUri.Replace($Uri.PathAndQuery, '/tenant/administration/tenant-onboarding-wizard?tableFilter=Complex: id eq {0}' -f $NewRelationship.id)

$InviteEntity = [PSCustomObject]@{
'PartitionKey' = 'invite'
'RowKey' = $NewRelationship.id
'InviteUrl' = $InviteUrl
'RoleMappings' = [string](@($RoleMappings) | ConvertTo-Json -Depth 10 -Compress)
'PartitionKey' = 'invite'
'RowKey' = $NewRelationship.id
'InviteUrl' = $InviteUrl
'OnboardingUrl' = $OnboardingUrl
'RoleMappings' = [string](@($RoleMappings) | ConvertTo-Json -Depth 10 -Compress)
}
Add-CIPPAzDataTableEntity @Table -Entity $InviteEntity

$Results.add('GDAP relationship invite created. Copy the URL below and log in as a Global Admin for the new tenant to approve the invite.')
$Message = 'GDAP relationship invite created. Log in as a Global Admin in the new tenant to approve the invite.'
} else {
$Results.add('Error creating GDAP relationship request')
$Message = 'Error creating GDAP relationship request'
}
}
} catch {
$Results.add('Error creating GDAP relationship')
$Message = 'Error creating GDAP relationship'
Write-Host "GDAP ERROR: $($_.Exception.Message)"
}

Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Created GDAP Invite - $InviteUrl" -Sev 'Info'

$body = @{
Results = @($Results)
Message = $Message
Invite = $InviteEntity
}
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using namespace System.Net

Function Invoke-ExecGraphExplorerPreset {
<#
.FUNCTIONALITY
Entrypoint
#>
[CmdletBinding()]
param($Request, $TriggerMetadata)

$APIName = $TriggerMetadata.FunctionName
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug'

$Username = ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($request.headers.'x-ms-client-principal')) | ConvertFrom-Json).userDetails
# Write to the Azure Functions log stream.
Write-Host 'PowerShell HTTP trigger function processed a request.'


switch ($Request.Body.Action) {
'Copy' {
$Id = (New-Guid).Guid
}
'Save' {
$Id = $Request.Body.values.reportTemplate.value
}
'Delete' {
$Id = $Request.Body.values.reportTemplate.value
}
}

$params = $Request.Body.values | Select-Object endpoint, '$filter', '$select', '$count', '$expand', '$search', NoPagination, '$top', IsShared
$Preset = [PSCustomObject]@{
PartitionKey = 'Preset'
RowKey = [string]$Id
id = [string]$Id
name = [string]$Request.Body.values.name
Owner = [string]$Username
IsShared = $Request.Body.values.IsShared
params = [string](ConvertTo-Json -InputObject $params -Compress)
}

try {
$Success = $false
$Table = Get-CIPPTable -TableName 'GraphPresets'
$Message = '{0} preset succeeded' -f $Request.Body.Action
if ($Request.Body.Action -eq 'Copy') {
Add-CIPPAzDataTableEntity @Table -Entity $Preset
$Success = $true
} else {
$Entity = Get-CIPPAzDataTableEntity @Table -Filter "RowKey eq '$Id'"
if ($Entity.Owner -eq $Username ) {
if ($Request.Body.Action -eq 'Delete') {
Remove-AzDataTableEntity @Table -Entity $Entity
} elseif ($Request.Body.Action -eq 'Save') {
Add-CIPPAzDataTableEntity @Table -Entity $Preset -Force
}
$Success = $true
} else {
$Message = 'Error: You can only modify your own presets.'
$Success = $false
}
}

$StatusCode = [HttpStatusCode]::OK
} catch {
$Success = $false
$Message = $_.Exception.Message
$StatusCode = [HttpStatusCode]::BadRequest
}
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = $StatusCode
Body = @{
Results = $Message
Success = $Success
}
})
}
29 changes: 17 additions & 12 deletions Modules/CIPPCore/Public/Entrypoints/Invoke-ExecOffboardTenant.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Function Invoke-ExecOffboardTenant {
$BulkResults = New-GraphBulkRequest -Requests $BulkRequests -tenantid $TenantFilter

$results.Add('Succesfully removed guest users')
Write-LogMessage -user $ExecutingUser -API $APIName -message "CSP Guest users were removed" -Sev "Info" -tenant $TenantFilter
} else {
$results.Add('No guest users found to remove')
}
Expand All @@ -46,7 +47,6 @@ Function Invoke-ExecOffboardTenant {
}

if ($request.body.RemoveCSPnotificationContacts) {
Write-Host "DO WE GET HERE?"
# Remove all email adresses that match the CSP tenants domains from the contact properties in /organization
try {
try {
Expand Down Expand Up @@ -79,6 +79,7 @@ Function Invoke-ExecOffboardTenant {
try {
New-GraphPostRequest -type PATCH -body $patchContactBody -Uri "https://graph.microsoft.com/v1.0/organization/$($orgContacts.id)" -tenantid $Tenantfilter -ContentType "application/json"
$results.Add("Succesfully removed notification contacts from $($property): $(($propertyContacts | Where-Object { $domains -contains $_.Split("@")[1] }))")
Write-LogMessage -user $ExecutingUser -API $APIName -message "Contacts were removed from $($property)" -Sev "Info" -tenant $TenantFilter
} catch {
$errors.Add("Failed to update property $($property): $($_.Exception.message)")
}
Expand All @@ -90,16 +91,17 @@ Function Invoke-ExecOffboardTenant {

}

if ($request.body.RemoveMSPvendorApps) {
# 9fcfb031-1bf6-4848-8732-5573fd64fc09 - Augmentt
# 9359814a-7403-4af9-9113-d5c8cab020ed - Rewst CSP connector
# 06bfda05-2d5e-4b3b-ac5d-79f07e402973 - Rewst Prod
# c19d36e8-6537-4998-9872-ea8b962bd0b6 - Rewst Azure Integration
# d7db2a1c-c38b-4bd1-a30f-0915167ba928 - Datto Backupify/Saas Protection
# 0c3cdc94-15ba-4b89-9222-29f599727b1c - AutoTask Client Portal SSO
# 62603940-b9b0-454f-b138-eb8d571f21d3 - Eshgro Smarter 365?
# Possible others, Scapmann, PatchMyPC, Datto M365 management, Kaseya crap, Exclaimer(?), HP, Lenovo, Dell, Apple(???), resellers(all region tenants?), Action1, Liquit
# Current idea, do a filtered serviceprincipals request based on the appOwner tenantids of known MSP vendors, load that data into a multi-select on the GUI
if ($request.body.RemoveVendorApps) {
$request.body.RemoveVendorApps | ForEach-Object {
try {
$delete = (New-GraphPostRequest -type 'DELETE' -Uri "https://graph.microsoft.com/v1.0/serviceprincipals/$($_.value)" -tenantid $Tenantfilter)
$results.Add("Succesfully removed app $($_.label)")
Write-LogMessage -user $ExecutingUser -API $APIName -message "App $($_.label) was removed" -Sev "Info" -tenant $TenantFilter
} catch {
#$results.Add("Failed to removed app $($_.displayName)")
$errors.Add("Failed to removed app $($_.label)")
}
}
}

# All customer tenant specific actions ALWAYS have to be completed before this action!
Expand All @@ -112,14 +114,15 @@ Function Invoke-ExecOffboardTenant {
try {
$delete = (New-GraphPostRequest -type 'DELETE' -Uri "https://graph.microsoft.com/v1.0/serviceprincipals/$($_.id)" -tenantid $Tenantfilter)
$results.Add("Succesfully removed app $($_.displayName)")
Write-LogMessage -user $ExecutingUser -API $APIName -message "App $($_.displayName) was removed" -Sev "Info" -tenant $TenantFilter
} catch {
#$results.Add("Failed to removed app $($_.displayName)")
$errors.Add("Failed to removed app $($_.displayName)")
}
}
} catch {
#$results.Add("Failed to retrieve multitenant apps, no apps have been removed: $($_.Exception.message)")
$errors.Add("Failed to retrieve multitenant apps, no apps have been removed: $($_.Exception.message)")
$errors.Add("Failed to retrieve multitenant CSP apps, no apps have been removed: $($_.Exception.message)")
}
}

Expand All @@ -131,6 +134,7 @@ Function Invoke-ExecOffboardTenant {
try {
$terminate = (New-GraphPostRequest -type 'POST' -Uri "https://graph.microsoft.com/v1.0/tenantRelationships/delegatedAdminRelationships/$($_.id)/requests" -body '{"action":"terminate"}' -ContentType 'application/json' -tenantid $env:TenantID)
$results.Add("Succesfully terminated GDAP relationship $($_.displayName) from tenant $TenantFilter")
Write-LogMessage -user $ExecutingUser -API $APIName -message "GDAP Relationship $($_.displayName) has been terminated" -Sev "Info" -tenant $TenantFilter
} catch {
#$results.Add("Failed to terminate GDAP relationship $($_.displayName): $($_.Exception.message)")
$errors.Add("Failed to terminate GDAP relationship $($_.displayName): $($_.Exception.message)")
Expand All @@ -147,6 +151,7 @@ Function Invoke-ExecOffboardTenant {
try {
$terminate = (New-GraphPostRequest -type 'PATCH' -body '{ "relationshipToPartner": "none" }' -Uri "https://api.partnercenter.microsoft.com/v1/customers/$TenantFilter" -ContentType 'application/json' -scope 'https://api.partnercenter.microsoft.com/user_impersonation' -tenantid $env:TenantID)
$results.Add('Succesfully terminated contract relationship')
Write-LogMessage -user $ExecutingUser -API $APIName -message "Contract relationship terminated" -Sev "Info" -tenant $TenantFilter
} catch {
#$results.Add("Failed to terminate contract relationship: $($_.Exception.message)")
$errors.Add("Failed to terminate contract relationship: $($_.Exception.message)")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,11 @@ function Invoke-ExecOnboardTenant {
Add-CIPPAzDataTableEntity @OnboardTable -Entity $TenantOnboarding -Force -ErrorAction Stop

Push-OutputBinding -Name QueueItem -Value ([pscustomobject]@{
FunctionName = 'ExecOnboardTenantQueue'
id = $Id
Roles = $Request.Body.gdapRoles
FunctionName = 'ExecOnboardTenantQueue'
id = $Id
Roles = $Request.Body.gdapRoles
AddMissingGroups = $Request.Body.addMissingGroups
AutoMapRoles = $Request.Body.autoMapRoles
})
}

Expand Down
Loading

0 comments on commit 9ce75fe

Please sign in to comment.