refactor(scripts): optimize system remediation and M365 export scripts
- teams: harden Classic Teams removal, protect New Teams, and clean HKU run keys - dotnet: add bootstrapper EXE uninstall support and remove orphaned 3.1.* folders - teams: add MSIX package targeting and version parsing for vulnerable New Teams builds - m365: improve Graph SDK export speed, reuse sessions, and add null-safe handling
This commit is contained in:
1 parent
4fd95b76d6
commit
5ef82842f2
19 files changed
+1651
-1268
No files matched your search
@@ -0,0 +1,109 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Exports Microsoft 365 user recertification and licensing report using Microsoft Graph SDK.
|
||||
.DESCRIPTION
|
||||
Retrieves all M365 users, resolves license SKU IDs to readable part numbers,
|
||||
extracts last interactive sign-in dates, and exports the dataset to CSV.
|
||||
.EXAMPLE
|
||||
.\Export-M365UserCertification.ps1 -OutputPath ".\M365-User-Certification-Export.csv"
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory = $false)]
|
||||
[string]$OutputPath = ".\M365-User-Certification-Export.csv"
|
||||
)
|
||||
|
||||
# Silence Graph cmdlet progress bars to drastically decrease execution time
|
||||
$OriginalProgressPreference = $ProgressPreference
|
||||
$ProgressPreference = 'SilentlyContinue'
|
||||
|
||||
try {
|
||||
# Check existing Microsoft Graph session
|
||||
$CurrentContext = Get-MgContext
|
||||
$RequiredScopes = @("User.Read.All", "Directory.Read.All", "AuditLog.Read.All")
|
||||
|
||||
if (-not $CurrentContext) {
|
||||
Write-Host "Connecting to Microsoft Graph..." -ForegroundColor Cyan
|
||||
Connect-MgGraph -Scopes $RequiredScopes
|
||||
}
|
||||
else {
|
||||
Write-Host "Connected as $($CurrentContext.Account)" -ForegroundColor Green
|
||||
}
|
||||
|
||||
# Resolve relative path to absolute path
|
||||
$ResolvedOutputPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($OutputPath)
|
||||
|
||||
Write-Host "Building license SKU lookup table..." -ForegroundColor Cyan
|
||||
$SkuLookup = @{}
|
||||
Get-MgSubscribedSku -All | ForEach-Object {
|
||||
$SkuLookup[$_.SkuId.ToString()] = $_.SkuPartNumber
|
||||
}
|
||||
|
||||
# Explicitly define target properties (signInActivity requires AuditLog.Read.All)
|
||||
$Properties = @(
|
||||
"id",
|
||||
"displayName",
|
||||
"userPrincipalName",
|
||||
"userType",
|
||||
"accountEnabled",
|
||||
"assignedLicenses",
|
||||
"externalUserState",
|
||||
"signInActivity"
|
||||
)
|
||||
|
||||
Write-Host "Fetching user data from Microsoft Graph..." -ForegroundColor Cyan
|
||||
$Users = Get-MgUser -All -Property $Properties
|
||||
|
||||
Write-Host "Processing $($Users.Count) users..." -ForegroundColor Cyan
|
||||
|
||||
$Export = foreach ($User in $Users) {
|
||||
# Resolve licenses
|
||||
$AssignedLicenses = if ($User.AssignedLicenses -and $User.AssignedLicenses.Count -gt 0) {
|
||||
($User.AssignedLicenses | ForEach-Object {
|
||||
$SkuId = $_.SkuId.ToString()
|
||||
if ($SkuLookup.ContainsKey($SkuId)) {
|
||||
$SkuLookup[$SkuId]
|
||||
}
|
||||
else {
|
||||
$SkuId
|
||||
}
|
||||
}) -join "; "
|
||||
}
|
||||
else {
|
||||
"None"
|
||||
}
|
||||
|
||||
# Safe null-check for SignInActivity
|
||||
$LastSignIn = if ($User.SignInActivity -and $User.SignInActivity.LastSignInDateTime) {
|
||||
$User.SignInActivity.LastSignInDateTime
|
||||
}
|
||||
else {
|
||||
"Never / No Record"
|
||||
}
|
||||
|
||||
[PSCustomObject]@{
|
||||
Name = $User.DisplayName
|
||||
UserPrincipalName = $User.UserPrincipalName
|
||||
UserType = $User.UserType
|
||||
AccountEnabled = $User.AccountEnabled
|
||||
AssignedLicenses = $AssignedLicenses
|
||||
GuestInvitationState = $User.ExternalUserState
|
||||
LastInteractiveSignInDate = $LastSignIn
|
||||
}
|
||||
}
|
||||
|
||||
# Export results to CSV
|
||||
$Export |
|
||||
Sort-Object Name |
|
||||
Export-Csv -Path $ResolvedOutputPath -NoTypeInformation -Encoding UTF8
|
||||
|
||||
Write-Host "Export complete: $ResolvedOutputPath" -ForegroundColor Green
|
||||
|
||||
}
|
||||
catch {
|
||||
Write-Error "An error occurred during execution: $_"
|
||||
}
|
||||
finally {
|
||||
# Restore original progress preference
|
||||
$ProgressPreference = $OriginalProgressPreference
|
||||
}
|
||||
Reference in new issue
Block a user