Skip to content

Commit

Permalink
Merge pull request #101 from KelvinTegelaar/dev
Browse files Browse the repository at this point in the history
[pull] dev from KelvinTegelaar:dev
  • Loading branch information
BNWEIN authored Dec 7, 2024
2 parents a1adc3b + 440d435 commit 0771e53
Show file tree
Hide file tree
Showing 25 changed files with 451 additions and 295 deletions.
2 changes: 1 addition & 1 deletion Modules/CIPPCore/Public/Add-CIPPScheduledTask.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ function Add-CIPPScheduledTask {
$Parameters = [System.Collections.Hashtable]@{}
foreach ($Key in $task.Parameters.PSObject.Properties.Name) {
$Param = $task.Parameters.$Key
if ($Param -is [System.Collections.IDictionary]) {
if ($Param -is [System.Collections.IDictionary] -or $Param.Key) {
$ht = @{}
foreach ($p in $Param.GetEnumerator()) {
$ht[$p.Key] = $p.Value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,21 @@ function Get-CippAuditLogSearchResults {
[string]$TenantFilter,
[Parameter(ValueFromPipelineByPropertyName = $true, Mandatory = $true)]
[Alias('id')]
[string]$QueryId
[string]$QueryId,
[switch]$CountOnly
)

process {
New-GraphGetRequest -uri ('https://graph.microsoft.com/beta/security/auditLog/queries/{0}/records?$top=999' -f $QueryId) -AsApp $true -tenantid $TenantFilter -ErrorAction Stop
$GraphRequest = @{
Uri = ('https://graph.microsoft.com/beta/security/auditLog/queries/{0}/records?$top=999&$count=true' -f $QueryId)
Method = 'GET'
AsApp = $true
tenantid = $TenantFilter
}
if ($CountOnly.IsPresent) {
$GraphRequest.CountOnly = $true
}

New-GraphGetRequest @GraphRequest -ErrorAction Stop
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ function Push-AuditLogTenant {
# Get webhook rules
$ConfigEntries = Get-CIPPAzDataTableEntity @ConfigTable
$LogSearchesTable = Get-CippTable -TableName 'AuditLogSearches'

Write-Information ("Audit: Memory usage before processing $([System.GC]::GetTotalMemory($false))")
$SearchCount = 0
$Configuration = $ConfigEntries | Where-Object { ($_.Tenants -match $TenantFilter -or $_.Tenants -match 'AllTenants') }
if ($Configuration) {
try {
Expand Down Expand Up @@ -88,12 +89,17 @@ function Push-AuditLogTenant {
}
}
}
$SearchCount++
Write-Information "Audit: Memory usage after processing $SearchCount searches: $([System.GC]::GetTotalMemory($false))"
}
} catch {
Write-Information ( 'Audit Log search: Error {0} line {1} - {2}' -f $_.InvocationInfo.ScriptName, $_.InvocationInfo.ScriptLineNumber, $_.Exception.Message)
}
}
} catch {
Write-Information ( 'Push-AuditLogTenant: Error {0} line {1} - {2}' -f $_.InvocationInfo.ScriptName, $_.InvocationInfo.ScriptLineNumber, $_.Exception.Message)
} finally {
Write-Information "Audit Logs: Completed processing $($TenantFilter)"
Write-Information "Audit Logs: Memory usage after processing $([System.GC]::GetTotalMemory($false))"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Function Invoke-ExecRestoreBackup {
$APIName = $TriggerMetadata.FunctionName
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug'
try {
foreach ($line in ($Request.body | ConvertFrom-Json | Select-Object * -ExcludeProperty ETag)) {
foreach ($line in ($Request.body | ConvertFrom-Json | Select-Object * -ExcludeProperty ETag, Timestamp)) {
Write-Host ($line)
$Table = Get-CippTable -tablename $line.table
$ht2 = @{}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,19 @@ Function Invoke-ExecDeviceAction {
if ($Request.Query.Action -eq 'setDeviceName') {
$ActionBody = @{ deviceName = $Request.Body.input } | ConvertTo-Json -Compress
}
$ActionResult = New-CIPPDeviceAction -Action $Request.Query.Action -ActionBody $ActionBody -DeviceFilter $Request.Query.GUID -TenantFilter $Request.Query.TenantFilter -ExecutingUser $request.headers.'x-ms-client-principal' -APINAME $APINAME
else {
$ActionBody = $Request.Body | ConvertTo-Json -Compress
}

$cmdparams = @{
Action = $Request.Query.Action
ActionBody = $ActionBody
DeviceFilter = $Request.Query.GUID
TenantFilter = $Request.Query.TenantFilter
ExecutingUser = $request.headers.'x-ms-client-principal'
APINAME = $APINAME
}
$ActionResult = New-CIPPDeviceAction @cmdparams
$body = [pscustomobject]@{'Results' = "$ActionResult" }

} catch {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ Function Invoke-AddGroup {
}
$GraphRequest = New-ExoRequest -tenantid $tenant -cmdlet 'New-DistributionGroup' -cmdParams $params
}
$GraphRequest = New-ExoRequest -tenantid $tenant -cmdlet 'New-DistributionGroup' -cmdParams $params
# At some point add logic to use AddOwner/AddMember for New-DistributionGroup, but idk how we're going to brr that - rvdwegen
}
"Successfully created group $($groupobj.displayname) for $($tenant)"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using namespace System.Net

function Invoke-ListPerUserMFA {
<#
.FUNCTIONALITY
Entrypoint
.ROLE
Identity.User.Read
#>
[CmdletBinding()]
param($Request, $TriggerMetadata)

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

# Write to the Azure Functions log stream.
Write-Host 'PowerShell HTTP trigger function processed a request.'

# Parse query parameters
$Tenant = $Request.query.tenantFilter
try {
$AllUsers = [System.Convert]::ToBoolean($Request.query.allUsers)
} catch {
$AllUsers = $false
}
$UserId = $Request.query.userId

# Get the MFA state for the user/all users
try {
if ($AllUsers -eq $true) {
$Results = Get-CIPPPerUserMFA -TenantFilter $Tenant -AllUsers $true
} else {
$Results = Get-CIPPPerUserMFA -TenantFilter $Tenant -userId $UserId
}
$StatusCode = [HttpStatusCode]::OK
} catch {
$ErrorMessage = Get-NormalizedError -Message $_.Exception.Message
$Results = "Failed to get MFA State for $UserId : $ErrorMessage"
$StatusCode = [HttpStatusCode]::Forbidden
}

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
StatusCode = $StatusCode
Body = @($Results)
})


}
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,28 @@ function Start-AuditLogOrchestrator {
param()
try {
$AuditLogSearchesTable = Get-CIPPTable -TableName 'AuditLogSearches'
$AuditLogSearches = Get-CIPPAzDataTableEntity @AuditLogSearchesTable -Filter "CippStatus eq 'Pending'"
$15MinutesAgo = (Get-Date).AddMinutes(-15).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ')
$1DayAgo = (Get-Date).AddDays(-1).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ')
$AuditLogSearches = Get-CIPPAzDataTableEntity @AuditLogSearchesTable -Filter "(CippStatus eq 'Pending' or (CippStatus eq 'Processing' and Timestamp le datetime'$15MinutesAgo')) and Timestamp ge datetime'$1DayAgo'" -Property PartitionKey, RowKey, Tenant, CippStatus, Timestamp

$WebhookRulesTable = Get-CIPPTable -TableName 'WebhookRules'
$WebhookRules = Get-CIPPAzDataTableEntity @WebhookRulesTable

if (($AuditLogSearches | Measure-Object).Count -eq 0) {
Write-Information 'No audit log searches available'
} elseif (($WebhookRules | Measure-Object).Count -eq 0) {
Write-Information 'No webhook rules defined'
} else {
$Queue = New-CippQueueEntry -Name 'Audit Log Collection' -Reference 'AuditLogCollection' -TotalTasks ($AuditLogSearches).Count
$Batch = $AuditLogSearches | Sort-Object -Property Tenant -Unique | Select-Object @{Name = 'TenantFilter'; Expression = { $_.Tenant } }, @{Name = 'QueueId'; Expression = { $Queue.RowKey } }, @{Name = 'FunctionName'; Expression = { 'AuditLogTenant' } }

$InputObject = [PSCustomObject]@{
OrchestratorName = 'AuditLogs'
Batch = @($Batch)
SkipLog = $true
}
Write-Information "Audit Logs: Processing $($AuditLogSearches.Count) searches"
if ($PSCmdlet.ShouldProcess('Start-AuditLogOrchestrator', 'Starting Audit Log Polling')) {
$Queue = New-CippQueueEntry -Name 'Audit Log Collection' -Reference 'AuditLogCollection' -TotalTasks ($AuditLogSearches).Count
$Batch = $AuditLogSearches | Sort-Object -Property Tenant -Unique | Select-Object @{Name = 'TenantFilter'; Expression = { $_.Tenant } }, @{Name = 'QueueId'; Expression = { $Queue.RowKey } }, @{Name = 'FunctionName'; Expression = { 'AuditLogTenant' } }

$InputObject = [PSCustomObject]@{
OrchestratorName = 'AuditLogs'
Batch = @($Batch)
SkipLog = $true
}
Start-NewOrchestration -FunctionName 'CIPPOrchestrator' -InputObject ($InputObject | ConvertTo-Json -Depth 5 -Compress)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function Start-UserTasksOrchestrator {
$currentUnixTime = [int64](([datetime]::UtcNow) - (Get-Date '1/1/1970')).TotalSeconds
if ($currentUnixTime -ge $task.ScheduledTime) {
try {
$null = Update-AzDataTableEntity @Table -Entity @{
$null = Update-AzDataTableEntity -Force @Table -Entity @{
PartitionKey = $task.PartitionKey
RowKey = $task.RowKey
ExecutedTime = "$currentUnixTime"
Expand All @@ -36,7 +36,9 @@ function Start-UserTasksOrchestrator {
if ($task.Tenant -eq 'AllTenants') {
$AllTenantCommands = foreach ($Tenant in $TenantList) {
$NewParams = $task.Parameters.Clone()
$NewParams.TenantFilter = $Tenant.defaultDomainName
if ((Get-Command $task.Command).Parameters.TenantFilter) {
$NewParams.TenantFilter = $Tenant.defaultDomainName
}
[pscustomobject]@{
Command = $task.Command
Parameters = $NewParams
Expand All @@ -46,13 +48,15 @@ function Start-UserTasksOrchestrator {
}
$Batch.AddRange($AllTenantCommands)
} else {
$ScheduledCommand.Parameters['TenantFilter'] = $task.Tenant
if ((Get-Command $task.Command).Parameters.TenantFilter) {
$ScheduledCommand.Parameters['TenantFilter'] = $task.Tenant
}
$Batch.Add($ScheduledCommand)
}
} catch {
$errorMessage = $_.Exception.Message

$null = Update-AzDataTableEntity @Table -Entity @{
$null = Update-AzDataTableEntity -Force @Table -Entity @{
PartitionKey = $task.PartitionKey
RowKey = $task.RowKey
Results = "$errorMessage"
Expand Down
4 changes: 2 additions & 2 deletions Modules/CIPPCore/Public/Get-CIPPMFAState.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ function Get-CIPPMFAState {
}
}

$PerUser = if ($PerUserMFAState -eq $null) { $null } else { ($PerUserMFAState | Where-Object -Property UserPrincipalName -EQ $_.UserPrincipalName).PerUserMFAState }
$PerUser = if ($null -eq $PerUserMFAState) { $null } else { ($PerUserMFAState | Where-Object -Property UserPrincipalName -EQ $_.UserPrincipalName).PerUserMFAState }

$MFARegUser = if (($MFARegistration | Where-Object -Property UserPrincipalName -EQ $_.userPrincipalName).isMFARegistered -eq $null) { $false } else { ($MFARegistration | Where-Object -Property UserPrincipalName -EQ $_.userPrincipalName) }
$MFARegUser = if ($null -eq ($MFARegistration | Where-Object -Property UserPrincipalName -EQ $_.userPrincipalName).isMFARegistered) { $false } else { ($MFARegistration | Where-Object -Property UserPrincipalName -EQ $_.userPrincipalName) }

[PSCustomObject]@{
Tenant = $TenantFilter
Expand Down
13 changes: 10 additions & 3 deletions Modules/CIPPCore/Public/GraphRequests/Get-GraphRequestList.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,12 @@ function Get-GraphRequestList {
$GraphQuery = [System.UriBuilder]('https://graph.microsoft.com/{0}/{1}' -f $Version, $Endpoint)
$ParamCollection = [System.Web.HttpUtility]::ParseQueryString([String]::Empty)
foreach ($Item in ($Parameters.GetEnumerator() | Sort-Object -CaseSensitive -Property Key)) {
$ParamCollection.Add($Item.Key, $Item.Value)
if ($Item.Value -is [System.Boolean]) {
$Item.Value = $Item.Value.ToString().ToLower()
}
if ($Item.Value) {
$ParamCollection.Add($Item.Key, $Item.Value)
}
}
$GraphQuery.Query = $ParamCollection.ToString()
$PartitionKey = Get-StringHash -String (@($Endpoint, $ParamCollection.ToString()) -join '-')
Expand Down Expand Up @@ -246,6 +251,7 @@ function Get-GraphRequestList {
default {
try {
$QueueThresholdExceeded = $false

if ($Parameters.'$count' -and !$SkipCache -and !$NoPagination) {
if ($Count -gt $singleTenantThreshold) {
$QueueThresholdExceeded = $true
Expand Down Expand Up @@ -290,7 +296,7 @@ function Get-GraphRequestList {

if (!$QueueThresholdExceeded) {
#nextLink should ONLY be used in direct calls with manual pagination. It should not be used in queueing
if ($nextLink) { $GraphRequest.uri = $nextLink }
if ($NoPagination.IsPresent -and $nextLink -match '^https://.+') { $GraphRequest.uri = $nextLink }

$GraphRequestResults = New-GraphGetRequest @GraphRequest -Caller 'Get-GraphRequestList' -ErrorAction Stop
$GraphRequestResults = $GraphRequestResults | Select-Object *, @{n = 'Tenant'; e = { $TenantFilter } }, @{n = 'CippStatus'; e = { 'Good' } }
Expand All @@ -313,7 +319,8 @@ function Get-GraphRequestList {
}

} catch {
throw $_.Exception
$Message = ('Exception at {0}:{1} - {2}' -f $_.InvocationInfo.ScriptName, $_.InvocationInfo.ScriptLineNumber, $_.Exception.Message)
throw $Message
}
}
}
Expand Down
22 changes: 11 additions & 11 deletions Modules/CIPPCore/Public/Invoke-CIPPOffboardingJob.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,23 @@ function Invoke-CIPPOffboardingJob {
$userid = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users/$($username)?`$select=id" -tenantid $Tenantfilter).id
Write-Host "Running offboarding job for $username with options: $($Options | ConvertTo-Json -Depth 10)"
$Return = switch ($Options) {
{ $_.'ConvertToShared' -eq 'true' } {
{ $_.'ConvertToShared' -eq $true } {
Set-CIPPMailboxType -ExecutingUser $ExecutingUser -tenantFilter $tenantFilter -userid $username -username $username -MailboxType 'Shared' -APIName $APIName
}
{ $_.RevokeSessions -eq 'true' } {
{ $_.RevokeSessions -eq $true } {
Revoke-CIPPSessions -tenantFilter $tenantFilter -username $username -userid $userid -ExecutingUser $ExecutingUser -APIName $APIName
}
{ $_.ResetPass -eq 'true' } {
{ $_.ResetPass -eq $true } {
Set-CIPPResetPassword -tenantFilter $tenantFilter -userid $username -ExecutingUser $ExecutingUser -APIName $APIName
}
{ $_.RemoveGroups -eq 'true' } {
{ $_.RemoveGroups -eq $true } {
Remove-CIPPGroups -userid $userid -tenantFilter $Tenantfilter -ExecutingUser $ExecutingUser -APIName $APIName -Username "$Username"
}

{ $_.'HideFromGAL' -eq 'true' } {
{ $_.'HideFromGAL' -eq $true } {
Set-CIPPHideFromGAL -tenantFilter $tenantFilter -userid $username -HideFromGAL $true -ExecutingUser $ExecutingUser -APIName $APIName
}
{ $_.'DisableSignIn' -eq 'true' } {
{ $_.'DisableSignIn' -eq $true } {
Set-CIPPSignInState -TenantFilter $tenantFilter -userid $username -AccountEnabled $false -ExecutingUser $ExecutingUser -APIName $APIName
}

Expand All @@ -57,23 +57,23 @@ function Invoke-CIPPOffboardingJob {
Set-CIPPForwarding -userid $userid -username $username -tenantFilter $Tenantfilter -Forward $Options.forward -KeepCopy $KeepCopy -ExecutingUser $ExecutingUser -APIName $APIName
}
}
{ $_.'RemoveLicenses' -eq 'true' } {
{ $_.'RemoveLicenses' -eq $true } {
Remove-CIPPLicense -userid $userid -username $Username -tenantFilter $Tenantfilter -ExecutingUser $ExecutingUser -APIName $APIName -Schedule
}

{ $_.'Deleteuser' -eq 'true' } {
{ $_.'deleteuser' -eq $true } {
Remove-CIPPUser -userid $userid -username $Username -tenantFilter $Tenantfilter -ExecutingUser $ExecutingUser -APIName $APIName
}

{ $_.'removeRules' -eq 'true' } {
{ $_.'removeRules' -eq $true } {
Write-Host "Removing rules for $username"
Remove-CIPPMailboxRule -userid $userid -username $Username -tenantFilter $Tenantfilter -ExecutingUser $ExecutingUser -APIName $APIName -RemoveAllRules
}

{ $_.'removeMobile' -eq 'true' } {
{ $_.'removeMobile' -eq $true } {
Remove-CIPPMobileDevice -userid $userid -username $Username -tenantFilter $Tenantfilter -ExecutingUser $ExecutingUser -APIName $APIName
}
{ $_.'removeCalendarInvites' -eq 'true' } {
{ $_.'removeCalendarInvites' -eq $true } {
Remove-CIPPCalendarInvites -userid $userid -username $Username -tenantFilter $Tenantfilter -ExecutingUser $ExecutingUser -APIName $APIName
}
{ $_.'removePermissions' } {
Expand Down
2 changes: 1 addition & 1 deletion Modules/CIPPCore/Public/Invoke-RemoveStandardTemplate.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Function Invoke-RemoveStandardTemplate {
$User = $request.headers.'x-ms-client-principal'
Write-LogMessage -user $User -API $APINAME -message 'Accessed this API' -Sev 'Debug'

$ID = $request.body.ID
$ID = $Request.Body.ID ?? $Request.Query.ID
try {
$Table = Get-CippTable -tablename 'templates'

Expand Down
2 changes: 1 addition & 1 deletion Modules/CIPPCore/Public/New-CIPPBackup.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function New-CIPPBackup {
)
$CSVfile = foreach ($CSVTable in $BackupTables) {
$Table = Get-CippTable -tablename $CSVTable
Get-AzDataTableEntity @Table | Select-Object * -ExcludeProperty DomainAnalyser, table | Select-Object *, @{l = 'table'; e = { $CSVTable } }
Get-AzDataTableEntity @Table | Select-Object * -ExcludeProperty DomainAnalyser, table, Timestamp, ETag | Select-Object *, @{l = 'table'; e = { $CSVTable } }
}
$RowKey = 'CIPPBackup' + '_' + (Get-Date).ToString('yyyy-MM-dd-HHmm')
$CSVfile
Expand Down
Loading

0 comments on commit 0771e53

Please sign in to comment.