Reset-xOTP.ps1

<#
     .SYNOPSIS
        Resets SecureMFA.com OTP accounts in SQL database.
    .DESCRIPTION
        Resets SecureMFA OTP accounts.
        Dependencies:
            * System which executes a script must have Microsoft Framework 4.6.1 and above installed.
            * SecureMFA_SupportTools.dll file must be present in script directory.
            * SecureMFA_SupportTools.json configuration file must be present in script directory.
                                     
            Bellow is a sample of valid Json config file with minimal configuration required for script to work:
                {
                "sql_server": "asqlaol1.adatum.labnet",
                "sql_database": "SecureMfaOTP",
                "ui_input_text": "Please enter user's UPN"
                "ui_environment": "MyCompany"
                }
 
    .PARAMETER HardReset
        Deletes user OTP configuration from the database.
 
    .NOTES
        Version: 1.0.0.4
        Author: SecureMfa.com
        Creation Date: 19/12/2019
        Purpose/Change: HardReset bugfix
   
    .EXAMPLE
        C:\PS> Reset-xOTP
 
        This command will import SecureMFA_SupportTools.json file from current directory and execute soft reset command for OTP user.
        Action is not destructive as it will allow user to see QR code during logon. This will help user to get his QR code on for configuration.
 
    .EXAMPLE
        C:\PS> Reset-xOTP -HardReset
 
        This command will import SecureMFA_SupportTools.json file from current directory and execute hard reset command for OTP user.
        Action will delete user's QR configuration from database. New QR code will be generated during logon for the user.
     
#>


#>
Function Reset-xOTP {
Param
(
    [Parameter(Mandatory=$false,ParameterSetName="Default")]
    [String]$upn = $null,
    [Parameter(Mandatory=$false, ParameterSetName="Default")]
    [Switch]$HardReset

)

DynamicParam
{
    # create a dictionary to return, and collection of parameters
    $paramDictionary = New-Object -Type System.Management.Automation.RuntimeDefinedParameterDictionary
    $attributeCollection = New-Object -Type System.Collections.ObjectModel.Collection[System.Attribute]
 
    # create a new [string] parameter for all parameter sets, and decorate with a [ValidateSet]
    $dynParam = New-Object -Type System.Management.Automation.RuntimeDefinedParameter("Profile", [String], $attributeCollection)
    $attributes = New-Object System.Management.Automation.ParameterAttribute
    $fname = "Profiles.json"
    $paramOptions = New-Object System.Management.Automation.ValidateSetAttribute -ArgumentList (ConvertFrom-Json (Get-Content (join-path $PSScriptRoot $fname) -Raw))
 
    $attributeCollection.Add($attributes)
    $attributeCollection.Add($paramOptions)
    $paramDictionary.Add("Profile", $dynParam)
 
    return $paramDictionary
}

Process
{
    #Static Parameters
    $Event_Source = "SecureMFA_SupportTools"
    [Int16]$UserStatus = 0;
    $ConfirmPreference="high"
    $decision_Validation = $null

    $message  = "Please confirm if you want to execute HardRest on user [$upn]"            
    $question = 'Please confirm?'
    $choices = New-Object Collections.ObjectModel.Collection[Management.Automation.Host.ChoiceDescription]
    $choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList '&Yes'))
    $choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList '&No'))

    #Confirmation for destructive action - hardreset
    if($HardReset) { $decision_Validation = $Host.UI.PromptForChoice($message, $question, $choices, 0) ; if ($decision_Validation -eq 1 ) {break} }

    #Checking Dependencies
    #EventLog source dependency
    $ErrMsg = "ResetOTP EventLog source is missing. Please execute following PS command 'New-EventLog -Source SecureMFA_SupportTools -LogName Application' on the system before using the app."
    if (((Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Services\EventLog\Application).pschildname | where { $_ -eq $Event_Source} | measure).Count -eq 0) 
    {write-host $ErrMsg -ForegroundColor red; pause; break}
    #Config file dependency
    if ( $PSBoundParameters.Keys.Contains("Profile") )
    {
        $configfile = (Join-Path -Path $PSScriptRoot -ChildPath ($PSBoundParameters.Profile + '_SecureMFA_SupportTools.json'))
    }
    else {$configfile = (Join-Path -Path $PSScriptRoot -ChildPath SecureMFA_SupportTools.json)}
    #Test config file path.
    $ErrMsg = "$configfile file is missing. Please copy a file to script directory and try again."
    if (!(Test-Path $configfile)) { write-host $ErrMsg -ForegroundColor red; pause; break }
    #DLL file dependency
    $dllpath = (Join-Path -Path $PSScriptRoot -ChildPath SecureMFA_SupportTools.dll)
    $ErrMsg = "$configfile file is missing. Please copy a file to script directory and try again."
    if (!(Test-Path $dllpath)) { write-host $ErrMsg -ForegroundColor red; pause; break }

    #Read JSON file Configuration
    $json = Get-Content -Raw $configfile | ConvertFrom-Json
    $sqlinstance = $json.sqlserver
    $sqldbname = $json.sqldbname
    $sqlintegratedsecurity = $json.sqlintegratedsecurity
    $sqluseraccount = $json.sqluseraccount
    $sqluserpassword = $json.sqluserpassword
    $input_text = $json.ui_input_text
    $environment = $json.ui_environment
    $sqlConnectString = "server=" + $sqlinstance + ";initial catalog=" + $sqldbname + ";integrated security=" + $sqlintegratedsecurity + ";User ID=" + $sqluseraccount + ";Password=" + $sqluserpassword;

    #Get user's input if required
    write-host " -- Reset OTP utility for $environment --" -ForegroundColor Green -NoNewline
    if ($HardReset) {write-host " [HardReset] " -ForegroundColor red} else {write-host " [SoftReset] " -ForegroundColor yellow}
    if ($upn -eq $null) { Do { $upn = read-host $input_text} while ($upn -eq "")}

    Try {

        [System.Reflection.Assembly]::LoadFile($dllpath) | Out-Null 
    
        if ([SecureMFA_SupportTools.OTP]::isUserExist($upn, $sqlConnectString, [ref] $UserStatus)) 
            {
            write-host "User status: $UserStatus" -ForegroundColor Cyan
            #Softreset for active user
            if (!($HardReset) -and ($UserStatus -gt 0)) 
                {
                $isSuccess = [SecureMFA_SupportTools.OTP]::SetUserSoftReset($upn, $sqlConnectString, $env:username, $env:computername)
                if ($isSuccess) {write-host "User: $upn has been SoftReset by: $env:username from computer: $env:computername"} 
                }
            #HardReset
            elseif (($HardReset) -and ($UserStatus -gt 0))
                {
                $isSuccess = [SecureMFA_SupportTools.OTP]::SetUserHardReset($upn, $sqlConnectString, $env:username, $env:computername)
                if ($isSuccess) {write-host "User: $upn has been HardReset by: $env:username from computer: $env:computername"} 
                }
            #SoftReset for non active user
            else
                {
                 write-host "SoftReset cannot be executed for User: [$upn] , because user have not logged in yet."
                } 
             
            } 
        
        else 
            {
             write-host "User: [$upn] doesn’t exist in OTP database. "
            }
        }

    #On error acction
    catch [System.Exception] { 
            $completed = get-date
            $line = $_.InvocationInfo.ScriptLineNumber
            $msg = $_.Exception.Message 

            Write-Host -ForegroundColor Red "Error: $msg"
            Write-EventLog –LogName Application –Source $Event_Source –EntryType Error –EventID 5559 –Message “$msg Executed by: $env:username Computer: $env:computername Line: $line”                 
            }  
    }
}