Script Repository


Allow users to add themselves to groups by e-mail

June 22, 2017
1108

The script enables users to add themselves to Active Directory groups by sending an email to an Exchange mailbox. The mail message must have a subject that conforms to a certain predefined format. In the below example, the subject format is Automated task. Add me to: <Group Name>, where <Group Name> specifies the Group Name (pre-Windows 2000) of the group to add a user to. Users are added by their email address specified in the From field of the mail message. The email address must be specified in one of the following attributes of the AD user account:

  • Email (LDAP name mail)
  • Email Proxy Addresses (LDAP name proxyAddresses)

The script will use credentials of a user specified in the Run As section of the Run a program or PowerShell script action used to run the script in order to receive the email requests. The user must be assigned Full Access permissions for the mailbox that receives such mail requests.

To be able to launch the script, download and install Microsoft Exchange Web Services Managed API on the computer where Adaxes service runs.

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. Specify $NULL if you want to pull email messages from an Exchange Online mailbox;
  • $subject - specify the format for the message subject. The script will search for the group name at the very end of the subject;
  • $mailboxMailAddress - specifies the address of the mailbox where requests to be added to a group will be sent.
    You can use value references in the mailbox address. For example, if you specify %mail%, the script will search in the mailbox of the user on which the script is executed.
Edit Remove
PowerShell
# Exchange settings
$exchangeWebServiceDllPath = "C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll" # TODO: modify me
$exchangeServer = "ExchangeServer.domain.com" # TOOD: modify me. If $NULL, connect to Exchange Online
$subject = "Automated task. Add me to" # TOOD: modify me
$mailboxMailAddress = "recipient@domain.com" # TOOD: modify me

Import-Module $exchangeWebServiceDllPath

function SearchObjects($filter, $propertiesToLoad)
{
    $searcher = $Context.BindToObject("Adaxes://rootDSE")
    $searcher.SearchFilter = $filter
    $searcher.SearchScope = "ADS_SCOPE_SUBTREE"
    $searcher.PageSize = 500
    $searcher.ReferralChasing = "ADS_CHASE_REFERRALS_NEVER"
    $searcher.SetPropertiesToLoad($propertiesToLoad)
    $searcher.VirtualRoot = $True
    
    try
    {
        $searchResultIterator = $searcher.ExecuteSearch()
        $searchResults = $searchResultIterator.FetchAll()
        
        return ,$searchResults
    }
    finally
    {
        # Release resources
        if ($searchResultIterator){ $searchResultIterator.Dispose() }
    }
}

if ($exchangeServer -eq $NULL)
{
    # Connect to Exchange Online via the Exchange Web Services API
    $exchangeWebService = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService
    $office365Cred = $Context.GetOffice365Credential()
    if ($office365Cred -eq $NULL)
    {
        $Context.LogMessage("Credentials are not specified for the Office 365 Tenant that the mailbox belongs to or the mailbox is not associated with any Office 365 Tenant", "Warning")
        return
    }
    
    $exchangeWebService.Credentials = New-Object System.Net.NetworkCredential($office365Cred.Username, $office365Cred.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 to find the necessary mail message
$searchFilter = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+ContainsSubstring([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::Subject, $subject)
$searchFilterCollection = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollection([Microsoft.Exchange.WebServices.Data.LogicalOperator]::And)
$searchFilterCollection.Add($searchFilter)

# 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(1000)
$itemView.OrderBy.Add([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived, [Microsoft.Exchange.WebServices.Data.SortDirection]::Descending)

# Find message
$searchResults = $inbox.FindItems($searchFilterCollection, $itemView)
if ($searchResults.Items.Count -eq 0)
{
    return # No messages to process
}

# Process mail
foreach ($item in $searchResults.Items)
{
    $item.Load()
    $groupName = $item.Subject.Replace($subject, "").Trim()

    # Search group
    $searchResults = SearchObjects "(&(objectCategory=group)(sAMAccountName=$groupName))" @()
    
    if ($searchResults.Length -eq 0)
    {
        $Context.LogMessage("Group '$groupName' not found", "Warning")
        continue
    }
    elseif ($searchResults.Length -gt 1)
    {
        $Context.LogMessage("Found more than one group with name '$groupName'", "Warning")
        continue
    }
    $groupPath = $searchResults[0].AdsPath
    
    # Get sender address
    $senderMmailAddress = $item.Sender.Address
    
    # Find the user in AD
    $searchResults = SearchObjects "(&(sAMAccountType=805306368)(|(mail=$senderMmailAddress)(proxyAddresses=$senderMmailAddress)))" @()
    
    if ($searchResults.Length -eq 0)
    {
        $Context.LogMessage("Requesting user not found. Email address: '$senderMmailAddress'", "Warning")
        continue
    }
    elseif ($searchResults.Length -gt 1)
    {
        $Context.LogMessage("Cannot identify a requesting user. Found more than one user with mail '$senderMmailAddress'", "Warning")
        continue
    }

    $userPath = $searchResults[0].AdsPath
    
    # Add user to group
    $group = $Context.BindToObjectEx($groupPath, $True)

    try
    {
        $group.Add($userPath)
    }
    catch
    {
        $username = $Context.GetDisplayNameFromAdsPath($userPath)
        $Context.LogMessage("An error occurred when adding user '$username' to group '$groupName'", "Warning")
    }
    
    # Remove message
    $item.Delete("MoveToDeletedItems")
}


Comments ( 0 )
No results found.
Leave a comment