Set-xOTP.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
<#
     .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”                 
            }    

    }
}