Script Repository


Import new user account from email message

April 30, 2020
1179

The script imports a user account from an email message sent to a specific mailbox. For the script to be able to download an email, it needs to have a certain predefined subject, and the Adaxes service account must have full access to the mailbox where it is sent.

See Also: Import new and updated users from email message in CSV format.

For details on how to schedule import of users, see Schedule Import of Users from a CSV File. On step 6, insert this script.

To be able to launch the script, download and install Microsoft Exchange Web Services Managed API on the computer where Adaxes service runs. Also, you need to install the Adaxes PowerShell Module for Active Directory.

The email message body must conform to a certain format.

Message Body Sample:

sn: Robertson
givenName: William
sAMAccountName: wrobertson
description: Sales Manager at New York Office
physicalDeliveryOfficeName: New York
AccountPassword: secret
manager: Stephen Jones

Parameters:

  • $exchangeWebServiceDllPath - specifies the full path to the Microsoft Exchange Web Services dll module;
  • $exchangeServer - specifies the fully qualified domain name (FQDN) of your Exchange Server;
  • $searchSubject - specifies the subject of emails that contain user account information;
  • $mailboxMailAdress - specifies the email address of the mailbox where the emails will be sent;
  • $delimiter - specifies the delimiter between AD attribute name and AD attribute value in the emails;
  • $accountPasswordColumn - specifies the name of the column that contains account passwords;
  • $otherPropertiesMap - specifies a map of property names in the email messages and LDAP display names of the corresponding user account properties. If a property name is not specified in this list, it will be used as a LDAP display name of a property;
  • $aDObjectProperties - specifies a list of headers of the columns that contain references to other AD objects, such as, for example, Manager, Secretary or Assistant. Objects can by specified in these columns by their:
    • Distinguished Name
    • Full name (cn attribute)
    • Display name
Edit Remove
PowerShell
Import-Module Adaxes

# Exchange settings
$exchangeWebServiceDllPath = "C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll" # TODO: modify me
$exchangeServer = "example.com" # TOOD: modify me. If $NULL connect to Exchange Online
$searchSubject = "New User" # TOOD: modify me
$mailboxMailAddress = "recipient@example.com" # TOOD: modify me

# Mail message settings
$delimiter = ":"
$accountPasswordColumn = "AccountPassword" # TODO: modify me
$otherPropertiesMap = @{
    "Job Title" = "title";
    "First Name" = "givenName";
    "Last Name" = "sn";
} # TODO: modify me. Use this parameter if property name is not equal to LDAP display name of attribute. Example $otherPropertiesMap = @{"<Property Name>" = "ldapName";}
$aDObjectNameProperties = @("Manager") # TODO: modify me. Example $aDObjectNameProperties = @("<column 1>", "<column 2>")

Function Create-User ($userInfoImported)
{
    # Parse user information
    # Create hash table
    $userInfo = @{}
    $server = $Context.GetObjectDomain("%distinguishedName%")

    # Split input string into property/value pairs
    $propertyValues = $userInfoImported -split("\n")
    foreach ($entry in $propertyValues)
    {
        # Split each pair into key and value
        [regex]$regexp = $delimiter
        $key,$value = $regexp.Split($entry, 2)
        if (-not(([System.String]::IsNullOrEmpty($key)) -or ([System.String]::IsNullOrEmpty($value))))
        {
            $columnName = $key.Trim()
            $value = $value.Trim()
            
            # Convert password value to secure string
            if ($columnName -ieq $accountPasswordColumn)
            {
                $accountPassword = ConvertTo-SecureString -AsPlainText $value -Force
                continue
            }
            
            # Replace column name with attribute name
            if ($otherPropertiesMap.ContainsKey($columnName))
            {
                $propertyName = $otherPropertiesMap[$columnName]
            }
            else
            {
                $propertyName = $columnName
            }

            # Parse columns that contain references to AD objects
            if ($aDObjectNameProperties -icontains $columnName)
            {
                $aDObject = Get-AdmObject -Filter {(Name -eq $value) -or (DisplayName -eq $value) -or (distinguishedName -eq $value)} `
                    -AdaxesService localhost -ErrorAction SilentlyContinue -Server $server
            
                if ($aDObject -is [System.Array])
                {
                    $Context.LogMessage("Found more than one object with identity '$value'.", "Warning")
                    continue
                }

                if ($aDObject -eq $NULL)
                {
                    $Context.LogMessage("Object with identity '$value' not found.", "Warning")
                    continue
                }
            
                $value = $aDObject.DistinguishedName
            }

            # Parse boolean values
            if ($value -ieq "True" -or $value -ieq "False")
            {
                $value = [System.Boolean]::Parse($value)
            }

            # Add to $userInfo
            $userInfo[$propertyName] = $value
        }
    }
    
    # Build user name
    $displayName = $userInfo.GivenName + " " + $userInfo.SN # TODO: modify me
    $parameters = @{
        "Path" = "%distinguishedName%"
        "Name" = $displayName
        "Server" = $server
        "AdaxesService" = "localhost"
        "Enabled" = $True
        "OtherAttributes" = $userInfo
        "ErrorAction" = "Stop"
    }

    if (!([System.String]::IsNullOrEmpty($accountPassword)))
    {
        $parameters.Add("AccountPassword", $accountPassword)
    }

    # Create a new user account
    try
    {
        New-AdmUser @parameters
    }
    catch
    {
        $Context.LogMessage("An error occurred when creating user '$displayName'. Error: " + $_.Exception.Message, "Warning")
    }
}

Import-Module $exchangeWebServiceDllPath

if ($exchangeServer -eq $NULL)
{
    # Connect to Exchange Online via the Exchange Web Services API
    $exchangeWebService = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService
    $microsoft365Cred = $Context.GetOffice365Credential()
    if ($microsoft365Cred -eq $NULL)
    {
        $Context.LogMessage("Microsoft 365 credentials not set", "Warning")
        return
    }
        
    $exchangeWebService.Credentials = New-Object System.Net.NetworkCredential($microsoft365Cred.Username, $microsoft365Cred.GetNetworkCredential().Password)
    $exchangeWebService.Url = "https://outlook.office365.com/EWS/Exchange.asmx"
}
else
{
    # Connect to Exchange on-premises via the Exchange Web Services API
    $exchangeWebService = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010)
    $exchangeWebService.Url = "https://$exchangeServer/ews/exchange.asmx"
}

# Build filter
$secondSearchFilter = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::Subject, $searchSubject)
$searchFilterCollection = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollection([Microsoft.Exchange.WebServices.Data.LogicalOperator]::And)
$searchFilterCollection.Add($secondSearchFilter)
    
# Bind to the Inbox folder
$folderID = New-Object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox, $mailboxMailAddress)
$inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($exchangeWebService, $folderID)
    
# Set order
$itemView = New-Object Microsoft.Exchange.WebServices.Data.ItemView(50)
$itemView.OrderBy.Add([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived, [Microsoft.Exchange.WebServices.Data.SortDirection]::Descending)
    
# Get mail and create users
$more = $true
while ($more)
{
    $searchResults = $inbox.FindItems($searchFilterCollection, $itemView)
    if ($searchResults.Items.Count -eq 0)
    {
        return # No mail messages with the specified subject
    }

    foreach ($item in $searchResults.Items)
    {
        $item.Load()

        if ($item.Body.BodyType -eq [Microsoft.Exchange.WebServices.Data.BodyType]::HTML)
        {
            $message = $item.Body.Text -replace '<.*?>',''
        }
        else
        {
            $message = $item.Body.Text
        }
    
        Create-User $message

        $item.Delete("MoveToDeletedItems")
    }

    $more = $searchResults.MoreAvailable
    if ($more)
    {
        $itemView.Offset += 50
    }
}

Comments ( 0 )
No results found.
Leave a comment