New-xOTP_User.ps1
<#
.SYNOPSIS Creates SecureMFA.com OTP accounts in SQL database. .DESCRIPTION preloads SecureMFA OTP accounts in SQL database for manual configuration. 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", "data_encryption_passphrase": "d9GhT=7=Ox8-+LaZ" } .PARAMETER Disable Disbales user's OTP account in the database. .NOTES Version: 1.0.1.1 Author: SecureMfa.com Creation Date: 18/08/2020 Purpose/Change: New .EXAMPLE C:\PS> New-xOTP_User -upn test1@adatum.labnet This command will import SecureMFA_SupportTools.json file from current directory and creates OTP account for test1 user. Command will show secretKey output for user which can be used for manual setup with TOTP Authenticator app. .EXAMPLE C:\PS> New-xOTP_User -upn test1@adatum.labnet -Encrypt This command will import SecureMFA_SupportTools.json file from current directory and creates OTP account with encrypted secret for test1 user. Command will show secretKey output for user which can be used for manual setup with TOTP Authenticator app. #> #> Function New-xOTP_User { Param ( [Parameter(Mandatory=$true,ParameterSetName="Default")] [String]$upn = $null, [Parameter(Mandatory=$false, ParameterSetName="Default")] [Switch]$Encrypt, [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 create OTP account 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 creating new OTP account if(!($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 $data_encryption_passphrase = $json.data_encryption_passphrase; $sqlConnectString = "server=" + $sqlinstance + ";initial catalog=" + $sqldbname + ";integrated security=" + $sqlintegratedsecurity + ";User ID=" + $sqluseraccount + ";Password=" + $sqluserpassword; #Get user's input if required write-host " -- New OTP User utility for $environment --" -ForegroundColor Green -NoNewline write-host " [New 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 "New OTP account cannot be created because user $upn exist with status: $UserStatusValue `nPlease hardreset user to delete all OTP data before progressing with a new OTP account creation." -ForegroundColor Cyan } else { [String]$sekretKey = ""; if($Encrypt) {$isSuccess = [SecureMFA_SupportTools.OTP]::NewUser($upn, $sqlConnectString, $true , $data_encryption_passphrase, $env:username, $env:computername, [ref] $sekretKey)} else {$isSuccess = [SecureMFA_SupportTools.OTP]::NewUser($upn, $sqlConnectString, $false , $data_encryption_passphrase, $env:username, $env:computername , [ref] $sekretKey)} if ($isSuccess) { write-host "OTP account for user: $upn has been created by: $env:username from computer: $env:computername" write-host "$upn secretKey: $sekretKey" -ForegroundColor Cyan write-host "NOTE: Above secretkey is displayed only once. To recover it you will need to hardreset OTP account and create a new one again." -ForegroundColor yellow write-host "`n--- SET UP THE AUTHENTICATOR APP ---`n" write-host "1) Install TOTP Authenticator app on your iOS or Android device. `nThis can Microsoft Authenticator , Google Authenticator, Symantec VIP etc . Any OTP authentication app which is compatible with Time-Based One-Time Password algorithm defined in RFC6238." write-host "2) In the Authenticator app enter a setup-key/code manually. `nProcess may be slightly different for various authenticators" write-host "3) When prompted, enter following details and click Continue. `n a) A name for the account (for example UPN value) `n b) The secret key provided displayed on the screen." write-host "4) At this point Authenticator app should start generating OTP codes on your mobile device." } } } #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” } } } |