add: public function to check mfa status
This commit is contained in:
99
source/Public/Get-MFAStatus.ps1
Normal file
99
source/Public/Get-MFAStatus.ps1
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
Retrieves the MFA (Multi-Factor Authentication) status for Azure Active Directory users.
|
||||||
|
.DESCRIPTION
|
||||||
|
The Get-MFAStatus function connects to Microsoft Online Service and retrieves the MFA status for all Azure Active Directory users, excluding guest accounts. Optionally, you can specify a single user by their User Principal Name (UPN) to get their MFA status.
|
||||||
|
.PARAMETER UserId
|
||||||
|
The User Principal Name (UPN) of a specific user to retrieve MFA status for. If not provided, the function retrieves MFA status for all users.
|
||||||
|
.EXAMPLE
|
||||||
|
Get-MFAStatus
|
||||||
|
Retrieves the MFA status for all Azure Active Directory users.
|
||||||
|
.EXAMPLE
|
||||||
|
Get-MFAStatus -UserId "example@domain.com"
|
||||||
|
Retrieves the MFA status for the specified user with the UPN "example@domain.com".
|
||||||
|
.OUTPUTS
|
||||||
|
System.Object
|
||||||
|
Returns a sorted list of custom objects containing the following properties:
|
||||||
|
- UserPrincipalName
|
||||||
|
- DisplayName
|
||||||
|
- MFAState
|
||||||
|
- MFADefaultMethod
|
||||||
|
- MFAPhoneNumber
|
||||||
|
- PrimarySMTP
|
||||||
|
- Aliases
|
||||||
|
.NOTES
|
||||||
|
The function requires the MSOL module to be installed and connected to your tenant.
|
||||||
|
Ensure that you have the necessary permissions to read user and MFA status information.
|
||||||
|
#>
|
||||||
|
function Get-MFAStatus {
|
||||||
|
[CmdletBinding()]
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory = $false)]
|
||||||
|
[ValidateNotNullOrEmpty()]
|
||||||
|
[string]$UserId
|
||||||
|
)
|
||||||
|
|
||||||
|
begin {
|
||||||
|
# Connect to Microsoft Online service
|
||||||
|
}
|
||||||
|
|
||||||
|
process {
|
||||||
|
if (Get-Module MSOnline){
|
||||||
|
Connect-MsolService
|
||||||
|
Write-Host "Finding Azure Active Directory Accounts..."
|
||||||
|
# Get all users, excluding guests
|
||||||
|
$Users = if ($PSBoundParameters.ContainsKey('UserId')) {
|
||||||
|
Get-MsolUser -UserPrincipalName $UserId
|
||||||
|
} else {
|
||||||
|
Get-MsolUser -All | Where-Object { $_.UserType -ne "Guest" }
|
||||||
|
}
|
||||||
|
$Report = [System.Collections.Generic.List[Object]]::new() # Create output list
|
||||||
|
Write-Host "Processing" $Users.Count "accounts..."
|
||||||
|
ForEach ($User in $Users) {
|
||||||
|
$MFADefaultMethod = ($User.StrongAuthenticationMethods | Where-Object { $_.IsDefault -eq "True" }).MethodType
|
||||||
|
$MFAPhoneNumber = $User.StrongAuthenticationUserDetails.PhoneNumber
|
||||||
|
$PrimarySMTP = $User.ProxyAddresses | Where-Object { $_ -clike "SMTP*" } | ForEach-Object { $_ -replace "SMTP:", "" }
|
||||||
|
$Aliases = $User.ProxyAddresses | Where-Object { $_ -clike "smtp*" } | ForEach-Object { $_ -replace "smtp:", "" }
|
||||||
|
|
||||||
|
If ($User.StrongAuthenticationRequirements) {
|
||||||
|
$MFAState = $User.StrongAuthenticationRequirements.State
|
||||||
|
}
|
||||||
|
Else {
|
||||||
|
$MFAState = 'Disabled'
|
||||||
|
}
|
||||||
|
|
||||||
|
If ($MFADefaultMethod) {
|
||||||
|
Switch ($MFADefaultMethod) {
|
||||||
|
"OneWaySMS" { $MFADefaultMethod = "Text code authentication phone" }
|
||||||
|
"TwoWayVoiceMobile" { $MFADefaultMethod = "Call authentication phone" }
|
||||||
|
"TwoWayVoiceOffice" { $MFADefaultMethod = "Call office phone" }
|
||||||
|
"PhoneAppOTP" { $MFADefaultMethod = "Authenticator app or hardware token" }
|
||||||
|
"PhoneAppNotification" { $MFADefaultMethod = "Microsoft authenticator app" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Else {
|
||||||
|
$MFADefaultMethod = "Not enabled"
|
||||||
|
}
|
||||||
|
|
||||||
|
$ReportLine = [PSCustomObject] @{
|
||||||
|
UserPrincipalName = $User.UserPrincipalName
|
||||||
|
DisplayName = $User.DisplayName
|
||||||
|
MFAState = $MFAState
|
||||||
|
MFADefaultMethod = $MFADefaultMethod
|
||||||
|
MFAPhoneNumber = $MFAPhoneNumber
|
||||||
|
PrimarySMTP = ($PrimarySMTP -join ',')
|
||||||
|
Aliases = ($Aliases -join ',')
|
||||||
|
}
|
||||||
|
|
||||||
|
$Report.Add($ReportLine)
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Processing complete."
|
||||||
|
return $Report | Select-Object UserPrincipalName, DisplayName, MFAState, MFADefaultMethod, MFAPhoneNumber, PrimarySMTP, Aliases | Sort-Object UserPrincipalName
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Host "You must first install MSOL using:`nInstall-Module MSOnline -Scope CurrentUser -Force"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
71
tests/Unit/Public/Get-MFAStatus.tests.ps1
Normal file
71
tests/Unit/Public/Get-MFAStatus.tests.ps1
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
BeforeAll {
|
||||||
|
$script:moduleName = '<% $PLASTER_PARAM_ModuleName %>'
|
||||||
|
|
||||||
|
# If the module is not found, run the build task 'noop'.
|
||||||
|
if (-not (Get-Module -Name $script:moduleName -ListAvailable))
|
||||||
|
{
|
||||||
|
# Redirect all streams to $null, except the error stream (stream 2)
|
||||||
|
& "$PSScriptRoot/../../build.ps1" -Tasks 'noop' 2>&1 4>&1 5>&1 6>&1 > $null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Re-import the module using force to get any code changes between runs.
|
||||||
|
Import-Module -Name $script:moduleName -Force -ErrorAction 'Stop'
|
||||||
|
|
||||||
|
$PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:moduleName
|
||||||
|
$PSDefaultParameterValues['Mock:ModuleName'] = $script:moduleName
|
||||||
|
$PSDefaultParameterValues['Should:ModuleName'] = $script:moduleName
|
||||||
|
}
|
||||||
|
|
||||||
|
AfterAll {
|
||||||
|
$PSDefaultParameterValues.Remove('Mock:ModuleName')
|
||||||
|
$PSDefaultParameterValues.Remove('InModuleScope:ModuleName')
|
||||||
|
$PSDefaultParameterValues.Remove('Should:ModuleName')
|
||||||
|
|
||||||
|
Remove-Module -Name $script:moduleName
|
||||||
|
}
|
||||||
|
|
||||||
|
Describe Get-Something {
|
||||||
|
|
||||||
|
Context 'Return values' {
|
||||||
|
BeforeEach {
|
||||||
|
$return = Get-Something -Data 'value'
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'Returns a single object' {
|
||||||
|
($return | Measure-Object).Count | Should -Be 1
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Context 'Pipeline' {
|
||||||
|
It 'Accepts values from the pipeline by value' {
|
||||||
|
$return = 'value1', 'value2' | Get-Something
|
||||||
|
|
||||||
|
$return[0] | Should -Be 'value1'
|
||||||
|
$return[1] | Should -Be 'value2'
|
||||||
|
}
|
||||||
|
|
||||||
|
It 'Accepts value from the pipeline by property name' {
|
||||||
|
$return = 'value1', 'value2' | ForEach-Object {
|
||||||
|
[PSCustomObject]@{
|
||||||
|
Data = $_
|
||||||
|
OtherProperty = 'other'
|
||||||
|
}
|
||||||
|
} | Get-Something
|
||||||
|
|
||||||
|
|
||||||
|
$return[0] | Should -Be 'value1'
|
||||||
|
$return[1] | Should -Be 'value2'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Context 'ShouldProcess' {
|
||||||
|
It 'Supports WhatIf' {
|
||||||
|
(Get-Command Get-Something).Parameters.ContainsKey('WhatIf') | Should -Be $true
|
||||||
|
{ Get-Something -Data 'value' -WhatIf } | Should -Not -Throw
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Reference in New Issue
Block a user