by David | May 27, 2024 | Information Technology, Resources
Imagine waking up to an email full of alerts about unwanted access attempts. It is every administrator’s nightmare. The truth is that many security incidents can be traced back to disabled accounts that were not properly reviewed. You might wonder, “What about disabled accounts? “Aren’t they harmless?” Well, not quite. There are reasons we need to, Audit Disabled Accounts.
Disabled accounts in Active Directory (AD) are analogous to lost keys to your home. They may be out of sight, but they do exist. Those who look hard enough can find them. If you do not audit these accounts on a regular basis, you risk exposing your network to vulnerabilities. Neglected accounts may result in attacks or compliance difficulties.
I discovered this the hard way during my early days as a sysadmin. I believed I had things under control. One day, an audit found multiple disabled accounts that had been left neglected for months. It was a wakeup call. Since then, reviewing disabled accounts has been an important part of my routine.
Why should you consider auditing disabled accounts? It’s not just about checking the compliance box. It is about ensuring a safe and well-managed environment. It is critical to keep your network secure from unauthorized access and breaches. In this post, I’ll show you how to build up a PowerShell script to audit disabled accounts. We will also automate the process using a scheduled task. Believe me, it’s easier than you think. Your future self will thank you for this.
Let us begin our path toward greater security and peace of mind.
The Why Audit Disabled Accounts?
Picture this: It’s the middle of the day, when the CFO’s account is abruptly deactivated. Chaos ensues. The support desk is frantic, and everyone is on edge. You are left wondering, “Who did this, and when?” It’s a frustrating situation that could have been prevented with routine audits.
Auditing disabled accounts is more than just a boring process; it is critical for determining exactly when and by whom an account was disabled. Consider installing a surveillance camera on your network doors. You know precisely who locked which door and at what time. This level of visibility is critical for keeping control of your Active Directory (AD).
This PowerShell script was built in response to a particularly stressful occurrence. A help desk technician unintentionally shut down the CFO’s account. The names were nearly identical: bholts for the CFO, and bsholts for a floor technician. One tiny error resulted in a major problem. The CFO was naturally furious, demanding to know who was to blame. That’s when I realized I needed a solid technique to keep track of these actions.
Security is a significant reason for auditing disabled accounts. If an attacker acquires access to one of these accounts, they may be able to explore your network without detection. It’s like leaving the front door wide open. Regular audits ensure that these accounts are appropriately managed and secured, preventing unwanted access.
Compliance
Compliance is another reason to keep track of disabled accounts. Many regulatory regimes impose severe controls on user accounts. GDPR, HIPAA, and other regulations need proper account management, including for disabled accounts. Failure to comply might result in costly fines and a tarnished reputation.
However, it is not simply about avoiding undesirable results. Regular auditing of disabled accounts is also excellent housekeeping. It keeps your Active Directory clean and orderly. An clean Active Directory makes it easier to manage active users and keeps your environment running smoothly.
In my early sysadmin days, I underestimated the necessity of auditing disabled accounts. That was until the incident with the CFO’s account. Since then, auditing has been an essential component of my managerial routine. It’s a modest step that provides significant peace of mind.
So take a time to reflect on your current practices. Do you periodically audit disabled accounts? If not, this is a great moment to start. It represents an investment in your network’s security and efficiency. And believe me, it is worth every minute.
The Script
#Hourly
[cmdletbinding()]
param (
[int]$HoursBack = 1,
[string[]]$Servers,
[string]$OutCSVfile
)
$StartTimeStamp = ((Get-Date).AddHours(-($HoursBack)))
$EndTimeStamp = (Get-Date)
$ReturnInfo = @()
$FilterTable = @{
'StartTime' = $StartTimeStamp
'EndTime' = $EndTimeStamp
'LogName' = 'Security'
'Id' = 4725
}
$Events = foreach ($Server in $Servers) {
Get-WinEvent -ComputerName "$Server" -FilterHashtable $FilterTable -ErrorAction SilentlyContinue
}
foreach ($Event in $Events) {
$ReturnInfo += [pscustomobject][ordered]@{
Task = "Account Disabled"
Time = $Event.TimeCreated
DC = $Event.MachineName
Name = (get-aduser -Identity "$($Event.Properties[0].Value)" -Properties DIsplayname).Displayname
Username = $Event.Properties[0].Value
Admin = $Event.Properties[4].Value
}
}
$ReturnInfo | Export-Csv $OutCSVfile -NoClobber -NoTypeInformation -Append
The Breakdown
Let’s dive into the heart of this guide: the PowerShell script that will help you audit disabled accounts in Active Directory. We’ll break it down line by line, so you understand exactly how it works and how to customize it for your needs.
[cmdletbinding()]
param (
[int]$HoursBack = 1,
[string[]]$Servers,
[string]$OutCSVfile
)
- Parameters and Initialization
- [cmdletbinding()]: This line makes the script act like an advanced function, providing more control over parameters and runtime behavior.
- param: Here, we define three parameters:
$HoursBack
: The number of hours back to search for disabled accounts (default is 1).
$Servers
: An array of server names to query.
$OutCSVfile
: The file path to save the audit results.
$StartTimeStamp = ((Get-Date).AddHours(-($HoursBack)))
$EndTimeStamp = (Get-Date)
- Setting Up Timestamps
- $StartTimeStamp: Sets the start time for the search to one hour ago.
- $EndTimeStamp: Sets the end time to the current date and time.
$ReturnInfo = @()
$FilterTable = @{
'StartTime' = $StartTimeStamp
'EndTime' = $EndTimeStamp
'LogName' = 'Security'
'Id' = 4725
}
Grabbing the Events
- Filtering Events
- $ReturnInfo: Initializes an empty array to store the results. This allows us to collect the needed information for later.
- $FilterTable: Defines the criteria for filtering events:
StartTime
and EndTime
specify the time range. It’s important not to grab to many logs because Powershell can’t handle large amount of data.
LogName
is set to ‘Security’ to search in the Security log because that is where the disabled accounts live.
Id
is set to 4725, the event ID for account disablement.
$Events = foreach ($Server in $Servers) {
Get-WinEvent -ComputerName "$Server" -FilterHashtable $FilterTable -ErrorAction SilentlyContinue
}
- Retrieving Events
- foreach ($Server in $Servers): Iterates through each server in the
$Servers
list of strings. Remember, a list of strings is like an array but for strings. Reminds me of noodles before you cook them. Which my daughter made spaghetti the other day and I am proud of her.
- Get-WinEvent: Retrieves the events that match the criteria in
$FilterTable
. -ErrorAction SilentlyContinue
suppresses errors. I liken this command to the spaghetti after it has been cooked.
foreach ($Event in $Events) {
$ReturnInfo += [pscustomobject][ordered]@{
Task = "Account Disabled"
Time = $Event.TimeCreated
DC = $Event.MachineName
Name = (get-aduser -Identity "$($Event.Properties[0].Value)" -Properties Displayname).Displayname
Username = $Event.Properties[0].Value
Admin = $Event.Properties[4].Value
}
}
Processing and Exporting Events
- Processing Events
- foreach ($Event in $Events): Iterates through each retrieved event. We like to loop a lot with powershell.
- $ReturnInfo += [pscustomobject][ordered]: Adds a custom object to the
$ReturnInfo
array, containing:
Task
: Describes the task (“Account Disabled”).
Time
: The time the event was created.
DC
: The domain controller where the event occurred.
Name
: The display name of the disabled account.
Username
: The username of the disabled account.
Admin
: The account of the administrator who performed the action.
$ReturnInfo | Export-Csv $OutCSVfile -NoClobber -NoTypeInformation -Append
- Exporting Results
- Export-Csv: Exports the
$ReturnInfo
array to a CSV file specified by $OutCSVfile
.
-NoClobber
prevents overwriting existing files.
-NoTypeInformation
omits type information from the CSV. That’s the crappy line that sucks at the top of csvs that powershell 5 likes to add. You don’t ahve to do this if you are using powershell 7.
-Append
adds the results to the file without overwriting it.
By understanding each part of this script, you can tailor it to your specific needs. Whether you’re dealing with multiple servers or need a different time range, you now have the tools to make those adjustments. From here, you can make scheduled tasks that points to the required devices and such. We will cover that next week.
In the end
Auditing disabled accounts in Active Directory is like keeping a vigilant eye on the silent guardians of your network. It’s a crucial step to ensure that your environment remains secure and compliant. With the PowerShell script we’ve walked through, you now have the tools to monitor when an account was disabled and by whom, saving you from potential security breaches and compliance headaches.
Remember the story of the help desk technician who accidentally disabled the CFO’s account? That incident was a wake-up call, highlighting the importance of regular audits. By setting up a scheduled task to run this script, you can prevent similar scenarios in the future. You’ll have clear, reliable records that can help you quickly identify and rectify mistakes, keeping your network safe and your users happy.
Regularly auditing disabled accounts isn’t just about avoiding problems; it’s about creating a culture of diligence and responsibility. It’s about taking proactive steps to manage your AD environment effectively. Whether you’re a seasoned sysadmin or new to the role, these practices are essential in maintaining a robust and secure network.
So, take a moment to implement these steps. Set up the script, configure the scheduled task, and rest easy knowing you’ve added a solid layer of protection to your network. Your future self, and your organization, will thank you.
What we can learn as a person?
Disabled accounts linger around and sometimes they can have emails and more attached to them. But they are not active. When I was working with the MSP, I often found ADs with a lot of these accounts and no documentation. Why were they disabled, and left there? Was it some compliance or something else?
Well, in our life, we have something like disabled accounts. They don’t activly hurt us, but over time they can add up and cause issues. That’s small truama. Some therapist call it death by a tousand paper cuts. By themselves, they are not damaging enough to cause PTSD or anything along those likes, but over time, they can cause major issues. A good example of this is, you get spanked each sunday because you fail asleep in church. Some people start seeing churchs as a place of abuse while others embrace the church as safty. By itself a simple spanking doesn’t cause trauma, unless it’s really ugly, but over time, it can cause all kinds of issues.
The shame child
The best way to handle these micro trauma’s is to address the distorted emotions that are born from them. A good example of this is a child who was shamed for being evil at birth. Hearing this one time is nothing, but hearing this daily makes this child believe he is evil. This translates to shame. This shame can come out in many different forms. To heal, he has to come to the conculsion himself that he wasn’t evil from birth and this belief is wrong.
It’s time for him to delete those accounts of shame. Knowing where they come from is half the battle. If you don’t kno where the emotion comes from, how do you find the emotion? It is a discovery process. It’s a rough one too. Seek a licensed therapist for this and have a good community.
Additional reading
by David | Aug 26, 2022 | Information Technology, PowerShell, Resources
It’s time to Set Users’ MFA with a nice little function. This function is designed to gather information and set a user’s MFA with the method you want. It even allows you to reset and disable MFA. We are going to break this blog up a little differently. We will go through each area of the function as the breakdown. Let’s get started.
Function and Parameters
The first thing we are going to build out is the Function and the Parameters. The function command is like a wrapper for a script. This way you can add this to your PowerShell tool kit module.
Function Set-SHDUserMFA {
[CmdletBinding()]
param(
)
}
Parameters
User Principal Name
The parameters are where people select items that they want. We have a few here. The First parameter is the User Principal Name. This is like an email address. This parameter is a List of strings. Basically, you are allowed to add more than one user name to this field. To make life easier we have set a Parameter set name. The PSN is called UPN. So the end user can either type UPN or UserPrincipalName for this parameter. This parameter is Mandatory.
Function Set-SHDUserMFA {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, ParameterSetName = 'UPN', Position = 0),ValueFromPipeline = $true,ValueFromPipelineByPropertyName = $true,][string[]]$UserPrincipalName,
)
}
Status
Afterward, The status parameter allows you to set the MFA status that you want. Here we have Enabled, Disable, Enforced, and Reset. The Enabled will enable MFA. Disable of course disables. Enforced will skip the text and go straight to the Apps. Finally, the reset will reset all the MFA token flags. This is how you Set Users’ MFA. This parameter isn’t mandatory.
Function Set-SHDUserMFA {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, ParameterSetName = 'UPN', Position = 0)][string[]]$UserPrincipalName,
[Parameter(Mandatory = $false)][validateset("Enabled", "Disable", "Enforced", "Reset")][string]$Status,
)
}
Info
Finally, we have the Info switch. This switch tells the script to produce an in-depth MFA report on the user. This parameter is not mandatory. We choose not to make it mandatory because we might not care.
Function Set-SHDUserMFA {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, ParameterSetName = 'UPN', Position = 0)][string[]]$UserPrincipalName,
[Parameter(Mandatory = $false)][validateset("Enabled", "Disable", "Enforced", "Reset")][string]$Status,
[Parameter()][Switch]$Info
)
}
Begin
PowerShell Version
Chiefly, I stated that we were targeting one section at a time. Here in the begin, we will check the environment that we are working with. The MSOnline module only runs in PowerShell 5 and not PowerShell 7. Thus we need to check. Thus, we use the PS Version Table variable. This will produce the PowerShell version number. We can test against that and end the script if the user is using PowerShell 7. In the below example, we are using the write-error to let the user know what’s going on.
#Checks PS version
if ($PSVersionTable.psversion.major -ne 5) {
Write-Error "Your Powershell Version is $($PSVersionTable.psversion.major). Msonline service only works on Powershell 5. Ending."
end
}
Module Test
Aftward, we test the MSOnline module. The Get-InstalledModule tests the installation status of MSOnline. Running MSOnline command tests the status of the module load. Afterward, we either connect or error out.
#Checks to see if the module is installed if not, tells the end user to install.
if (Get-InstalledModule -name MSOnline -ErrorAction SilentlyContinue) {
#Checks to see if the msolservice if it isn't connected, we connect
if (-not (Get-MsolDomain -ErrorAction SilentlyContinue)) {
Connect-MsolService
}
} else {
Write-Error "MSOnline Services are not installed. Please install the MSOnline services with the following command `n Install-module MSOnline `n"
}
Process – Set Users’ MFA
Confirming the User
Next, we start the process section. The process is where most of the meat and potatoes are. Firstly we have the User Principal Name loop. This loop is very important. The parameter we created beforehand has multiple possible inputs. Thus, it’s best to loop through those possible inputs. We are going to call the Internal variable UPN.
foreach ($UPN in $UserPrincipalName) {
#Do Stuff Yall
}
After that, we will be building out a try/catch to test if the user exists. The try/catch will give us the ability to test the user without blowing up the script. Get-MsolUser is the command we will be using with an error action of “stop”. The catch will contain the error write-out.
#Checks if the user exists, if not, ends the upn and writes an error.
try {
$User = Get-MsolUser -UserPrincipalName $UPN -ErrorAction Stop
} catch {
Write-Error $_.Exception.Message
}
The Switch
Now that we have the user verified, it’s time to move forward. We start with the switch. The switch is a process of if statements but formatted nicely. In our case, we will be building the switch of the status parameter. If the user selected blah, then we take blah action. Here is the basic structure of a switch. It’s switch and the parameters name. Then each possible answer to that parameter. The status is a “validate set” parameter. This means all the answers are inside the parameter.
switch ($Status) {
#If enabled then we enable mfa
'Enabled' {
#Do Something
}
'Enforced' {
#Do Something
}
'Reset' {
#Do Something
}
'Disable' {
#Do Something
}
}
Enabled
The enabled will enable the MFA of a target user. We went over some of this code in a previous blog. Firstly, we want to create a new object. This object is a Microsoft Online Administration object that focuses on Strong authentication requirements. Once we create this object we will assign properties different values. Finally, we use the Set-Msoluser to set the user accordingly.
$sar = New-Object -TypeName Microsoft.Online.Administration.StrongAuthenticationRequirement
$sar.RelyingParty = "*"
$sar.State = "Enabled"
Set-MsolUser -UserPrincipalName $UPN -StrongAuthenticationRequirements $sar
Enforced
On the other hand, We have enforced. Enforced forces the user to use an authentication app. We will follow the same path as before. Create the object, and set the properties. Then set the object to the user with the set-msoluser command. Notice the sar.state property.
$sar = New-Object -TypeName Microsoft.Online.Administration.StrongAuthenticationRequirement
$sar.RelyingParty = "*"
$sar.State = "Enforced"
Set-MsolUser -UserPrincipalName $UPN -StrongAuthenticationRequirements $sar
Reset
Before we created an object, this time we only need a command. We are using the Reset-Msolstrongauthenticationmethodbyupn. Don’t even try saying the command without spaces. This is a beast of a command, but it works. What it does is it resets the methods that the user uses to login in. If the user selected an authentication app, this will allow the user to set another one up. Great command if a user lost their phone.
Reset-MsolStrongAuthenticationMethodByUpn -UserPrincipalName $UPN
Disable
Finally, we have “disable”. Unlike before methods we will be setting the strong authentication requirements to NOTHING! ABSOLUTELY NOTHING! (UHF reference).
Set-MsolUser -UserPrincipalName $UPN -StrongAuthenticationRequirements @()
This is what the switch block looks like when fully put together.
switch ($Status) {
#If enabled then we enable mfa
'Enabled' {
$sar = New-Object -TypeName Microsoft.Online.Administration.StrongAuthenticationRequirement
$sar.RelyingParty = "*"
$sar.State = "Enabled"
Set-MsolUser -UserPrincipalName $UPN -StrongAuthenticationRequirements $sar
}
#if enforced, we enforce mfa
'Enforced' {
$sar = New-Object -TypeName Microsoft.Online.Administration.StrongAuthenticationRequirement
$sar.RelyingParty = "*"
$sar.State = "Enforced"
Set-MsolUser -UserPrincipalName $UPN -StrongAuthenticationRequirements $sar
}
#if reset, resets mfa
'Reset' { Reset-MsolStrongAuthenticationMethodByUpn -UserPrincipalName $UPN }
#if disable, it removes mfa requirements
'Disable' { Set-MsolUser -UserPrincipalName $UPN -StrongAuthenticationRequirements @() }
}
Info Flag
Grab user Info
Finally, the Info Flag piece. Here we are going to be gathering information about the user. It’s at the end of the command because we want the information after we set the user’s MFA. The first step we take is to grab user information. We do this with the Get-Msoluser command. “But couldn’t we use the previous $user grab?” The answer is no because we want the most up-to-date. We want to reflect on the changes we have made beforehand.
#Grabs the user information
$User = Get-MsolUser -UserPrincipalName $UPN -ErrorAction Stop
Confirm Strong Authentication Requirements
Afterward, we want to test this data. The first test is, does the user have strong authentication requirements. “Strongauthenticationrequirements” property is our target. Since the property has data, we place that data into the “MFAState” parameter. However, if it doesn’t, we put “Disabled” into this variable.
#If it has a strong authentication requirement we grab the state, if the state is blank, then we return disabled
if ($User.StrongAuthenticationRequirements) {
$MFAState = $User.StrongAuthenticationRequirements.State
} else {
$MFAState = 'Disabled'
}
Find the Default
Next, we want to grab the default method type. We do this with a where-object that searches for “isdefault”. Then we expand the method types.
#grabs the Strong authentication methods
$MethodType = $User.StrongAuthenticationMethods | Where-Object { $_.IsDefault -eq $true } | select-object -ExpandProperty MethodType
Determine the Default
This will produce a string if there is a default. However, it will produce null if there is not. So we test to see if the $MethodType has data. Once we do that we start another switch. I like switches. Inside this switch we are comparing the unique names to real names. This makes life easier and allows non-admin answers they can understand. Here is a list of names and their translations.
- OneWaySMS = SMS
- TwoWayVoiceMobile = Phone call
- PhoneAppOTP = TOTP
- PhoneAppNotification = Authenticator App
However, it’s none of these, we just say, disabled.
#if the methods are not blank, we find out which one is the right method. and make since of the code. If it is blank, we say disabled.
if ($MethodType) {
switch ($MethodType) {
'OneWaySMS' { $DefaultMethodType = 'SMS' }
'TwoWayVoiceMobile' { $DefaultMethodType = 'Call' }
'PhoneAppOTP' { $DefaultMethodType = 'TOTP' }
'PhoneAppNotification' { $DefaultMethodType = 'Authenticator App' }
}
} else {
$DefaultMethodType = 'Disabled'
}
PS Custom Object
Finally, the PS custom object. This is where we return the information the user wants. The PowerShell custom object will contain the following information, the username, display name, the mfa state, and the default method type.
[PSCustomObject]@{
UserPrincipalName = $User.UserPrincipalName
DisplayName = $User.DisplayName
MFAState = $MFAState
DefaultMethodType = $DefaultMethodType
}
The last thing we do is we null out the methodtypes. Sometimes PowerShell 5 will carry over these items in a loop.
#Nulls out the method type variable because we are in a loop.
$MethodType = $null
Conclusion
When you Set Users’ MFA, you make people mad. However, life gets way more secure. This function is inside my tool belt and it helps me out almost every day. I can push hundreds of users through it quickly. I will leave you with the script itself.
The Script
Function Set-SHDUserMFA {
<#
.SYNOPSIS
Sets the MFA status of a user.
.DESCRIPTION
The script can grab the Status information of MFA of a user. It can set the users mfa to enabled, enforced, disabled, and even reset the mfa of a user.
.PARAMETER UserPrincipalName
A list of strings, the user principal names of the users you wish to preform the actions against.
.PARAMETER SetStatus
The action you wish to preform
Enabled: Enables MFA
Disable: Disables MFA
Reset: Resets MFA
Enforced: Enforces MFA
.PARAMETER Info
Grabs UPN, Displayname, The MFA state, and Default Method Type
.NOTES
Name: Set-SHDUserMFA
Author: therandomadmin
Version: 1.0
DateCreated: 8/3/2022
.LINK
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true, ParameterSetName = 'UPN', Position = 0,ValueFromPipeline = $true,valueFromPipelineByPropertyName = $true,)][string[]]$UserPrincipalName,
[Parameter(Mandatory = $false)][validateset("Enabled", "Disable", "Enforced", "Reset")][string]$Status,
[Parameter()][Switch]$Info
)
BEGIN {
#Checks PS version
if ($PSVersionTable.psversion.major -ne 5) {
Write-Error "Your Powershell Version is $($PSVersionTable.psversion.major). Msonline service only works on Powershell 5. Ending."
end
}
#Checks to see if the module is installed if not, tells the end user to install.
if (Get-InstalledModule -name MSOnline -ErrorAction SilentlyContinue) {
#Checks to see if the msolservice if it isn't connected, we connect
if (-not (Get-MsolDomain -ErrorAction SilentlyContinue)) {
Connect-MsolService
}
}
else {
Write-Error "MSOnline Services are not installed. Please install the MSOnline services with the following command `n Install-module MSOnline `n"
}
}
PROCESS {
#Starts the UPN loop
foreach ($UPN in $UserPrincipalName) {
#Checks if the user exists, if not, ends the upn and writes an error.
try {
$User = Get-MsolUser -UserPrincipalName $UPN -ErrorAction Stop
}
catch {
Write-Error $_.Exception.Message
}
#Checks status
switch ($Status) {
#If enabled then we enable mfa
'Enabled' {
$sar = New-Object -TypeName Microsoft.Online.Administration.StrongAuthenticationRequirement
$sar.RelyingParty = "*"
$sar.State = "Enabled"
Set-MsolUser -UserPrincipalName $UPN -StrongAuthenticationRequirements $sar
}
#if enforced, we enforce mfa
'Enforced' {
$sar = New-Object -TypeName Microsoft.Online.Administration.StrongAuthenticationRequirement
$sar.RelyingParty = "*"
$sar.State = "Enforced"
Set-MsolUser -UserPrincipalName $UPN -StrongAuthenticationRequirements $sar
}
#if reset, resets mfa
'Reset' { Reset-MsolStrongAuthenticationMethodByUpn -UserPrincipalName $UPN }
#if disable, it removes mfa requirements
'Disable' { Set-MsolUser -UserPrincipalName $UPN -StrongAuthenticationRequirements @() }
}
#if you flip the flag for info we grab the info.
if ($Info) {
#Grabs the user information
$User = Get-MsolUser -UserPrincipalName $UPN -ErrorAction Stop
#If it has a strong authentication requirement we grab the state, if the state is blank, then we return disabled
if ($User.StrongAuthenticationRequirements) {
$MFAState = $User.StrongAuthenticationRequirements.State
}
else {
$MFAState = 'Disabled'
}
#grabs the Strong authentication methods
$MethodType = $User.StrongAuthenticationMethods | Where-Object { $_.IsDefault -eq $true } | select-object -ExpandProperty MethodType
#if the methods are not blank, we find out which one is the right method. and make since of the code. If it is blank, we say disabled.
if ($MethodType) {
switch ($MethodType) {
'OneWaySMS' { $DefaultMethodType = 'SMS' }
'TwoWayVoiceMobile' { $DefaultMethodType = 'Call' }
'PhoneAppOTP' { $DefaultMethodType = 'TOTP' }
'PhoneAppNotification' { $DefaultMethodType = 'Authenticator App' }
}
}
else {
$DefaultMethodType = 'Disabled'
}
#creates a ps object and displays all the information collected
[PSCustomObject]@{
UserPrincipalName = $User.UserPrincipalName
DisplayName = $User.DisplayName
MFAState = $MFAState
DefaultMethodType = $DefaultMethodType
}
#Nulls out the method type variable because we are in a loop.
$MethodType = $null
}
}
}
END {}
}
More Links:
by David | Nov 3, 2021 | Help Desk, Information Technology, PowerShell
How does one enable, disable, and reset a user’s MFA in Office 365? I was surprised by how much is required for enabling MFA.
Enable MFA
The first thing we do is Get the User from the Get-MsolUser.
$user = Get-MsolUser -UserPrincipalName $UPN
Next, we create a Strong Authentication object using the New-Object.
$SAR = New-Object -TypeName Microsoft.Online.Administration.StrongAuthenticationRequirement
Now the object is created, you can review the object by using the Get-Member command. This object has 4 properties and 4 methods. We can now edit the properties. We will edit the RelyingParty and state.
$sar.RelyingParty = "*"
$sar.State = "Enabled"
Now we place the edited items into the user’s account.
$sarobject = @($sa)
Set-MsolUser -UserPrincipalName $user.Userprincipalname -StrongAuthenticationRequirements $sarobject
The Script
$user = Get-MsolUser -UserPrincipalName $UPN
$SAR = New-Object -TypeName Microsoft.Online.Administration.StrongAuthenticationRequiremen $sar.RelyingParty = "*"
$sar.State = "Enabled"
$sarobject = @($sa)
Set-MsolUser -UserPrincipalName $user.Userprincipalname -StrongAuthenticationRequirements $sarobjec
Disable MFA
Disabling MFA is extremely easy compared to enabling it. It’s as simple as putting a blank object inside the strong authentication requirements flag.
Set-MsolUser -UserPrincipalName $user.Userprincipalname -StrongAuthenticationRequirements @()
Reset MFA
The last one is to reset the MFA. Microsoft created a commandlet just for this case. The command is Reset-MsolStrongAuthenticationMethodByUpn.
Reset-MsolStrongAuthenticationMethodByUpn -UserPrincipalName $user.Userprincipalname
I hope this helps out.