M365 License Expiry Date Report

Converted from MSOnline to MS Graph and included Certificate-based Authentication.
This commit is contained in:
AdminDroid 2024-09-16 15:30:59 +05:30
parent 57bd60d821
commit 343272a785

View File

@ -1,9 +1,17 @@
<# <#
============================================================================================= =============================================================================================
Name: Get License Expiry Date report Name: Get License Expiry Date report
Version: 2.0 Version: 3.0
Website: o365reports.com Website: o365reports.com
ChangeLog
~~~~~~~~~
V1 - Initial version (04/03/2020)
V2 - Minor changes (10/06/2023)
V3 - Migrated from MSOnline module to MS Graph (9/13/2024)
Script Highlights: Script Highlights:
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
@ -13,7 +21,8 @@ Script Highlights:
4.Result can be filtered based on subscription status like Enabled, Expired, Disabled, etc. 4.Result can be filtered based on subscription status like Enabled, Expired, Disabled, etc.
5.Subscription name is shown asuser-friendly-namelike Office 365 Enterprise E3 rather than ENTERPRISEPACK. 5.Subscription name is shown asuser-friendly-namelike Office 365 Enterprise E3 rather than ENTERPRISEPACK.
6.The script can be executed with MFA enabled account too. 6.The script can be executed with MFA enabled account too.
7.The script is scheduler friendly. i.e., credentials can be passed as a parameter instead of saving inside the script. 7.The script is scheduler friendly.
8.Supports certificate based authentication (CBA) too.
For detailed script execution: https://o365reports.com/2020/03/04/export-office-365-license-expiry-date-report-powershell/ For detailed script execution: https://o365reports.com/2020/03/04/export-office-365-license-expiry-date-report-powershell/
============================================================================================ ============================================================================================
@ -26,39 +35,51 @@ Param
[switch]$Purchased, [switch]$Purchased,
[Switch]$Expired, [Switch]$Expired,
[Switch]$Active, [Switch]$Active,
[string]$UserName, [switch]$CreateSession,
[string]$Password [string]$TenantId,
[string]$ClientId,
[string]$CertificateThumbprint
) )
#Check for MSOnline module Function Connect_MgGraph
$Module=Get-Module -Name MSOnline -ListAvailable {
#Check for module installation
$Module=Get-Module -Name microsoft.graph.beta -ListAvailable
if($Module.count -eq 0) if($Module.count -eq 0)
{ {
Write-Host MSOnline module is not available -ForegroundColor yellow Write-Host Microsoft Graph PowerShell SDK is not available -ForegroundColor yellow
$Confirm= Read-Host Are you sure you want to install module? [Y] Yes [N] No $Confirm= Read-Host Are you sure you want to install module? [Y] Yes [N] No
if($Confirm -match "[yY]") if($Confirm -match "[yY]")
{ {
Install-Module MSOnline Write-host "Installing Microsoft Graph PowerShell module..."
Import-Module MSOnline Install-Module Microsoft.Graph.beta -Repository PSGallery -Scope CurrentUser -AllowClobber -Force
} }
else else
{ {
Write-Host MSOnline module is required to connect AzureAD.Please install module using Install-Module MSOnline cmdlet. Write-Host "Microsoft Graph Beta PowerShell module is required to run this script. Please install module using Install-Module Microsoft.Graph cmdlet."
Exit Exit
} }
} }
#Disconnect Existing MgGraph session
#Storing credential in script for scheduling purpose/ Passing credential as parameter if($CreateSession.IsPresent)
if(($UserName -ne "") -and ($Password -ne ""))
{ {
$SecuredPassword = ConvertTo-SecureString -AsPlainText $Password -Force Disconnect-MgGraph
$Credential = New-Object System.Management.Automation.PSCredential $UserName,$SecuredPassword }
Connect-MsolService -Credential $credential
Write-Host Connecting to Microsoft Graph...
if(($TenantId -ne "") -and ($ClientId -ne "") -and ($CertificateThumbprint -ne ""))
{
Connect-MgGraph -TenantId $TenantId -AppId $ClientId -CertificateThumbprint $CertificateThumbprint -NoWelcome
} }
else else
{ {
Connect-MsolService | Out-Null Connect-MgGraph -Scopes "Directory.Read.All" -NoWelcome
} }
}
Connect_MgGraph
$Result="" $Result=""
$Results=@() $Results=@()
@ -67,7 +88,8 @@ $ShowAllSubscription=$False
$PrintedOutput=0 $PrintedOutput=0
#Output file declaration #Output file declaration
$ExportCSV=".\LicenseExpiryReport_$((Get-Date -format yyyy-MMM-dd-ddd` hh-mm` tt).ToString()).csv" $Location=Get-Location
$ExportCSV="$Location\LicenseExpiryReport_$((Get-Date -format yyyy-MMM-dd-ddd` hh-mm` tt).ToString()).csv"
#Check for filters #Check for filters
if((!($Trial.IsPresent)) -and (!($Free.IsPresent)) -and (!($Purchased.IsPresent)) -and (!($Expired.IsPresent)) -and (!($Active.IsPresent))) if((!($Trial.IsPresent)) -and (!($Free.IsPresent)) -and (!($Purchased.IsPresent)) -and (!($Expired.IsPresent)) -and (!($Active.IsPresent)))
@ -79,13 +101,26 @@ if((!($Trial.IsPresent)) -and (!($Free.IsPresent)) -and (!($Purchased.IsPresent)
$FriendlyNameHash=@() $FriendlyNameHash=@()
$FriendlyNameHash=Get-Content -Raw -Path .\LicenseFriendlyName.txt -ErrorAction Stop | ConvertFrom-StringData $FriendlyNameHash=Get-Content -Raw -Path .\LicenseFriendlyName.txt -ErrorAction Stop | ConvertFrom-StringData
#Get next lifecycle date
$ExpiryDateHash=@{}
$LifeCycleDateInfo=(Invoke-MgGraphRequest -Uri https://graph.microsoft.com/V1.0/directory/subscriptions -Method Get).Value
foreach($Date in $LifeCycleDate)
{
$ExpiryDateHash.Add($Date.skuId,$Date.nextLifeCycleDateTime)
}
#Get available subscriptions in the tenant #Get available subscriptions in the tenant
$Subscriptions= Get-MsolSubscription | foreach{ $Subscriptions= Get-MgBetaSubscribedSku -All | foreach{
$SubscriptionName=$_.SKUPartNumber $SubscriptionName=$_.SKUPartNumber
$SubscribedOn=$_.DateCreated $SkuId=$_.SkuId
$ExpiryDate=$_.NextLifeCycleDate $ConsumedUnits=$_.ConsumedUnits
$Status=$_.Status $MoreSkuDetails=$LifeCycleDateInfo | Where {$_.skuId -eq $SkuId}
$TotalLicenses=$_.TotalLicenses $SubscribedOn=$MoreSkuDetails.createdDateTime
$Status=$MoreSkuDetails.status
$TotalLicenses=$MoreSkuDetails.totalLicenses
$ExpiryDate=$MoreSkuDetails.nextLifeCycleDateTime
$RemainingUnits=$TotalLicenses - $ConsumedUnits
$Print=0 $Print=0
#Convert Skuid to friendly name #Convert Skuid to friendly name
@ -114,21 +149,18 @@ $Subscriptions= Get-MsolSubscription | foreach{
$SubscribedDate="$SubscribedOn $SubscribedDate" $SubscribedDate="$SubscribedOn $SubscribedDate"
#Determine subscription type #Determine subscription type
If($_.IsTrial -eq $False) if(($SubscriptionName -like "*Free*") -and ($ExpiryDate -eq $null))
{
if(($SubscriptionName -like "*Free*") -or ($ExpiryDate -eq $null))
{ {
$SubscriptionType="Free" $SubscriptionType="Free"
} }
elseif($ExpiryDate -eq $null)
{
$SubscriptionType="Trial"
}
else else
{ {
$SubscriptionType="Purchased" $SubscriptionType="Purchased"
} }
}
else
{
$SubscriptionType="Trial"
}
#Friendly Expiry Date #Friendly Expiry Date
if($ExpiryDate -ne $null) if($ExpiryDate -ne $null)
@ -192,9 +224,9 @@ $Subscriptions= Get-MsolSubscription | foreach{
if($Print -eq 1) if($Print -eq 1)
{ {
$PrintedOutput++ $PrintedOutput++
$Result=@{'Subscription Name'=$SubscriptionName;'Friendly Subscription Name'=$NamePrint;'Subscribed Date'=$SubscribedDate;'Total Licenses'=$TotalLicenses;'License Expiry Date/Next LifeCycle Activity Date'=$ExpiryDate;'Friendly Expiry Date'=$FriendlyExpiryDate;'Subscription Type'=$SubscriptionType;'Status'=$Status} $Result=@{'Subscription Name'=$SubscriptionName;'SKU Id'=$SkuId;'Friendly Subscription Name'=$NamePrint;'Subscribed Date'=$SubscribedDate;'Total Units'=$TotalLicenses;'Consumed Units'=$ConsumedUnits;'Remaining Units'=$RemainingUnits;'License Expiry Date/Next LifeCycle Activity Date'=$ExpiryDate;'Friendly Expiry Date'=$FriendlyExpiryDate;'Subscription Type'=$SubscriptionType;'Status'=$Status}
$Results= New-Object PSObject -Property $Result $Results= New-Object PSObject -Property $Result
$Results | Select-Object 'Subscription Name','Friendly Subscription Name','Subscribed Date','Total Licenses','Subscription Type','License Expiry Date/Next LifeCycle Activity Date','Friendly Expiry Date','Status' | Export-Csv -Path $ExportCSV -Notype -Append $Results | Select-Object 'Subscription Name','Friendly Subscription Name','Subscribed Date','Total Units','Consumed Units','Remaining Units','Subscription Type','License Expiry Date/Next LifeCycle Activity Date','Friendly Expiry Date','Status','SKU Id' | Export-Csv -Path $ExportCSV -Notype -Append
} }
} }
@ -205,8 +237,7 @@ if((Test-Path -Path $ExportCSV) -eq "True")
Write-Host " Office 365 license expiry report available in:" -NoNewline -ForegroundColor Yellow Write-Host " Office 365 license expiry report available in:" -NoNewline -ForegroundColor Yellow
Write-Host $ExportCSV Write-Host $ExportCSV
Write-Host "" Write-Host ""
Write-Host " The Output file contains:" -NoNewline -ForegroundColor Yellow Write-Host " The Output file contains:" $PrintedOutput subscriptions
Write-Host $PrintedOutput subscriptions
Write-Host `n~~ Script prepared by AdminDroid Community ~~`n -ForegroundColor Green Write-Host `n~~ Script prepared by AdminDroid Community ~~`n -ForegroundColor Green
Write-Host "~~ Check out " -NoNewline -ForegroundColor Green; Write-Host "admindroid.com" -ForegroundColor Yellow -NoNewline; Write-Host " to get access to 1800+ Microsoft 365 reports. ~~" -ForegroundColor Green `n`n Write-Host "~~ Check out " -NoNewline -ForegroundColor Green; Write-Host "admindroid.com" -ForegroundColor Yellow -NoNewline; Write-Host " to get access to 1800+ Microsoft 365 reports. ~~" -ForegroundColor Green `n`n
$Prompt = New-Object -ComObject wscript.shell $Prompt = New-Object -ComObject wscript.shell