Set-xOTP.ps1

<#
     .SYNOPSIS
        Sets SecureMFA.com OTP accounts state in SQL database.
    .DESCRIPTION
        Sets SecureMFA OTP accounts to disabled or enabled state.
        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 Disable
        Disbales user's OTP account in the database.
 
    .NOTES
        Version: 1.0.0.5
        Author: SecureMfa.com
        Creation Date: 04/04/2020
        Purpose/Change: New
   
    .EXAMPLE
        C:\PS> Set-xOTP
 
        This command will import SecureMFA_SupportTools.json file from current directory and sets OTP user state as enabled.
        It will enable user for authentication.
 
    .EXAMPLE
        C:\PS> Set-xOTP -Disable
 
        This command will import SecureMFA_SupportTools.json file from current directory and sets OTP user state as disbaled.
        It will disable user for authentication.
     
#>


#>
Function Set-xOTP {
Param
(
    [Parameter(Mandatory=$true,ParameterSetName="Default")]
    [String]$upn = $null,
    [Parameter(Mandatory=$false, ParameterSetName="Default")]
    [Switch]$Disable,
    [Switch]$Unlock,
    [Switch]$Force

)

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 disable OTP for 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 before disabling account
    if($Disable -and !($Force)) { $decision_Validation = $Host.UI.PromptForChoice($message, $question, $choices, 0) ; if ($decision_Validation -eq 1 ) {break} }

    #Checking Dependencies
    #EventLog source dependency
    $ErrMsg = "Set OTP User 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 " -- Set OTP User utility for $environment --" -ForegroundColor Green -NoNewline
    if ($Disable) {write-host " [Disable OTP User] " -ForegroundColor red} else {write-host " [Enable OTP User] " -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)) 
            {
        
            switch($UserStatus){
                   0 {$UserStatusValue = "Never logged in."}
                   1 {$UserStatusValue = "Enabled."}
                   2 {$UserStatusValue = "Disabled."}
            }        
            write-host "User status before change: $UserStatusValue" -ForegroundColor Cyan   

            #Enable for active user
            if (!($Disable) -and !($Unlock) -and ($UserStatus -gt 0)) 
                {
                $isSuccess = [SecureMFA_SupportTools.OTP]::SetUserEnable($upn, $sqlConnectString, $env:username, $env:computername)
                if ($isSuccess) {write-host "User: $upn has been enabled by: $env:username from computer: $env:computername"} 
                }
            #Disable User
            elseif (($Disable) -and ($UserStatus -gt 0))
                {
                $isSuccess = [SecureMFA_SupportTools.OTP]::SetUserDisable($upn, $sqlConnectString, $env:username, $env:computername)
                if ($isSuccess) {write-host "User: $upn has been disabled by: $env:username from computer: $env:computername"} 
                }

            #Unlock User
            elseif (($Unlock) -and ($UserStatus -gt 0))
                {
                $isSuccess = [SecureMFA_SupportTools.OTP]::SetUserUnlock($upn, $sqlConnectString, $env:username, $env:computername)
                if ($isSuccess) {write-host "User: $upn has been unlocked by: $env:username from computer: $env:computername"} 
                }
            #Enable for non active user
            else
                {
                 write-host "Account status cannot be chnaged 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”                 
            }    

    }
}