diff --git a/AzureADDeviceCleanup.ps1 b/AzureADDeviceCleanup.ps1 index 0991df9..748d95f 100644 --- a/AzureADDeviceCleanup.ps1 +++ b/AzureADDeviceCleanup.ps1 @@ -1,4 +1,4 @@ -<# +<# Extremely Important Notes: ========================================================================================================= @@ -17,7 +17,7 @@ Extremely Important Notes: before deleting a stale device. - For more information, kindly visit the link: - https://docs.microsoft.com/en-us/azure/active-directory/devices/manage-stale-devices + https://learn.microsoft.com/en-us/entra/identity/devices/manage-stale-devices ========================================================================================================= @@ -30,10 +30,17 @@ Extremely Important Notes: .AUTHOR: Mohammad Zmaili +.VERSION + 1.1 (AzureAd PowerShell Module) + 1.2 (AzureAd PowerShell Module Retired, switching to Microsoft Graph API) + +.UPDATED BY + SUMANJIT PAN + .PARAMETER ThresholdDays Specifies the period of the last login. - Note: The default value is 90 days if this parameter is not configured. + Note: The default value is 180 days if this parameter is not configured. .PARAMETER Verify @@ -70,7 +77,7 @@ Extremely Important Notes: .EXAMPLE .\AzureADDeviceCleanup.ps1 -Verify - Verifies the stale devices since 90 says that will be deleted when running the PowerShell with 'CleanDevices' parameter. + Verifies the stale devices since 180 days that will be deleted when running the PowerShell with 'CleanDevices' parameter. .EXAMPLE .\AzureADDeviceCleanup.ps1 -Verify -ThresholdDays @@ -109,7 +116,7 @@ Last Login verified: 5/31/2019 2:32:37 PM [cmdletbinding()] param( [Parameter( Mandatory=$false)] - [Int]$ThresholdDays =90, + [Int]$ThresholdDays = 180, [Parameter( Mandatory=$false)] [switch]$Verify, @@ -150,113 +157,82 @@ $statuscode = (Invoke-WebRequest -Uri https://adminwebservice.microsoftonline.co if ($statuscode -ne 200){ '' '' -Write-Host "Operation aborted. Unable to connect to Azure AD, please check your internet connection." -ForegroundColor red -BackgroundColor Black +Write-Host "Operation aborted. Unable to connect to Microsoft Graph, please check your internet connection." -ForegroundColor red -BackgroundColor Black exit } } -Function CheckMSOnline{ +Function CheckMSGraph{ '' -Write-Host "Checking MSOnline Module..." -ForegroundColor Yellow +Write-Host "Checking Microsoft Graph Module..." -ForegroundColor Yellow - if (Get-Module -ListAvailable -Name MSOnline) { - Import-Module MSOnline - Write-Host "MSOnline Module has imported." -ForegroundColor Green -BackgroundColor Black - '' + if (Get-Module -ListAvailable | where {$_.Name -like "Microsoft.Graph"}) + { + Write-Host "Microsoft Graph Module has installed." -ForegroundColor Green + Import-Module -Name "Microsoft.Graph" + Write-Host "Microsoft Graph Module has imported." -ForegroundColor Cyan + '' + '' + } else + { + Write-Host "Microsoft Graph Module is not installed." -ForegroundColor Red + '' + Write-Host "Installing Microsoft Graph Module....." -ForegroundColor Yellow + Install-Module -Name "Microsoft.Graph" -Force + + if (Get-Module -ListAvailable | where {$_.Name -like "Microsoft.Graph"}) { + Write-Host "Microsoft Graph Module has installed." -ForegroundColor Green + Import-Module -Name "Microsoft.Graph" + Write-Host "Microsoft Graph Module has imported." -ForegroundColor Cyan + '' + '' + } else + { + '' + '' + Write-Host "Operation aborted. Microsoft Graph Module was not installed." -ForegroundColor Red + Exit} + } - Write-Host "Checking MSOnline version..." -ForegroundColor Yellow - $MVersion = Get-Module msonline | Select-Object version - if (($MVersion.Version.Major -eq 1) -and ($MVersion.Version.Minor -eq 1) -and ($MVersion.Version.Build -ge 183)){ - Write-Host "You have a supported version." -ForegroundColor Green -BackgroundColor Black - }else{ - Write-Host "You have an old version." -ForegroundColor Red -BackgroundColor Black - '' - Write-Host "Updating MSOnline version..." -ForegroundColor Yellow - Update-Module msonline -force - Remove-Module msonline - Import-Module msonline - $MVersion = Get-Module msonline | Select-Object version - if (($MVersion.Version.Major -eq 1) -and ($MVersion.Version.Minor -eq 1) -and ($MVersion.Version.Build -ge 183)){ - Write-Host "MSOnline Module has been updated. Please reopen PowerShell window." -ForegroundColor Green -BackgroundColor Black - exit - }else{ - Write-Host "Operation aborted. MSOnline module has not updated, please make sure you are running PowerShell as admin." -ForegroundColor red -BackgroundColor Black - exit - } - - } +Write-Host "Connecting to Microsoft Graph PowerShell..." -ForegroundColor Magenta - '' - Write-Host "Connecting to MSOnline..." -ForegroundColor Yellow - if ($SavedCreds){ - Connect-MsolService -Credential $UserCreds -ErrorAction SilentlyContinue + Connect-MgGraph -Credential $UserCreds -ErrorAction SilentlyContinue -NoWelcome }else{ - Connect-MsolService -ErrorAction SilentlyContinue + Connect-MgGraph -ErrorAction SilentlyContinue -NoWelcome } + $MgContext= Get-mgContext +Write-Host "User $($MgContext.Account) has connected to TenantId $($MgContext.TenantId) Microsoft Graph API successfully." -ForegroundColor Green +'' +'' - if (-not (Get-MsolCompanyInformation -ErrorAction SilentlyContinue)){ - Write-Host "Operation aborted. Unable to connect to MSOnline, please check you entered a correct credentials and you have the needed permissions." -ForegroundColor red -BackgroundColor Black - exit - } - Write-Host "Connected to MSOnline successfully." -ForegroundColor Green -BackgroundColor Black - '' - } else { - Write-Host "MSOnline Module is not installed." -ForegroundColor Red -BackgroundColor Black - Write-Host "Installing MSOnline Module....." -ForegroundColor Yellow - CheckInternet - Install-Module MSOnline -force - - if (Get-Module -ListAvailable -Name MSOnline) { - Write-Host "MSOnline Module has installed." -ForegroundColor Green -BackgroundColor Black - Import-Module MSOnline - Write-Host "MSOnline Module has imported." -ForegroundColor Green -BackgroundColor Black - '' - Write-Host "Connecting to MSOnline..." -ForegroundColor Yellow - Connect-MsolService -ErrorAction SilentlyContinue - - if (-not (Get-MsolCompanyInformation -ErrorAction SilentlyContinue)){ - Write-Host "Operation aborted. Unable to connect to MSOnline, please check you entered a correct credentials and you have the needed permissions." -ForegroundColor red -BackgroundColor Black - exit - } - Write-Host "Connected to MSOnline successfully." -ForegroundColor Green -BackgroundColor Black - '' - } else { - '' - '' - Write-Host "Operation aborted. MsOnline was not installed." -ForegroundColor red -BackgroundColor Black - exit - } } - -} - Function CheckImportExcel{ -Write-Host "Checking ImportExcel Module..." -ForegroundColor Yellow +Write-Host "Checking Excel Module..." -ForegroundColor Yellow - if (Get-Module -ListAvailable -Name ImportExcel) { - Import-Module ImportExcel - Write-Host "ImportExcel Module has imported." -ForegroundColor Green -BackgroundColor Black + if (Get-Module -ListAvailable -Name "ImportExcel") { + Import-Module -Name "ImportExcel" + Write-Host "Excel Module has imported." -ForegroundColor Green -BackgroundColor Black '' '' } else { - Write-Host "ImportExcel Module is not installed." -ForegroundColor Red -BackgroundColor Black + Write-Host "Excel Module is not installed." -ForegroundColor Red -BackgroundColor Black '' - Write-Host "Installing ImportExcel Module....." -ForegroundColor Yellow - Install-Module ImportExcel -Force + Write-Host "Installing Excel Module....." -ForegroundColor Yellow + Install-Module -Name "ImportExcel" -Force - if (Get-Module -ListAvailable -Name ImportExcel) { - Write-Host "ImportExcel Module has installed." -ForegroundColor Green -BackgroundColor Black - Import-Module ImportExcel - Write-Host "ImportExcel Module has imported." -ForegroundColor Green -BackgroundColor Black + if (Get-Module -ListAvailable -Name "ImportExcel") { + Write-Host "Excel Module has installed." -ForegroundColor Green -BackgroundColor Black + Import-Module -Name "ImportExcel" + Write-Host "Excel Module has imported." -ForegroundColor Green -BackgroundColor Black '' '' } else { '' '' - Write-Host "Operation aborted. ImportExcel was not installed." -ForegroundColor red -BackgroundColor Black + Write-Host "Operation aborted. Excel was not installed." -ForegroundColor Red -BackgroundColor Black exit } } @@ -289,67 +265,73 @@ Write-Host "You should determine whether your cleanup policy aligns with the act Write-Host "before deleting a stale device." -ForegroundColor yellow '' Write-Host "For more information, kindly visit the link:" -ForegroundColor yellow -Write-Host "https://docs.microsoft.com/en-us/azure/active-directory/devices/manage-stale-devices" -ForegroundColor yellow +Write-Host "https://learn.microsoft.com/en-us/entra/identity/devices/manage-stale-devices" -ForegroundColor yellow "====================================================================================================" '' -CheckMSOnline +CheckMSGraph CheckImportExcel -$global:lastLogon = [datetime](get-date).AddDays(- $ThresholdDays) +$Global:LastLogon = [datetime](get-date).AddDays(- $ThresholdDays) $Date=("{0:s}" -f (get-date)).Split("T")[0] -replace "-", "" $Time=("{0:s}" -f (get-date)).Split("T")[1] -replace ":", "" -$date2=("{0:s}" -f ($global:lastLogon)).Split("T")[0] -replace "-", "" +$LastLogin = ("{0:s}" -f ($LastLogon)).Split("T")[0] -replace "-", "" -$workSheetName = "AADDevicesOlderthen-" + $date2 +$WorkSheetName = "AADDevicesOlderthan-" + $LastLogin if ($Verify){ - Write-Host "Verifing stale devices older than"$global:lastLogon -ForegroundColor Yellow - $filerep = "AzureADDevicesList_" + $Date + $Time + ".xlsx" - $rep=Get-MsolDevice -all -ReturnRegisteredOwners -LogonTimeBefore $global:lastLogon | select Enabled, ObjectId, DeviceId, DisplayName, DeviceOsType, DeviceOsVersion, DeviceTrustType, DeviceTrustLevel, ApproximateLastLogonTimestamp, DirSyncEnabled, LastDirSyncTime, @{Name=’Registeredowners’;Expression={[string]::join(“;”, ($_.Registeredowners))}} - $rep | Export-Excel -workSheetName $workSheetName -path $filerep -ClearSheet -TableName "AADDevicesTable" -AutoSize - $global:AffectedDevices = $rep.Count + Write-Host "Verifing stale devices older than"$Global:LastLogon -ForegroundColor Yellow + $FileReport = "AzureADDevicesList_" + $Date + $Time + ".xlsx" + $DeviceReport = Get-MgDevice -All:$true | Where {($_.ApproximateLastSignInDateTime -le $Global:LastLogon) -and ($_.ApproximateLastSignInDateTime -ne $Null)} | Select-Object -Property DisplayName, AccountEnabled, DeviceId, OperatingSystem, OperatingSystemVersion, TrustType, ApproximateLastSignInDateTime + $DeviceReport | Export-Excel -workSheetName $WorkSheetName -path $FileReport -ClearSheet -TableName "AADDevicesTable" -AutoSize + $Global:AffectedDevices = $DeviceReport.Count Write-Host "Verification Completed." -ForegroundColor Green -BackgroundColor Black }elseif ($VerifyDisabledDevices){ - Write-Host "Verifing stale disabled devices older than"$global:lastLogon -ForegroundColor Yellow - $filerep = "DisabledDevices_" + $Date + $Time + ".xlsx" - $rep=Get-MsolDevice -all -ReturnRegisteredOwners -LogonTimeBefore $global:lastLogon | where{$_.Enabled -eq $false} | select Enabled, ObjectId, DeviceId, DisplayName, DeviceOsType, DeviceOsVersion, DeviceTrustType, DeviceTrustLevel, ApproximateLastLogonTimestamp, DirSyncEnabled, LastDirSyncTime, @{Name=’Registeredowners’;Expression={[string]::join(“;”, ($_.Registeredowners))}} - $rep | Export-Excel -workSheetName $workSheetName -path $filerep -ClearSheet -TableName "AADDevicesTable" -AutoSize - $global:AffectedDevices = $rep.Count + Write-Host "Verifing stale disabled devices older than"$Global:LastLogon -ForegroundColor Yellow + $FileReport = "DisabledDevices_" + $Date + $Time + ".xlsx" + $DeviceReport = Get-MgDevice -All:$true | Where {($_.ApproximateLastSignInDateTime -le $Global:LastLogon) -and ($_.ApproximateLastSignInDateTime -ne $Null) -and ($_.AccountEnabled -eq $false)} | Select-Object -Property DisplayName, AccountEnabled, DeviceId, OperatingSystem, OperatingSystemVersion, TrustType, ApproximateLastSignInDateTime + $DeviceReport | Export-Excel -workSheetName $WorkSheetName -path $FileReport -ClearSheet -TableName "AADDevicesTable" -AutoSize + $Global:AffectedDevices = $DeviceReport.Count Write-Host "Task Completed Successfully." -ForegroundColor Green -BackgroundColor Black }elseif ($DisableDevices){ - Write-Host "Disabling stale devices older than"$global:lastLogon -ForegroundColor Yellow - $filerep = "DisabledDevices_" + $Date + $Time + ".xlsx" - $rep=Get-MsolDevice -all -ReturnRegisteredOwners -LogonTimeBefore $global:lastLogon | where{$_.Enabled -eq $true} | select ObjectId, DeviceId, DisplayName, DeviceOsType, DeviceOsVersion, DeviceTrustType, DeviceTrustLevel, ApproximateLastLogonTimestamp, DirSyncEnabled, LastDirSyncTime, @{Name=’Registeredowners’;Expression={[string]::join(“;”, ($_.Registeredowners))}} - $rep | Disable-MsolDevice -Force - $rep | Export-Excel -workSheetName $workSheetName -path $filerep -ClearSheet -TableName "AADDevicesTable" -AutoSize - $global:AffectedDevices = $rep.Count + Write-Host "Disabling stale devices older than"$Global:LastLogon -ForegroundColor Yellow + $FileReport = "DisabledDevices_" + $Date + $Time + ".xlsx" + $DeviceReport = Get-AzureADDevice -All:$true | Where {($_.ApproximateLastSignInDateTime -le $Global:LastLogon) -and ($_.ApproximateLastSignInDateTime -ne $Null) -and ($_.AccountEnabled -eq $true)} | Select-Object -Property DisplayName, AccountEnabled, DeviceId, OperatingSystem, OperatingSystemVersion, TrustType, ApproximateLastSignInDateTime + foreach ($Device in $DeviceReport) { + Update-MgDevice -DeviceId $Device.Id -AccountEnabled:$false + } + $DeviceReport | Export-Excel -workSheetName $WorkSheetName -path $FileReport -ClearSheet -TableName "AADDevicesTable" -AutoSize + $Global:AffectedDevices = $DeviceReport.Count Write-Host "Task Completed Successfully." -ForegroundColor Green -BackgroundColor Black }elseif ($CleanDisabledDevices){ - Write-Host "Cleaning STALE DISABLED devices older than"$global:lastLogon -ForegroundColor Yellow - $filerep = "CleanedDevices_" + $Date + $Time + ".xlsx" - $rep=Get-MsolDevice -all -ReturnRegisteredOwners -LogonTimeBefore $global:lastLogon | where{$_.Enabled -eq $false} | select ObjectId, DeviceId, DisplayName, DeviceOsType, DeviceOsVersion, DeviceTrustType, DeviceTrustLevel, ApproximateLastLogonTimestamp, DirSyncEnabled, LastDirSyncTime, @{Name=’Registeredowners’;Expression={[string]::join(“;”, ($_.Registeredowners))}} - $rep | Remove-MsolDevice -Force - $rep | Export-Excel -workSheetName $workSheetName -path $filerep -ClearSheet -TableName "AADDevicesTable" -AutoSize - $global:AffectedDevices = $rep.Count + Write-Host "Cleaning STALE DISABLED devices older than"$Global:LastLogon -ForegroundColor Yellow + $FileReport = "CleanedDevices_" + $Date + $Time + ".xlsx" + $DeviceReport = Get-MgDevice -All:$true | Where {($_.ApproximateLastSignInDateTime -le $Global:LastLogon) -and ($_.ApproximateLastSignInDateTime -ne $Null) -and ($_.AccountEnabled -eq $false)} | Select-Object -Property DisplayName, AccountEnabled, DeviceId, OperatingSystem, OperatingSystemVersion, TrustType, ApproximateLastSignInDateTime + foreach ($Device in $DeviceReport) { + Remove-MgDevice -DeviceId $Device.Id + } + $DeviceReport | Export-Excel -workSheetName $WorkSheetName -path $FileReport -ClearSheet -TableName "AADDevicesTable" -AutoSize + $Global:AffectedDevices = $DeviceReport.Count Write-Host "Task Completed Successfully." -ForegroundColor Green -BackgroundColor Black }elseif ($CleanDevices){ - Write-Host "Cleaning STALE devices older than"$global:lastLogon -ForegroundColor Yellow - $filerep = "CleanedDevices_" + $Date + $Time + ".xlsx" - $rep=Get-MsolDevice -all -ReturnRegisteredOwners -LogonTimeBefore $global:lastLogon | select ObjectId, DeviceId, DisplayName, DeviceOsType, DeviceOsVersion, DeviceTrustType, DeviceTrustLevel, ApproximateLastLogonTimestamp, DirSyncEnabled, LastDirSyncTime, @{Name=’Registeredowners’;Expression={[string]::join(“;”, ($_.Registeredowners))}} - $rep | Remove-MsolDevice -Force - $rep | Export-Excel -workSheetName $workSheetName -path $filerep -ClearSheet -TableName "AADDevicesTable" -AutoSize - $global:AffectedDevices = $rep.Count + Write-Host "Cleaning STALE devices older than"$Global:LastLogon -ForegroundColor Yellow + $FileReport = "CleanedDevices_" + $Date + $Time + ".xlsx" + $DeviceReport = Get-MgDevice -All:$true | Where {($_.ApproximateLastSignInDateTime -le $Global:LastLogon) -and ($_.ApproximateLastSignInDateTime -ne $Null)} | Select-Object -Property DisplayName, AccountEnabled, DeviceId, OperatingSystem, OperatingSystemVersion, TrustType, ApproximateLastSignInDateTime + foreach ($Device in $DeviceReport) { + Remove-MgDevice -DeviceId $Device.Id + } + $DeviceReport | Export-Excel -workSheetName $WorkSheetName -path $FileReport -ClearSheet -TableName "AADDevicesTable" -AutoSize + $Global:AffectedDevices = $DeviceReport.Count Write-Host "Task Completed Successfully." -ForegroundColor Green -BackgroundColor Black }else{ - Write-Host "Operation aborted. You have not select any parameter, please make sure to select any of the following parameters:" -ForegroundColor red -BackgroundColor Black + Write-Host "Operation aborted. You have not select any parameter, please make sure to select any of the following parameters:" -ForegroundColor Red Write-Host " Verify @@ -373,7 +355,7 @@ Removed the stale devices as per the configured threshold. if ($OnScreenReport) { - $rep | Out-GridView -Title "Hybrid Devices Health Check Report" + $DeviceReport | Out-GridView -Title "Hybrid Devices Health Check Report" } @@ -382,9 +364,9 @@ if ($OnScreenReport) { Write-Host "===================================" Write-Host "|Azure AD Devices Cleanup Summary:|" Write-Host "===================================" -Write-Host "Number of affected devices:" $global:AffectedDevices -Write-Host "Last Login verified:" $global:lastLogon +Write-Host "Number of affected devices:" $Global:AffectedDevices +Write-Host "Last Login verified:" $Global:LastLogon +'' +$Loc = Get-Location +Write-host $FileReport "report has been created on the path:" $Loc -ForegroundColor Green -BackgroundColor Black '' -$loc=Get-Location -Write-host $filerep "report has been created on the path:" $loc -ForegroundColor green -BackgroundColor Black -'' \ No newline at end of file diff --git a/Outfile.png b/Outfile.png new file mode 100644 index 0000000..4904f69 Binary files /dev/null and b/Outfile.png differ diff --git a/PS.PNG b/PS.PNG deleted file mode 100644 index a021ec2..0000000 Binary files a/PS.PNG and /dev/null differ diff --git a/PS1.png b/PS1.png new file mode 100644 index 0000000..70d573e Binary files /dev/null and b/PS1.png differ diff --git a/PS2.png b/PS2.png new file mode 100644 index 0000000..e08b933 Binary files /dev/null and b/PS2.png differ diff --git a/README.md b/README.md index 654240f..00c8969 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ AzureADDeviceCleanup PowerShell script helps to manage the stale devices in Azur - Verifies the stale disabled devices as per the entered threshold days. - Cleans the stale devices from Azure AD as per the entered threshold days. - Cleans the stale disabled devices only from Azure AD as per the entered threshold days - - Checks if ‘MSOnline‘ module is installed and updated. If not, it takes case of this. + - Checks if ‘AzureAd‘ module is installed and updated. If not, it takes case of this. - Checks if ‘ImportExcel‘ module is installed. If not, it installs and imports it. @@ -56,10 +56,11 @@ Using AzureADDeviceCleanup PowerShell script, you can automate Azure AD devices - Execute the PowerShell: -![PS output](https://github.com/mzmaili/AzureADDeviceCleanup/blob/master/PS.PNG) +![PS output](https://github.com/Sumanjit092/AzureADDeviceCleanup/blob/master/PS1.png) +![PS output](https://github.com/Sumanjit092/AzureADDeviceCleanup/blob/master/PS2.png) - Excel output: -![CSVReport](https://github.com/mzmaili/AzureADDeviceCleanup/blob/master/Untitled.png) +![CSVReport](https://github.com/Sumanjit092/AzureADDeviceCleanup/blob/master/Outfile.png) ```azurepowershell @@ -75,7 +76,7 @@ Using AzureADDeviceCleanup PowerShell script, you can automate Azure AD devices .PARAMETER ThresholdDays Specifies the period of the last login. - Note: The default value is 90 days if this parameter is not configured. + Note: The default value is 180 days if this parameter is not configured. .PARAMETER Verify @@ -116,7 +117,7 @@ Using AzureADDeviceCleanup PowerShell script, you can automate Azure AD devices .EXAMPLE .\AzureADDeviceCleanup.ps1 -Verify - Verifies the stale devices since 90 says that will be deleted when running the PowerShell with 'CleanDevices' parameter. + Verifies the stale devices since 180 says that will be deleted when running the PowerShell with 'CleanDevices' parameter. .EXAMPLE .\AzureADDeviceCleanup.ps1 -Verify -ThresholdDays diff --git a/Untitled.png b/Untitled.png deleted file mode 100644 index 4a769de..0000000 Binary files a/Untitled.png and /dev/null differ