Skip to content
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
5 changes: 5 additions & 0 deletions Config/CIPPDBCacheTypes.json
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,11 @@
"friendlyName": "SharePoint Site Usage",
"description": "SharePoint site usage statistics"
},
{
"type": "SiteActivity",
"friendlyName": "Site Activity",
"description": "Per-site activity with siteType classification (SharePoint, SharePointAndTeams, OneDrive) and separate workload activity columns"
},
{
"type": "SharePointSharingLinks",
"friendlyName": "SharePoint & OneDrive Sharing Links",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
function Get-CIPPAlertInactiveSharePointSites {
<#
.FUNCTIONALITY
Entrypoint
#>
[CmdletBinding()]
param (
[Parameter(Mandatory = $false)]
[Alias('input')]
$InputValue,
$TenantFilter
)

$HasSharePoint = Test-CIPPStandardLicense -StandardName 'InactiveSharePointSites' -TenantFilter $TenantFilter -Preset SharePoint
if (-not $HasSharePoint) {
return
}

try {
$DaysSinceActivity = 90
$IncludeNeverActive = $false

if ($InputValue -is [hashtable] -or $InputValue -is [PSCustomObject]) {
if ($null -ne $InputValue.IncludeNeverActive) {
$IncludeNeverActive = [bool]$InputValue.IncludeNeverActive
}
if ($null -ne $InputValue.DaysSinceActivity -and $InputValue.DaysSinceActivity -ne '') {
$ParsedDays = 0
if ([int]::TryParse($InputValue.DaysSinceActivity.ToString(), [ref]$ParsedDays) -and $ParsedDays -gt 0) {
$DaysSinceActivity = $ParsedDays
}
}
} elseif ($InputValue) {
$ParsedDays = 0
if ([int]::TryParse($InputValue.ToString(), [ref]$ParsedDays) -and $ParsedDays -gt 0) {
$DaysSinceActivity = $ParsedDays
}
}

$Lookup = (Get-Date).AddDays(-$DaysSinceActivity).Date

$SiteActivityRows = @(New-CIPPDbRequest -TenantFilter $TenantFilter -Type 'SiteActivity')
if (-not $SiteActivityRows) {
return
}

$AlertData = foreach ($Site in $SiteActivityRows) {
if ($Site.isDeleted -eq $true) { continue }
if ($Site.siteType -ne 'SharePoint') { continue }

$LastActivity = $Site.effectiveLastActivityDate
if (-not $LastActivity) {
if (-not $IncludeNeverActive) { continue }
} elseif ([DateTime]$LastActivity -gt $Lookup) {
continue
}

$SiteUrl = $Site.webUrl
$SiteLabel = $Site.displayName ?? $SiteUrl
if ([string]::IsNullOrWhiteSpace($SiteLabel) -and $Site.ownerDisplayName) {
$SiteLabel = $Site.ownerDisplayName
}

$LastActivityDisplay = if ($LastActivity) { $LastActivity } else { 'Never' }
$DaysSinceActivityValue = if ($LastActivity) {
[Math]::Round(((Get-Date).Date - [DateTime]$LastActivity).TotalDays)
} else {
'N/A'
}

$OwnerPart = if ($Site.ownerPrincipalName) { " Owner: $($Site.ownerPrincipalName)." } else { '' }
$Message = "Site '$SiteLabel' ($SiteUrl) SharePoint last active $LastActivityDisplay.$OwnerPart"

[PSCustomObject]@{
Message = $Message
Id = $Site.siteId
siteId = $Site.siteId
webUrl = $SiteUrl
displayName = $Site.displayName
ownerPrincipalName = $Site.ownerPrincipalName
lastActivityDate = $LastActivityDisplay
DaysSinceActivity = $DaysSinceActivityValue
rootWebTemplate = $Site.rootWebTemplate
cachedAt = $Site.cachedAt
reportPeriod = $Site.reportPeriod
teamLinkResolutionStatus = $Site.teamLinkResolutionStatus
Tenant = $TenantFilter
}
}

if ($AlertData) {
Write-AlertTrace -cmdletName $MyInvocation.MyCommand -tenantFilter $TenantFilter -data $AlertData
}
} catch {
$ErrorMessage = Get-CippException -Exception $_
Write-AlertMessage -message "Inactive SharePoint sites alert failed: $($ErrorMessage.NormalizedError)" -tenant $TenantFilter -LogData $ErrorMessage
}
}
101 changes: 101 additions & 0 deletions Modules/CIPPAlerts/Public/Alerts/Get-CIPPAlertInactiveTeamsSites.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
function Get-CIPPAlertInactiveTeamsSites {
<#
.FUNCTIONALITY
Entrypoint
#>
[CmdletBinding()]
param (
[Parameter(Mandatory = $false)]
[Alias('input')]
$InputValue,
$TenantFilter
)

$HasTeams = Test-CIPPStandardLicense -StandardName 'InactiveTeamsSites' -TenantFilter $TenantFilter -Preset Teams
if (-not $HasTeams) {
return
}

try {
$DaysSinceActivity = 90
$IncludeNeverActive = $false

if ($InputValue -is [hashtable] -or $InputValue -is [PSCustomObject]) {
if ($null -ne $InputValue.IncludeNeverActive) {
$IncludeNeverActive = [bool]$InputValue.IncludeNeverActive
}
if ($null -ne $InputValue.DaysSinceActivity -and $InputValue.DaysSinceActivity -ne '') {
$ParsedDays = 0
if ([int]::TryParse($InputValue.DaysSinceActivity.ToString(), [ref]$ParsedDays) -and $ParsedDays -gt 0) {
$DaysSinceActivity = $ParsedDays
}
}
} elseif ($InputValue) {
$ParsedDays = 0
if ([int]::TryParse($InputValue.ToString(), [ref]$ParsedDays) -and $ParsedDays -gt 0) {
$DaysSinceActivity = $ParsedDays
}
}

$Lookup = (Get-Date).AddDays(-$DaysSinceActivity).Date

$SiteActivityRows = @(New-CIPPDbRequest -TenantFilter $TenantFilter -Type 'SiteActivity')
if (-not $SiteActivityRows) {
return
}

$AlertData = foreach ($Site in $SiteActivityRows) {
if ($Site.isDeleted -eq $true) { continue }
if ($Site.siteType -ne 'SharePointAndTeams') { continue }

$LastActivity = $Site.effectiveLastActivityDate
if (-not $LastActivity) {
if (-not $IncludeNeverActive) { continue }
} elseif ([datetime]$LastActivity -gt $Lookup) {
continue
}

$TeamsSiteUrl = $Site.webUrl
$TeamsSiteLabel = $Site.teamsTeamName ?? $Site.displayName ?? $TeamsSiteUrl
if ([string]::IsNullOrWhiteSpace($TeamsSiteLabel) -and $Site.ownerDisplayName) {
$TeamsSiteLabel = $Site.ownerDisplayName
}

$LastActivityDisplay = if ($LastActivity) { $LastActivity } else { 'Never' }
$DaysSinceActivityValue = if ($LastActivity) {
[Math]::Round(((Get-Date).Date - [datetime]$LastActivity).TotalDays)
} else {
'N/A'
}

$OwnerPart = if ($Site.ownerPrincipalName) { " Owner: $($Site.ownerPrincipalName)." } else { '' }
$Message = "TeamsSite '$TeamsSiteLabel' ($TeamsSiteUrl) Teams last active $LastActivityDisplay.$OwnerPart"

[PSCustomObject]@{
Message = $Message
Id = $Site.siteId
siteId = $Site.siteId
teamsSiteName = $TeamsSiteLabel
teamsSiteUrl = $TeamsSiteUrl
teamsTeamId = $Site.teamsTeamId
teamsTeamName = $Site.teamsTeamName
teamsLastActivityDate = $LastActivityDisplay
DaysSinceActivity = $DaysSinceActivityValue
sharePointLastActivityDate = $Site.sharePointLastActivityDate
effectiveLastActivityDate = $Site.effectiveLastActivityDate
ownerPrincipalName = $Site.ownerPrincipalName
teamLinkResolutionStatus = $Site.teamLinkResolutionStatus
cachedAt = $Site.cachedAt
reportPeriod = $Site.reportPeriod
Tenant = $TenantFilter
}
}

if ($AlertData) {
Write-AlertTrace -cmdletName $MyInvocation.MyCommand -tenantFilter $TenantFilter -data $AlertData
}
} catch {
$ErrorMessage = Get-CippException -Exception $_
Write-AlertMessage -message "Inactive TeamsSite alert failed: $($ErrorMessage.NormalizedError)" -tenant $TenantFilter -LogData $ErrorMessage
}
}
1 change: 1 addition & 0 deletions Modules/CIPPCore/Public/Invoke-CIPPDBCacheCollection.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ function Invoke-CIPPDBCacheCollection {
'SPOTenant'
'SPOTenantSyncClientRestriction'
'SharePointSiteUsage'
'SiteActivity'
'OneDriveUsage'
)
Teams = @(
Expand Down
19 changes: 9 additions & 10 deletions Modules/CIPPCore/Public/Set-CIPPSAMAdminRoles.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -83,23 +83,22 @@ function Set-CIPPSAMAdminRoles {
$ActionLogs.Add('Added Service Principal to Compliance Center')
} catch {
$SpError = $_.Exception.Message
if ($SpError -match 'already exist') {
$ActionLogs.Add('Service Principal already added to Compliance Center')
} else {
$ActionLogs.Add("Failed to add Service Principal to Compliance Center: $SpError")
$HasFailures = $true
switch ($SpError) {
{ $_ -match 'already exist' } { $ActionLogs.Add('Service Principal already added to Compliance Center') }
{ $_ -match 'New-ServicePrincipal is not present' } { $ActionLogs.Add('Tenant does not have a license to use Compliance Center features. Skipping.') }
default { $ActionLogs.Add("Failed to add Service Principal to Compliance Center: $SpError"); $HasFailures = $true }
}

}
try {
$null = New-ExoRequest -cmdlet 'New-ServicePrincipal' -cmdParams @{AppId = $env:ApplicationID; ObjectId = $id; DisplayName = 'CIPP-SAM' } -tenantid $TenantFilter -useSystemMailbox $true -AsApp
$ActionLogs.Add('Added Service Principal to Exchange Online')
} catch {
$SpError = $_.Exception.Message
if ($SpError -match 'already exist') {
$ActionLogs.Add('Service Principal already added to Exchange Online')
} else {
$ActionLogs.Add("Failed to add Service Principal to Exchange Online: $SpError")
$HasFailures = $true
switch ($SpError) {
{ $_ -match 'already exist' } { $ActionLogs.Add('Service Principal already added to Compliance Center') }
{ $_ -match 'Response status code does not indicate success' } { $ActionLogs.Add('Could not connect to Exchange, we received an access denied. This is expected if you do not have an exchange license.'); $HasFailures = $true }
default { $ActionLogs.Add("Failed to add Service Principal to Compliance Center: $SpError"); $HasFailures = $true }
}
}

Expand Down
Loading
Loading