Create_SecureMFA_OTP_AD_attributes.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 |
#THIS ONLY REQUIRES IF YOU PLAN TO RUN SecureMFA OTP Provider in AD MODE. #You need to execute this script on Read-Write domain controller with AD account which is member of Schema Admins group. #SecureMFA OTP provider when operates in AD mode ("auth_mode": "AD") it requires custom Active Directory (AD) attributes to be created to store OTP data for the user. #This action cannot be undone and needs to be tested in your TEST domain first before moving into PRODUCTION. #New AD Schema Attributes will be added into custom SecureMFA Auxiliary Class and that Class will be added into Existing User Class as AD Schema best practices suggest. #OID numbers for custom attributes are from SecureMFA Private Enterprise range assigned by iana.org . Which do not overlap with other vendors OIDs numbers used to create custom AD attributes. function ADDADSchemaAttributetoClass($SchemaAttribute) { [bool]$reset = $true $attempts=30 $sleepInSeconds=180 do { try { $reset = $true Write-Host "Adding $SchemaAttribute into SecureMFA Auxiliary Class.($attempts)" -ForegroundColor Green #Get AD Schema details $dse = Get-ADRootDSE $schemaPath = $dse.schemaNamingContext $type = 'attributeSchema' #ADD AD Schema Attribute To SecureMFA Class $Schema = Get-ADObject -SearchBase $schemaPath -Filter "name -eq `'SecureMFA`'" $Schema | Set-ADObject -Add @{mayContain = $SchemaAttribute} -ErrorAction stop } catch [Exception] { Write-Host "Waiting for AD schema attribute refresh ... Please note this action can take a few minutes to complete." -ForegroundColor Yellow $reset = $false } $attempts-- if ($attempts -gt 0 -and $reset -eq $false) { sleep $sleepInSeconds } } until ($attempts -le 0 -or $reset -eq $true) return $reset } function ADDADAttribute{ Param( [parameter(Mandatory)] [String]$Name, [Parameter(Mandatory)] [String]$Description, [parameter(Mandatory)] [String]$AttributeID, [Parameter(Mandatory)] [ValidateSet('String','Int','Time','Boolean')] [String]$AttributeType, [Parameter()] [Boolean]$IsSingleValued = $True ) #Attribute values by type https://technet.microsoft.com/en-us/library/cc961740.aspx switch ($AttributeType) { 'String' {$attributeSyntax = '2.5.5.4'; $omSyntax = 20} 'Int' {$attributeSyntax = '2.5.5.9'; $omSyntax = 2} 'Time' {$attributeSyntax = '2.5.5.11'; $omSyntax = 24} 'Boolean' {$attributeSyntax = '2.5.5.8'; $omSyntax = 1} Default {} } #AD atribute params------- $attributes = @{ lDAPDisplayName = $Name; attributeId = $AttributeID; oMSyntax = $omSyntax; attributeSyntax = $attributeSyntax; isSingleValued = $IsSingleValued; adminDescription = $Description; searchflags = 0 } #If AD Attribute doesn't exist create one. if(!(Get-ADObject -SearchBase "$((Get-ADRootDSE).SchemaNamingContext)" -Filter {lDAPDisplayName -eq $Name})) { New-ADObject -Name $Name -Type $type -Path $schemapath -OtherAttributes $attributes Write-host "AD attribute $Name has been created." -ForegroundColor Green } Else {Write-host "AD attribute $Name allready exist in AD." -ForegroundColor yellow} } #START Script #Get AD Schema details $dse = Get-ADRootDSE $schemaPath = $dse.schemaNamingContext $type = 'attributeSchema' #Create a New AD Schema Auxiliary Class for SecureMFA $Name = 'SecureMFA' $attributes = @{ governsId = '1.3.6.1.4.1.54153.2.1000' adminDescription = 'SecureMFA Class to host OTP attributes' objectClass = 'classSchema' ldapDisplayName = $Name adminDisplayName = $Name objectClassCategory = 3 systemOnly = $FALSE # subclassOf: top subclassOf = "2.5.6.0" # rdnAttId: cn rdnAttId = "2.5.4.3" } #If Schema Auxiliary Class for SecureMFA doesn't exist create one. if(!(Get-ADObject -SearchBase (Get-ADRootDSE).SchemaNamingContext -Filter {name -like "SecureMFA"})) { New-ADObject -Name $Name -Type 'classSchema' -Path $schemapath -OtherAttributes $attributes Write-host "A New AD Schema Auxiliary Class SecureMFA has been created." -ForegroundColor Green } Else {Write-host "Auxiliary Class SecureMFA allready exist in AD." -ForegroundColor Yellow} #Add AD Schema SecureMFA Auxiliary Class To default User Class $auxClass = Get-ADObject -SearchBase $schemaPath -Filter "name -eq `'$Name`'" -Properties governsID $classToAddTo = Get-ADObject -SearchBase $schemaPath -Filter "name -eq `'user`'" $classToAddTo | Set-ADObject -Add @{auxiliaryClass = $($auxClass.governsID)} #START Creating AD attributes ADDADAttribute -Name 'sMFA-OTP-secret' -Description 'User Secret attribute' -AttributeID '1.3.6.1.4.1.54153.2.1000.00001' -AttributeType String -IsSingleValued $true ADDADAttribute -Name 'sMFA-OTP-logon' -Description 'User logon status attribute' -AttributeID '1.3.6.1.4.1.54153.2.1000.00002' -AttributeType Int -IsSingleValued $true ADDADAttribute -Name 'sMFA-OTP-lastlogon' -Description 'User laslogon attribute' -AttributeID '1.3.6.1.4.1.54153.2.1000.00003' -AttributeType Time -IsSingleValued $true ADDADAttribute -Name 'sMFA-OTP-logoncount' -Description 'User logoncount attribute' -AttributeID '1.3.6.1.4.1.54153.2.1000.00004' -AttributeType Int -IsSingleValued $true ADDADAttribute -Name 'sMFA-OTP-failedlogoncount' -Description 'User failedlogoncount attribute' -AttributeID '1.3.6.1.4.1.54153.2.1000.00005' -AttributeType Int -IsSingleValued $true ADDADAttribute -Name 'sMFA-OTP-failedlastlogon' -Description 'User failedlastlogon attribute' -AttributeID '1.3.6.1.4.1.54153.2.1000.00006' -AttributeType Time -IsSingleValued $true ADDADAttribute -Name 'sMFA-OTP-failedcode' -Description 'User failedcode attribute' -AttributeID '1.3.6.1.4.1.54153.2.1000.00007' -AttributeType String -IsSingleValued $true ADDADAttribute -Name 'sMFA-OTP-logonip' -Description 'User logonip attribute' -AttributeID '1.3.6.1.4.1.54153.2.1000.00008' -AttributeType String -IsSingleValued $true ADDADAttribute -Name 'sMFA-OTP-useragent' -Description 'User useragent attribute' -AttributeID '1.3.6.1.4.1.54153.2.1000.00009' -AttributeType String -IsSingleValued $true ADDADAttribute -Name 'sMFA-OTP-interval' -Description 'User interval attribute' -AttributeID '1.3.6.1.4.1.54153.2.1000.00010' -AttributeType Int -IsSingleValued $false #Refresh AD schema $dse.schemaUpdateNow = $true Write-host "Refreshing AD Schema." -ForegroundColor Green [bool]$reset = $false #START Adding AD Schema Attributes to User Class: @("sMFA-OTP-secret","sMFA-OTP-logon","sMFA-OTP-lastlogon","sMFA-OTP-logoncount","sMFA-OTP-failedlogoncount","sMFA-OTP-failedlastlogon","sMFA-OTP-failedcode","sMFA-OTP-logonip","sMFA-OTP-useragent","sMFA-OTP-interval") | foreach { $SchemaAttribute = $_.trim() $reset = ADDADSchemaAttributetoClass $SchemaAttribute if($reset) {Write-host "AD attribute $SchemaAttribute have been added into SecureMFA Auxiliary Class." -ForegroundColor Green} else {Write-host "AD attribute $SchemaAttribute has failed to add into SecureMFA Auxiliary Class. Please try again later when AD replication for attributes is completed across your environment." -ForegroundColor red} } #Refresh AD schema $dse.schemaUpdateNow = $true write-host "Custom sMFA attributes have been created. Please note that depending on AD replication policies it may take a while to show a new custom attribute for user object in AD when using GUI tools." -ForegroundColor Cyan pause |