Applies to: Exchange Server 2007 SP3, Exchange Server 2007 SP2, Exchange Server 2007 SP1
Topic Last Modified: 2011-06-27
Tom Di Nardo, Senior Technical Writer, Microsoft Exchange Server; Dave Goldman, Escalation Engineer, Microsoft CSS Enterprise Messaging Support; Michael Barta, Support Escalation Engineer, Microsoft CSS Enterprise Messaging Support
February 2008
This white paper provides the information that you require to configure Microsoft Exchange Server 2007 with multiple address lists so different groups of users can have their own address list and secure those address lists so that groups of users can see only their specific address list.
Much of the information in this white paper originally appeared as individual Help topics in Exchange Server 2007 Help. In this white paper, we have consolidated the information that you need to deploy and manage segregated address lists in one central location. We have also provided sample scripts, which can be modified to fit your environment, to help automate the provisioning of virtual organizations and users.
Table of Contents
Address list segregation is a process whereby administrators can segment their users into separate groups and implement security policies so that groups of users can see only their specific address list. The ability to restrict access to address lists in this manner may be used as part of the toolset for helping companies meet their internal security requirements and as part of a regulatory compliance strategy for meeting the requirements dictated by the Health Insurance Portability and Accountability Act (HIPPA), and the Sarbanes-Oxley Act.
It is useful to illustrate how address list segregation can be implemented by way of examples. Suppose your company, Contoso, purchases the company Fabrikam. The management team determines that they want to manage Fabrikam’s entire IT infrastructure, but they want the employees of Contoso and Fabrikam to be completely segregated so that they can see only other users and resources from their respective companies. By implementing address list segregation, Contoso administrators can meet this requirement for all Exchange Server 2007 functionality.
Another example scenario is one in which Contoso establishes a compliance group to support regulatory compliance efforts for the company. Company management wants this new group not to be visible to any other groups within the company via Microsoft Office Outlook or Outlook Web Access. By implementing address list segregation, Contoso administrators can meet this requirement by correctly configuring Exchange 2007.
Companies that want to completely segregate their address lists can do this by removing access to the Default Global Address List and creating two or more address lists or virtual organizations. You can also set up additional functionality to restrict searching via Outlook Web Access to particular organizational units (OUs) or specific address lists using the msExchQueryBaseDN attribute.
The configuration described in this document is complex. Although it can be effective in smaller environments or in limited scope, it can become very challenging to manage such a configuration as the scope of the deployment increases if automation steps are not implemented. While you can use scripts like those described in this document to automate the provisioning process, you must plan for failures in your automation process when they occur. The more complex the provisioning scripts, the more difficult it will be to troubleshoot script failures and to determine in what state the failed provisioning request was actually left.
Additionally, you have to make sure that steps are taken to monitor service health in a manner that ensures that all aspects of the services offered by your deployment are proactively monitored to deliver reliable service. This requires not only a well-engineered monitoring infrastructure but also operational expertise and clearly documented processes and procedures to deal with the complexities and challenges that arise when delivering a hosted offering. These issues are not trivial in scope or in expense.
Customers who want to provide a commercial hosting environment should review the Microsoft Hosted Messaging and Collaboration (HMC) solution. This solution addresses the issues described earlier. For more information about the Microsoft HMC solution, see: Microsoft Solution for Hosted Messaging and Collaboration version 4.0.
The information that is provided in this white paper has been tested by the Exchange Product Group at the time that this paper was first published. If you make changes to your environment that are not discussed in this white paper, or if you have applied any service packs or updates to your environment, you may create an unsupported configuration.
This configuration is one in which companies may want to totally segregate their address lists and still have access to the Default Global Address List, or try to split the Global Address List (GAL) into two separate address lists. An example of this configuration would be a company with two groups of 500 users that belong to the Sales and Finance departments. Both groups are in the GAL, however the desire is to have everyone access the GAL except one group. If you are going to segregate your address lists, then they will be segregated. Attempting this configuration will cause problems with the check names functionality which will prevent users from creating Outlook profiles, and can also break the OAB Generation Process. This also allows Outlook users to see all of the Address Lists from within Outlook, which cannot be changed.
It is also important to understand that any attempt to use this white paper to configure Exchange 2007 for a commercial "hosting" solution is not supported. This white paper is not a replacement for the Microsoft HMC (Hosting and Collaboration) software. The information that is provided in this white paper is meant for internal segregation use only.
Return to top
Active Directory partitioning is implemented by creating separate OUs for each virtual organization or group. Each organizational unit will contain the segregated users, distribution lists, and security groups to restrict or grant access to Active Directory appropriately.
As with any Active Directory design, it is important to ensure minimized risk of unauthorized data access. With this design, the risk increases with the use of Internet access and partitioning security. Some risk is due to the fact that Exchange uses the Internet as a primary connection point. If a segregated user is allowed to log on, it has additional methods for accessing the GAL (GAL). Security groups contained within the OUs provide the partitioning security context for the segregated users. These security groups contain only those users who require rights to that specific OU. For example, all users will be restricted to the company's OUs within Active Directory. Some of those users may also be granted additional rights to create new objects (users).
After Exchange is configured to allow access, a security risk is inherent in the creation of new objects. Documented processes must be followed, either manually or programmatically, to ensure that appropriate security is applied to each object. Objects without the correct security context may be able to access objects outside the segregated boundaries. For example, users from one segregated group could potentially have access to user information within another segregated group.
Locate all segregated groups in a single forest within a single domain and use OUs to partition each group's users. The advantage of this architecture is that hardware requirements are reduced since all segregated groups are located on the same physical hardware. This option is easy to manage with a single administration process, and is scalable.
A disadvantage of this design is the risk of one segregated group's unintended access to another group's data should the documented permission processes not be followed.
An issue to consider is that Windows Server 2003 adds users and administrators to a default set of security groups, such as the Domain Users group. Disallow this to prevent users from having access to domain resources, such as printers. This will not prevent you from allowing users and administrators to access resources found only in Exchange.
Locate all segregated groups in a single forest with multiple domains. Each segregated group stores user data in a separate domain, and the global catalog would provide information from the directory.
A disadvantage of this architecture is cost. Locating each segregated group in a separate domain requires at least two domain controllers per segregated group and you must still implement processes to prevent the issues detailed above with the single domain method. Because security settings and defaults apply to a domain, the impact of a user being added to a Windows Server 2003 security group, such as Domain Users, is limited to the segregated groups in that domain.
Locate each segregated group in a separate forest partition where each group's users are located in a separate Active Directory schema. An advantage of this method is minimal risk of inadvertently giving one segregated group access to another group's data. Distributing services across hardware offers other advantages. In the event of a failure, you can continue to provide services to other companies while restoring services to the affected company.
A drawback of this design is cost. To locate each segregated group in a separate forest requires at least two domain controllers per group, separate administration processes, and disaster recovery equipment. You will also have to manage each and every forest as a completely separate entity. This approach is generally not practical because of the additional hardware and administrative cost.
Active Directory contains a database of all users. The practical implementation of this database, when accessed from an Outlook client, is referred to as the Exchange GAL. When segregating Exchange, if user searches this list, you want to limit the results to recipients in the same segregated group.
This partitioning of the GAL is provided by access control lists associated with global group memberships. For each organizational unit containing a segregated group, a global group must be created. The global group membership is the users of the segregated group located in the OU. Use this group, together with other permission changes, to provide a view of Active Directory specific to the segregated group located in the organizational unit.
When partitioning the GAL, you must remove the existing default rights to see all users and objects within Active Directory. To accomplish this task, you must remove from each organizational unit the permissions assigned to the Authenticated Users group and the Everyone group, if it exists.
The host company requires permissions to see all objects within Active Directory. Add rights for the security group for each segregated group's users, thus allowing the users to see other users in their own organizational unit. Go through each organizational unit and add a security group for that segregated group. For example, for the organizational unit representing Fabrikam.com, add the Fabrikam Users security group and assign Read rights.
There are some permissions that apply only to specific clients. Your service determines which clients get support. For example, Outlook Web Access does not incorporate user permission sets when doing searches. The permissions set on OUs do not prevent search results from including other segregated group's recipients. If you are using Outlook Web Access, you must set the attribute msExchQueryBaseDN on each address list or user object to restrict the search results to include only the members of the appropriate address list.
As with all security and permissions changes, verification and testing must be performed to ensure the expected result is obtained after the change has been implemented. In this example, the Outlook client and Outlook Web Access should be tested to guarantee that each segregated group can view only their group-specific data, and that all client features operate as intended.
When you configure multiple offline address lists for a particular messaging database (MDB) in Exchange, Exchange associates the offline address book that a user is permitted to download with the MDB where that user's mailbox is located. This may be unacceptable if you locate many segregated groups on a single mailbox database. Modification of the user attribute msExchUseOAB will allow Exchange to determine the offline address book (that is generated from a particular address list, or lists), and is meant to be available to each user. When you must locate multiple segregated groups on a single database, and these groups have different offline address lists, you must restrict the offline address book by using the msExchUseOAB attribute.
Microsoft Outlook Web Access (OWA) users may use the Find names feature to view users, including those who are not located in the same organizational unit. To limit the scope of a directory service search available to Outlook Web Access users, you must set the msExchQueryBaseDN attribute on each user object. The value that is specified for the msExchQueryBaseDN attribute limits the searches and the ambiguous name resolution queries that a user can perform. This can be set to the distinguishedname (DN) of the OU or an address list containing the correct group of users.
Active Directory in earlier versions of Microsoft Windows-based domains accept anonymous requests. In these versions, a successful result depends on having correct user permissions in Active Directory.
With Windows Server 2003, only authenticated users may initiate an LDAP request against Windows Server 2003-based domain controllers. You can override this new default behavior by changing the third character of the dsHeuristics attribute. By default, this attribute is not set. If the attribute is not set, you must change the value to 001. If the attribute is already populated, change the third character to a 1 and leave the first two as they are. The DN path for the dsHeuristics attribute is listed below. It can be found in the root domain of the forest.
CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration
The dsHeuristics setting applies to all Windows Server 2003-based domain controllers in the same forest. The value is realized by domain controllers upon Active Directory replication without restarting Windows.
User principal names (UPNs) provide logon names in a format similar to e-mail names. By making UPN values independent from domain names, you can move user accounts between domains while leaving UPN values unchanged, making the move transparent to users and easing administration.
The primary benefit of using UPNs is to provide a unique namespace for each segregated organization. Through the use of UPN for logon and user identification, rob@contoso.com and rob@fabrikam.com can be supported in the same Active Directory domain without worrying about Rob’s user ID or e-mail name being unique. Each segregated group can be provided a unique namespace, which is equivalent to how most companies allocate user credentials. This also masks the Windows domain name from the segregated users who have this attribute configured. This provides the appearance to each segregated group that the entire environment is set up purely for them, even though several virtual organizations have been segregated within your environment.
The main advantage to using UPNs is for Outlook Web Access or IMAP logons. This enables users to log on to their mailboxes, using only their SMTP address and password, without specifying a Windows 2003 domain.
When you use Exchange 2007 to segregate different companies or divisions under one Exchange infrastructure, you must create multiple address lists, GALs and offline address lists. The address lists typically have different user accounts listed in them based on the filters that you create. By default, all the users in the Exchange 2007 organization can view all the defined GALs. This may not be acceptable in some cases; for example, it would not be acceptable at a company that has multiple divisions that are required by law to ensure that the data for each division remain completely separated. This issue can be overcome by restricting access to a particular set of users for specific address lists, GALs and offline address lists.
In this section, you will use the Exchange Management Console, the Exchange Management Shell, ADSIEdit (AdsiEdit.msc), and Active Directory Users and Computers to prepare Active Directory to host segregated information. This approach allows for easy configuration and administration of your segregated environment because it provides very clearly defined security boundaries. This section contains the following procedures:
When you have prepared the environment, you can leverage Windows PowerShell scripting to automate the provisioning of additional virtual companies and their users. By scripting these functions, you can reduce the possibility of human error in the provisioning process. We recommend that administrators become familiar with the manual provisioning process for virtual companies and users in a lab environment before creating scripts. Familiarity with the individual steps will make troubleshooting issues much easier. Sample PowerShell scripts are provided in the "Automating the Creation of Virtual Companies and Users" section of this document.
To configure the dsHeuristics value using ADSIEdit, use the following procedure:
To perform the following procedures, the account you use must be a member of the Domain Administrators group.
For more information about permissions, delegating roles, and the rights that are required to administer Exchange 2007, see Permission Considerations.
Install ADSIEdit. ADSIEdit can be found on the Windows 2003 Server installation media or on Windows Server 2003 Service Pack 2 32-bit Support Tools.
Open ADSIEdit.
Expand CN=Configuration.
Expand CN=Services.
Expand CN=Windows NT.
Select CN=Directory Service.
Right click CN=Directory Service and click Properties.
Select the attribute dsHeuristics.
Apply the change and click OK to close out of the properties.
For more information about ADSIEdit, see Adsiedit Overview.
Use the following procedure to create an organizational unit to contain all of the segregated companies.
Start Active Directory Users and Computers.
In the left pane, right-click your domain (the very top object).
Click New, and select Organizational Unit.
Type Companies, and click OK.
Use the following procedures to modify the permissions on the All Address Lists container using the Exchange Management Shell.
All rights assigned to the Authenticated Users, Everyone, and Anonymous Logon groups must be removed.
To perform the following procedures, the account you use must be delegated the Exchange Server Administrator role and membership in the local Administrators group on the target server.
Run the following command:
get-adpermission "All Address Lists" | Where {($_.User -like 'NT Authority\Authenticated Users') -or ($_.User -like 'Everyone') -or ($_.User -like 'NT Authority\ANONYMOUS LOGON')} | FT User,AccessRights,ExtendedRIghts,IsInherited
User AccessRights ExtendedRights IsInherited
---- ------------ -------------- -----------
NT AUTHORITY\Aut... {GenericRead} False
NT AUTHORITY\Aut... {ExtendedRight} {Open-Address-Book} False
NT AUTHORITY\Aut... {ListChildren} True
NT AUTHORITY\Aut... {ReadProperty} True
Everyone {ExtendedRight} {ms-Exch-Create-... True
Everyone {ExtendedRight} {ms-Exch-Store-C... True
Everyone {GenericRead} True
NT AUTHORITY\ANO.. {ExtendedRight} {ms-Exch-Create-... True
NT AUTHORITY\ANO.. {ExtendedRight} {ms-Exch-Store-C... True
NT AUTHORITY\ANO.. {GenericRead} True
get-adpermission "All Address Lists" | Where {($_.User -like 'NT Authority\Authenticated Users') -and ($_.IsInherited -eq $false)} | Remove-ADPermission
Press Enter to confirm the removal of the GenericRead permission for the Authenticated Users group.
Press Enter to confirm the removal of the ExtendedRight permission for the Authenticated Users group.
To limit address list lookups to each organizational unit, you first need to delete the default address lists. Use one of the two procedures below to delete the following default Address Lists:
Run the following commands:
remove-addresslist "All Contacts" remove-addresslist "All Groups" remove-addresslist "All Rooms" remove-addresslist "All Users" remove-addresslist "Public Folders"
Open the Exchange Management Console.
Expand Organization Configuration.
Select Mailbox.
Select the Address Lists tab.
Select each of the following address lists:
Right click and select Remove or click the Remove action item.
Click Yes to confirm the deletion.
Use the following procedure to modify the security permissions for the default GAL that is created when Exchange 2007 is installed. It is important to modify the security settings, rather than delete the default GAL, to ensure that Exchange can have access to the GAL when necessary but that segregated users cannot see the default GAL entries, which include all users by default.
Get-GlobalAddressList "Default Global Address List" | Add-ADPermission -User "Authenticated Users" -AccessRights GenericRead -ExtendedRights Open-Address-Book -Deny:$True
Press Enter to confirm the removal of the permissions.
$galContainer = "CN=All Global Address Lists,CN=Address Lists Container,CN=<OrganizationName>,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=contoso,DC=com"
Get-ADPermission $galContainer -user "authenticated users"
Identity User Deny Rights
\Global Address List NT AUTHORITY\Authenticated Users True Open-Address-Book
\Global Address List NT AUTHORITY\Authenticated Users True ReadProperty
\\Global Address List NT AUTHORITY\Authenticated Users True ListObject, GenericExecute
Use the following procedure to modify the security permissions for the Offline Address Lists container that is created when Exchange 2007 is installed.
$container = "CN=Offline Address Lists,CN=Address Lists Container,CN=First Organization,CN=Microsoft Exchange,CN=Services,CN=Configuration, DC=Contoso,DC=com "
remove-adpermission $container -user "NT AUTHORITY\Authenticated Users" -ExtendedRights 'ms-Exch-Download-OAB'
$oabContainer = "CN=Offline Address Lists,CN=Address Lists Container,CN=First Organization,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=contoso,DC=com"
Get-ADPermission $oabContainer -user "authenticated users"
Offline Address L... NT AUTHORITY\Auth... False ms-Exch-Download-OAB
Offline Address L... NT AUTHORITY\Auth... False ListChildren
Offline Address L... NT AUTHORITY\Auth... True ReadProperty
To obtain more detailed information , run the following command:
Get-ADPermission $oabContainer -user "authenticated users" | fl
Use the following procedure to create an "All Hosted Groups" security group for all of your virtual organization security groups. This group will be added to the security permissions for the CN=Address Lists Container. With this configuration in place, users will only be able to view address lists that their security group allows them access to when they are using Outlook and they click on the address list icon on the menu bar.
To perform the following procedures, the account you use must be delegated the following:
New-DistributionGroup -Name "All Hosted Groups SG" -OrganizationalUnit "Contoso.com/Companies" -SamAccountName "AllHostedGroupsSG" -Alias "AllHostedGroupsSG" -Type "Security"
Add-ADPermission -Identity "CN=Address Lists Container,CN=Contoso,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=Contoso,DC=com" -User "All Hosted Groups SG" -AccessRights GenericRead -Deny
Add-ADPermission -Identity "CN=Address Lists Container,CN=Contoso,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=Contoso,DC=com" -User "All Hosted Groups SG" -AccessRights ReadProperty -Properties "Open Address List" -Deny
The following section of this document provides the steps required to add a new segregated company to your environment.
The following names are used in the examples below:
Using Active Directory Users and Computers, create a new OU for the new company. In the examples below, all companies are created as sub-OUs of the “Companies” OU.
To perform the following procedures, the account you use must be delegated the Exchange Server Administrator role and membership in the Domain Administrators group and local Administrators group on the target server.
$NewOU = <NewCompanyName>
$objDomain = [ADSI]"LDAP://DC01:389/ou=Companies,dc=contoso,dc=com" $objOU = $objDomain.Create("organizationalUnit","ou="+$NewOU) $objOU.SetInfo()
In the left pane, select the Companies OU.
Right-click the Companies OU.
Type <The Name of the New Company>, and click OK.
Adding a new UPN suffix allows users of the new company to log on with a different UPN address than that used in the domain. Use this procedure to add a UPN for each company that will be added to the environment if the company uses a different SMTP domain name.
Start Active Directory Domains and Trusts.
Right-click Active Directory Domains and Trusts (not your domain name) and select Properties.
On the Alternative UPN Suffixes tab, type Customer1, click Add, and click OK.
By modifying the upnSuffix attribute, you limit the domain dropdown list when creating new users in Active Directory. The list will only include the UPN of the original domain and the new suffix added below.
To modify the upnSuffix attribute using ADSIEdit, use the following procedure:
Expand the Domain Naming Context.
Right click the OU and select Properties.
Select the upnSuffixes attribute and click Edit.
Enter the new company UPN suffix and click Add (Example: Fabrikam.com).
Click OK two times to close out of the properties.
Use one of the following procedures to create a security group for the users of organizational unit “Fabrikam”. This user group will contain the user access privileges created for the organizational unit Fabrikam. This group is used to grant permissions to the appropriate Address Lists.
New-DistributionGroup -Name "Fabrikam SG" -OrganizationalUnit "Contoso.com/Companies/ Fabrikam" -SamAccountName "FabrikamUsersSG" -Alias "FabrikamSG" -Type "Security"
Get-DistributionGroup -Name "All Hosted Groups SG" | Add-DistributionGroupMember -Member "Company SG You Want to Add"
Start the Exchange Management Console.
In the console tree, expand Recipient Configuration, and then click Distribution Group.
In the action pane, click New Distribution Group. The New Distribution Group wizard appears.
On the Introduction page, click New Group, and then click Next.
On the Group Information page, complete the following fields:
Click Next.
On the New Distribution Group page, review the Configuration Summary. To make any configuration changes, click Back. To create the new security group, click New.
On the Completion page, the Summary states whether the security group was successfully created. The summary also displays the Exchange Management Shell command that was used to create the security group.
Click Finish.
Select the All Hosted Groups SG security group.
Click Properties.
Click the Members tab.
Click Add.
Select the new Security Group from the list and click OK.
Click Apply, and then click OK.
For more information about creating new security groups, see How to Create a New Security Group.
You must configure an accepted domain before that SMTP namespace can be used in an e-mail address policy. The accepted domain is automatically populated to the e-mail address policy editor. Each domain or subdomain that you want to use as part of an e-mail address policy must have an explicit accepted domain entry.
Accepted domains are configured on computers that have the Hub Transport server role installed and on computers that have the Edge Transport server role installed. We recommend that you configure accepted domains only on the Hub Transport server role and then populate that data on the Edge Transport server by using the Edge Subscription process. When the Edge Subscription process runs, the accepted domain configuration information is replicated to the subscribed Edge Transport server. For more information, see Subscribing the Edge Transport Server to the Exchange Organization.
To perform the following procedures, the account you use must be delegated the Exchange Organization Administrator role.
To perform the following procedures on a computer that has the Edge Transport server role installed, you must log on by using an account that is a member of the local Administrators group on that computer.
Run the following command to create an authoritative domain:
New-AcceptedDomain -Name "Fabrikam" -DomainName "Fabrikam.com" -DomainType Authoritative -domaincontroller "dc1"
In the console tree, expand Organization Configuration, select Hub Transport, and then in the work pane, click the Accepted Domains tab.
In the action pane, click New Accepted Domain… The New Accepted Domain wizard appears.
On the New Accepted Domain page, complete the following fields:
After you complete these fields on the New Accepted Domain page, select Authoritative Domain. E-mail is delivered to a recipient in this Exchange organization. to set the accepted domain type:
Click New.
On the Completion page, click Finish.
For detailed syntax and parameter information, see New-AcceptedDomain. After you configure the accepted domain, you must verify that a public Domain Name System (DNS) mail exchange (MX) resource record for that SMTP namespace exists and that the MX resource record references a server name and an IP address that is associated with the Exchange organization.
Use one of the following procedures to create a new e-mail address policy. For a recipient to receive or send e-mail messages, the recipient must have an e-mail address. E-mail address policies generate the primary and secondary e-mail addresses for your recipients (which include users, contacts, and groups) so they can receive and send e-mail.
To perform the following procedure, the account you use must be delegated the Exchange Organization Administrator role.
Make sure that you have read Managing E-Mail Address Policies.
new-EmailAddressPolicy -Name "Fabrikam" -IncludedRecipients 'AllRecipients' -ConditionalCustomattribute1 "Fabrikam" -Priority '1' -EnabledEmailAddressTemplates "SMTP:%1g%s@ Fabrikam.com" -domaincontroller "dc1"
In the console tree, expand Organization Configuration, and then click Hub Transport.
In the action pane, click New E-mail Address Policy. The New E-Mail Address Policy wizard appears.
On the Introduction page, complete the following fields:
Name Enter the name of the new company (Fabrikam).
All recipient types Click this button to apply the e-mail address policy to all recipient types. In Exchange 2007, recipients are comprised of mailbox users, mail-enabled users, mail contacts, mail-enabled distribution and security groups, and mail-enabled public folders.
The following specific types Click this button to apply the e-mail address policy to specific recipient types. You can select one or more of the following recipient types:
On the Conditions page, compete the following fields:
Preview Click this button to view the recipients that will be contained in the e-mail address policy, based on the conditions that you specified.
On the E-Mail Addresses tab, click Add to add a new e-mail address to your e-mail address policy. Choose the appropriate radio button to select the e-mail address format you want to use. Use the drop-down box to select the appropriate domain name for the new company (Fabrikam.com).
On the Schedule page, complete the following fields:
Apply the e-mail address policy select one of the following schedule settings to specify when the e-mail address policy should be applied.
Cancel tasks that are still running after (hours) Select this check box and use the corresponding text box to specify how long the new e-mail address policy task will run. The default is 8 hours.
On the New E-Mail Address Policy page, review your configuration settings. Click New to create the e-mail address policy. Click Back to make configuration changes.
On the Completion page, confirm whether the new e-mail address policy was created successfully. A status of Completed indicates that the wizard completed the task successfully. A status of Failed indicates that the task was not completed. If the task fails, review the summary for an explanation, and then click Back to make any configuration changes.
Click Finish to complete the New E-Mail Address Policy wizard.
For detailed syntax and parameter information, see the New-EmailAddressPolicy reference topic.
For more information about accepted domains, see the following topics:
For more information about e-mail address policies, see Understanding E-Mail Address Policies.
Use one of the following procedures to create a new address list.
New-AddressList -Name " Fabrikam AL" -Container '\' -IncludedRecipients 'AllRecipients' -conditionalcustomattribute1 "Fabrikam"
In the console tree, expand Organization Configuration, and then click Mailbox.
In the action pane, click New Address List. The New Address List wizard appears.
Name Enter a name for the new company address list (Fabrikam AL).
Container Click Browse to select the path to the container for the address list. To add the address list as a child to an existing address list, click the existing address list you want, and then click OK. To create a new parent address list, click All Address Lists, and then click OK. For more information about creating parent or child address lists, see Managing Address Lists.
Include these recipient types Select the types of recipients for the address list. You can select None, All recipient types, or The following specific types:
Apply the address list Select one of the following options to specify when the address list should be applied:
Cancel tasks that are still running after (hours) Select this check box and use the corresponding text box to specify how long the new address list task will run. The default is 8 hours.
On the New Address List page, review your configuration settings. Click New to create the address list. Click Back to make configuration changes.
On the Completion page, confirm whether the address list was created successfully. A status of Completed indicates that the wizard completed the task successfully. A status of Failed indicates that the task was not completed. If the task fails, review the summary for an explanation, and then click Back to make any changes.
Click Finish to complete the New Address List wizard.
Use the following procedure to modify the default permissions on the All Address Lists container.
Get-AddressList "Fabrikam AL" | Remove-ADPermission -User "Authenticated Users" -AccessRights genericread -ExtendedRights "open address list" -deny:$false Get-AddressList "Fabrikam AL" | Add-ADPermission -User "Fabrikam SG" -extendedrights "open address list" -deny:$false
GALs define a set of rules for looking up users in a global address book—for example, by alias name, long name, group name, and so on. Use the following procedure to create a GAL for the organizational unit Fabrikam.
New-GlobalAddressList -Name " Fabrikam GAL" -RecipientFilter {(alias -ne $null -and customattribute1 -eq "Fabrikam")}
For more information on the New-GlobalAddressList cmdlet, see New-GlobalAddressList.
Use one of the following procedures to create a new offline address book (OAB).
Additionally, before you perform these procedures, be aware that if you will be using the public folder distribution method, you must make sure that the public folder database is mounted and online.
To create an OAB that uses Web-based distribution for clients running Outlook 2007, run the following command:
New-OfflineAddressBook -Name " Fabrikam OAB" -Server OABGEN01 -AddressLists "\ Fabrikam AL " -VirtualDirectories "CAS01\OAB (Default Web Site)"
To create an OAB that uses public folder distribution for clients running Outlook 2003 or earlier, run the following command:
New-OfflineAddressBook -Name " Fabrikam OAB" -Server OABGEN01 -AddressLists "\ Fabrikam AL " -VirtualDirectories "CAS01\OAB (Default Web Site)" -publicfolderdistributionenabled $true
In the action pane, click New Offline Address Book. The New Offline Address Book wizard appears.
On the Distribution Points page, complete the following fields:
On the New Offline Address Book page, review your configuration settings. Click New to create the offline address book. Click Back to make configuration changes.
On the Completion page, confirm whether the OAB was created successfully. A status of Completed indicates that the wizard completed the task successfully. A status of Failed indicates that the task was not completed. If the task fails, review the summary for an explanation, and then click Back to make any configuration changes. Click Finish to complete the New Offline Address Book wizard.
For detailed syntax and parameter information, see the New-OfflineAddressBookreference topic.
For more information about OABs, see the following topics:
For more information about public folders, see the following topics:
Use the following procedure to set the appropriate permissions on the Fabrikam OAB. After you perform this procedure, only users who are members of the Fabrikam security group will be able to access the offline address list.
Get-OfflineAddressBook "Fabrikam OAB" | Add-ADPermission -User ' Fabrikam SG' -ExtendedRights 'ms-Exch-Download-OAB' -Deny:$false
The following section of this document provides the steps required to add a new user and associate that user with a segregated company in your environment.
When creating users in a segregated environment, in addition to creating the user mailboxes with the Exchange Management Shell or the Exchange Management Console, additional steps must be taken to set the following attributes on the user object:
These attributes can be set manually or via a PowerShell script.
Use either the Exchange Management Console or the Exchange Management Shell, as described in How to Create a Mailbox for a New User, to create a new user account and a mailbox for that user.
Use one of the following procedures to modify the group membership of the user(s) by adding them to the appropriate security group.
To perform this procedure, the account you use must be delegated the Exchange Recipient Administrator role.
get-mailbox "userAlias" | add-distributiongroupmember -identity "Fabrikam SG"
get-mailbox -organizationalunit "Fabrikam" | add-distributiongroupmember -identity "Fabrikam SG"
In the result pane, select the distribution group to which you want to add a recipient.
In the action pane, under the distribution group name, click Properties.
In <Distribution Group> Properties, on the Members tab, click Add to open the Select Recipient dialog box.
In the Select Recipient dialog box, click the recipient you want to add to the distribution group, and then click OK.
Click OK to return to the Exchange Management Console.
For detailed syntax and parameter information, see the Add-DistributionGroupMember reference topic.
For more information about managing distribution groups, see Managing Distribution Groups.
Run one of the following procedures to modify the msExchUseOAB attribute to specify the OAB that is assigned to the user or users.
set-mailbox "mailbox name" -offlineaddressbook "Fabrikam OAB"
get-mailbox -organizationalunit "Fabrikam" | set-mailbox -offlineaddressbook "Fabrikam OAB"
Use the following procedure to modify the msExchQueryBaseDN attribute to limit the search and the ambiguous name resolution queries that an Outlook Web Access user can perform.
To perform this procedure, the account you use must be delegated the Exchange Organization Administrator role.
$user = ([ADSI]"LDAP://DC01:389/CN=Test User1,ou= Fabrikam,ou=companies,dc=contoso,dc=com").psbase; $user.Properties["msExchQueryBaseDN"].Value = "ou= Fabrikam,ou=companies,dc=contoso,dc=com"; $user.CommitChanges();
Use one of the following procedures to modify the custom attribute that is used to identify the user(s) of the virtual company (customattribute1 in this document’s examples).
set-mailbox "userAlias" -customattribute1 "Fabrikam"
get-mailbox -organizationalunit "Fabrikam" | set-mailbox -customattribute1 "Fabrikam"
When the above user creation steps have been taken, the following processes must be run to update the Address List, GAL, OAB, and redistribute content and re-stamp files with the appropriate permissions:
Update-addresslist "Fabrikam AL"
Update-globaladdresslist "Fabrikam GAL"
Update-offlineaddressbook "Fabrikam OAB"
Update-FileDistributionService CAS01 -type oab
The Exchange Management Shell makes scripting most of the Company and User creation processes described above very simple. You can also script the Company removal process in the event that a virtual company needs to be removed from the environment.
The NewCompany.ps1 sample script provided below will automate the creation of the Organizational Unit, Security Group, AcceptedDomain, EmailAddressPolicy, AddressList, GAL, and the Offline Address Book.
The script can be easily modified to make it usable in your environment. The script will prompt the administrator to enter a Company Name, Company Domain, and a domain controller name.
The NewUser.ps1 sample script provided below will automate the creation of the user object and mailbox as well as setting all of the required attributes. The script can be easily modified to make it usable in your environment. The script will prompt the administrator to enter a Company Name, a domain controller name, New User First Name, New User Last Name, and the UPN address for the user.
The DeleteCompany.ps1 sample script provided below will automate the process of removing a virtual company from your environment.
In order to make the NewCompany.ps1 script functional in your specific environment, it must be modified as described in the script remarks. This script will automate all of the steps required to provision a new company and will create a confirmation html page that details the results of the steps taken.
Open Notepad or another text editor.
Copy the following code into a file, and save the file by using a descriptive name and the .ps1 extension. We recommend that you name the file NewCompany.ps1.
#"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" #"!!!!!!! THIS IS NOT A MICROSOFT SUPPORTED SCRIPT. !!!!!!!!" #"!!!!!!! TEST IN A LAB FOR DESIRED OUTCOME !!!!!!!!" #"!!!!!!! !!!!!!!!" #"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" #" " #" !!!!!!! You must make the following changes to this script # #"1. Change the server names and domain names as appropriate." #" A. Change the OABGeneration server in Step 9" #" B. Change the OAB web site in Step 9" #" C. Change the public folder server" #"2. Modify the domain and OU structure contoso.com" #"3. Change the domain controller name CON-DC" # #" " # #"When the above steps have been taken, comment out this line and all those above it using # #at the beginning of the line." #" " # #" " #!!!! Change DC below !!!! #This step specifies a domain controller ## $DC = "con-dc.contoso.com" "Using Domain Controller - $DC" #checks for the "Company" OU #---------------------------- #---------------------------- $eaSave = $ErrorActionPreference $ErrorActionPreference = "Inquire" $context = new-object System.DirectoryServices.ActiveDirectory.DirectoryContext([System.DirectoryServices.ActiveDirectory.DirectoryContextType]::DirectoryServer, $dc) $domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($context) $root = $domain.psbase.GetDirectoryEntry() # check if the 'Companies' ou exists $orgs = $null $orgs = $root.psbase.Children.psbase.Find("OU=Companies") if ($orgs -eq $null) { write-host "Cannot find an OU named 'Companies'"; exit } #----------------------------- #----------------------------- " " " " ## Gets the company name ## "Enter the company name (no spaces):" $CompanyName = [Console]::ReadLine() $CompanyName = $CompanyName.Trim() ## Gets the company Email Domain Name ## "Enter the company email domain name - e.g. contoso.com:" $CompanyEmailDomainName = [Console]::ReadLine() $CompanyEmailDomainName = $CompanyEmailDomainName.Trim() ## Create the OU for New Company ## ##!!!!! Change DC to a valid DC for your environment !!!!!! "1 of 15, Creating an Organizational Unit for $CompanyName" $NewOU = $CompanyName $objDomain = [ADSI]"LDAP://CON-DC:389/ou=Companies,dc=contoso,dc=com" $objOU = $objDomain.Create("organizationalUnit","ou="+$NewOU) $objOU.SetInfo() "An OU has been created for $CompanyName" " " "Wait 20 seconds for the OU to be visible on the Domain Controller" [System.Threading.Thread]::Sleep(20000) #check for this companies OU #-------------------------------- #-------------------------------- # Find the org itself $newOrg = $null $newOrg = $orgs.psbase.Children.psbase.Find("ou="+$CompanyName) if ($newOrg -eq $null) { " " write-host "Cannot find an OU named" $CompanyName " " exit } #--------------------------------- #--------------------------------- " " ".............................................." "2 of 15, Creating a Security Group for $CompanyName" ".............................................." #!!!OU structure must be created first!!!! new-distributiongroup -name "$CompanyName SG" -Type "security" -OrganizationalUnit "contoso.com/Companies/$CompanyName" -SamAccountName "$CompanyName" -Alias "$CompanyName" -domaincontroller $DC " " ".............................................." "3 of 15, Add a Security Group for $CompanyName to the All Hosted Groups SG" ".............................................." Get-distributiongroup -id "All Hosted Groups SG" | Add-DistributionGroupMember -Member "$CompanyName SG" -domaincontroller $DC " " ".............................................." "4 of 15, Set customattribute1 on the USG for $CompanyName" ".............................................." set-distributiongroup "$CompanyName SG" -customattribute1 "$CompanyName" -domaincontroller $DC " " ".............................................." "5 of 15, Creating an Address List for $CompanyName" ".............................................." new-AddressList -Name "$CompanyName AL" -Container '\' -IncludedRecipients 'AllRecipients' -conditionalcustomattribute1 $CompanyName -domaincontroller $DC #" " #".............................................." "6 of 15, Add an Accepted Domain for $CompanyName" ".............................................." New-AcceptedDomain -Name "$CompanyName" -DomainName "$CompanyEmailDomainName" -DomainType Authoritative -domaincontroller $DC " " ".............................................." "7 of 15,Adding Email Address Policy for $CompanyName" ".............................................." New-EmailAddressPolicy -Name "$CompanyName" -Priority "1" -EnabledEmailAddressTemplates "SMTP:%1g%s@$CompanyEmailDomainName" -IncludedRecipients 'AllRecipients' -conditionalcustomattribute1 $CompanyName -domaincontroller $DC " " ".............................................." "8 of 15, Remove Authenticated Users from the $CompanyName address list" Get-AddressList "$companyName AL" -domaincontroller $DC | Remove-ADPermission -User "Authenticated Users" -accessrights GenericRead -extendedrights "open address list" -deny:$false -domaincontroller $DC #" " #".............................................." "9 of 15, Granting permissions for users of $CompanyName to view the Address List for $CompanyName" ".............................................." get-addresslist "$companyname AL" -domaincontroller $DC | add-adpermission -USER "$CompanyName SG" -extendedrights "Open Address list" -deny:$false -domaincontroller $DC " " ".............................................." "10 of 15, Creating a Global Address List for $CompanyName" ".............................................." new-globaladdresslist -name "$CompanyName GAL" -recipientFilter {(alias -ne $null -and customattribute1 -eq $CompanyName)} -domaincontroller $DC " " ".............................................." "11 of 15, Updating the Address List for $CompanyName" ".............................................." update-AddressList "$CompanyName AL" -domaincontroller $DC " " ".............................................." "12 of 15, Updating the Global Address List for $CompanyName" ".............................................." update-GlobalAddressList -Identity "$CompanyName GAL" -domaincontroller $DC " " ".............................................." "13 of 15, Updating the Email Address Policy for $CompanyName" ".............................................." update-EmailAddressPolicy -Identity "$CompanyName" -domaincontroller $DC " " ".............................................." "14 of 15,Creating an Offline Address List for $CompanyName" ".............................................." # !!!! Will need to change the server name here !!!! # !!!! Specify the OAB Generation Server and the OAB Distribution Location !!!! new-offlineAddressBook -Name "$CompanyName OAB" -Server CON-MLT-2007.contoso.COM -AddressLists "$CompanyName AL" -PublicFolderDistributionEnabled $true -VirtualDirectories "CON-MLT-2007\OAB (Default Web Site)" -domaincontroller $DC ".............................................." "15 of 15, Granting permissions for users of $CompanyName to view the Offline Address Book for $CompanyName" ".............................................." Get-OfflineAddressBook "$CompanyName OAB" -domaincontroller $DC | Add-ADPermission -User "$CompanyName SG" -ExtendedRights 'ms-Exch-Download-OAB' -Deny:$false -domaincontroller $DC $OAB = (get-offlineaddressbook "$CompanyName OAB" -domaincontroller $DC).distinguishedname $OU = (get-distributiongroup "$CompanyName SG" -domaincontroller $DC).organizationalunit $USG = (get-distributiongroup "$CompanyName SG" -domaincontroller $DC).name " " "==============================================" "Script for setup of $companyname complete" "==============================================" " " "For each user created in $Companyname, set the following attributes to the specified values:" "customattribute1 = $CompanyName" "msExchUseOAB = $OAB" "msExchQueryBaseDN = $OU" "groupmembership = $USG" " " " " " " #==================================================== #=====confirmation Section - Output to HTML file===== #==================================================== $b3 = get-addresslist "$companyName AL"-domaincontroller $DC $b3a = $b3.recipientfilter $b4 = get-globaladdresslist "$companyName GAL"-domaincontroller $DC $b4a = $b4.recipientfilter $b5 = get-offlineaddressbook "$companyName OAB"-domaincontroller $DC $b5a = $b5.addresslists $b5b = $b5.distinguishedname $b6 = get-distributiongroup "$companyName SG" -domaincontroller $DC $b6a = $b6.grouptype $date = date set-content -path c:\$CompanyName.htm -value "<html> <title>Company Confirmation: $companyName</title> <head></head> <body> <h1>Company Confirmation: <font color=green>$Companyname</font></h1> <table> <tr><td><font size=2>The script will query each item listed and return the value in <font color=green>GREEN</font>. If the value is not found, it will not be listed. </td></tr> </table> <br> <table> <tr><td>Creation Date:</td><td><font color=green>$date</font></td></tr> <tr><td>AddressList:</td><td><font color=green>$b3 - $b3a</font></td></tr> <tr><td>GlobalAddressList:</td><td><font color=green>$b4 - $b4a</font></td></tr> <tr><td>OfflineAddressBook:</td><td><font color=green>$b5 - $b5a</font></td></tr> <tr><td>DistributionGroup:</td><td><font color=green>$b6 - $b6a</font></td></tr> </table> <table> <br> <tr><td> </td></tr> <tr><td><font size=2>For each user created in $CompanyName, you will set the following attributes to the underlined values:</td></tr> <tr><td><font size=2>customattribute1 - <u>$companyName</u> (In ADSIEdit its extensionattribute1)</td></tr> <tr><td><font size=2>msExchUseOAB - <u>$OAB</u> (IN EMS its -offlineaddressbook)</td></tr> <tr><td><font size=2>msExchQueryBaseDN - <u>$OU</u></td></tr> <tr><td><font size=2>groupmembership - <u>$USG</u></td></tr> <tr><td> </td></tr> </font> </table> </body> </html>" invoke-item c:\$companyname.htm
Modify the script to make it functional in your environment as detailed in the script remarks.
Move the script to the location containing the Exchange Server scripts. By default these are located at c:\Program Files\Microsoft\Exchange Server\Scripts\
Start the Exchange Management Shell.
NewCompany.ps1
Enter the company name and the company e-mail domain when you are prompted.
The following sample script must be modified as described in the script remarks in order to make it functional in your specific environment. This script will automate all of the steps required to provision a user for a specific a virtual company in your environment. We recommend that you create a new script for user creation for each virtual company that you host. To ensure that the appropriate script is run, you should name each script with a descriptive name like NewContosoUser.ps1.
Copy the following code into a file and save the file with a descriptive name and the .ps1 extension. It is recommended to name the file New<Company>User.ps1, where <Company> is replaced with the name of the company. For example NewContosoUser.ps1.
#"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" #"!!!!!!! THIS IS NOT A MICROSOFT SUPPORTED SCRIPT. !!!!!!!!" #"!!!!!!! TEST IN A LAB FOR DESIRED OUTCOME !!!!!!!!" #"!!!!!!! !!!!!!!!!!" #"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" # Changes required before running script: # Change Locations are mentioned in BOLD. If you have any other OU for HOSTING apart from Customers then you would need to search the OU and then perform the neccesary changes searching keyword companies. # - Change the DC name in Step No. 1. # - Change the domain and OU structure to match existing organization in step 6. # - change the database location to the desired database in the new-mailbox cmdlet. You could also leave this set to one database and then move the mailboxes to the desired mailbox store once they are created. # - change domain and OU information in step 11 # Once the changes have been made, comment out this line and the ones above using "#" at the beginning of the line. # Checks to see if samAccountName is a dupe and creates appropriate one function GetAvailableAccountName([string] $inputName) { $returnValue = $null $SamAccountName = $inputName $SamAccountIndex = 0 do { $tempUser = $null; # Special case as we don't want to add the index to the first query if($samAccountIndex -eq 0) { $potentialName = $samAccountName } else { $potentialName = [string]::Format("{0}{1}", $samAccountName, $samAccountIndex) } $samUser = Get-User -Filter {SamAccountName -eq $potentialName} -ErrorAction "SilentlyContinue" $mbxUser = Get-Mailbox -Filter {Alias -eq $potentialName} -ErrorAction "SilentlyContinue" $isUnique = ($samUser -eq $null) -and ($mbxUser -eq $null) if(!($isUnique)) { # Increment the index $samAccountIndex++; } }while(!($isUnique)) if($samAccountIndex -eq 0) { $returnValue = $samAccountName } else { $returnValue = [string]::Format("{0}{1}", $samAccountName, $samAccountIndex) } $returnValue } #check for "Companies" OU #---------------------------- #---------------------------- $eaSave = $ErrorActionPreference $ErrorActionPreference = "stop" #$ErrorActionPreference = "SilentlyContinue" "1 of 14" $DC = "con-dc" "Using DC - $DC to create the mailbox" $context = new-object System.DirectoryServices.ActiveDirectory.DirectoryContext([System.DirectoryServices.ActiveDirectory.DirectoryContextType]::DirectoryServer, $DC) $domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($context) $root = $domain.psbase.GetDirectoryEntry() # check if the 'Companies' ou exists $orgs = $null $orgs = $root.psbase.Children.psbase.Find("OU=Companies") if ($orgs -eq $null) { " " write-host "Cannot find an OU named 'Companies'"; exit " " } #----------------------------- #----------------------------- " " "2 of 14" "Enter User Company Name:" $UserCompany = [Console]::ReadLine().Trim() " " #check for this companies OU #-------------------------------- #-------------------------------- # find the org itself $newOrg = $null $newOrg = $orgs.psbase.Children.psbase.Find("ou="+$userCompany) if ($newOrg -eq $null) { " " write-host "Cannot find an OU named" $userCompany " " exit } #--------------------------------- #--------------------------------- "3 of 14" "Enter User First Name:" $UserFirst = [Console]::ReadLine() $UserFirst = $UserFirst.Trim() " " "4 of 14" "Enter User Last Name:" $UserLast = [Console]::ReadLine() $UserLast = $UserLast.Trim() " " "5 of 14" do { "Enter User UPN:" $UserUPN = [Console]::ReadLine() $userUPN = $UserUPN.Trim() $tmpUser = Get-User -Filter {UserPrincipalName -eq $userUPN} if($tmpUser -ne $null) { write-host "The upn already exists in the directory! Please enter a unique UPN" } } while($tmpUser -ne $null)" " "6 of 14, parsing UPN name" " " $useralias = $userUPN.split("@")[0] $userdomain = $userUPN.split("@")[1] $userFull = $UserFirst + " " + $UserLast $UserOU = "CONTOSO.COM/COMPANIES/" + $UserCompany $SamAccountName = $userAlias "7 of 14, creating mailbox" New-Mailbox -Name $UserFull -Alias $UserAlias -OrganizationalUnit $UserOU -UserPrincipalName $UserUPN -SamAccountName $SamAccountName -FirstName $UserFirst -LastName $UserLast -ResetPasswordOnNextLogon $false -Database "Mailbox Database" -domaincontroller $DC "8 of 14, setting customattribute1 to $userCompany" set-mailbox "$userAlias" -customattribute1 "$userCompany" -offlineaddressbook "$userCompany OAB" -domaincontroller $DC -EmailAddressPolicyEnabled $false -emailAddresses ("SMTP:" + $userAlias + "@" + $userDomain) -windowsEmailAddress ($useralias + "@" + $userdomain) "9 of 14, adding $userAlias to $usercompany security group" add-distributiongroupmember "$userCompany SG" -member "$userAlias" -domaincontroller $DC "10 of 14, updating Address List" update-addresslist "$usercompany AL" #============================= # Mailbox Confirmation Section #============================= $a1 = get-mailbox $UserAlias $a2 = $a1.name $a3 = $a1.addresslistmembership $a4 = $a1.OfflineAddressBook $a5 = $a1.userprincipalname $a6 = $a1.organizationalunit $a7 = $a1.customattribute1 $a8 = $a1.distinguishedname $a10 = $a1.emailaddresses "11 of 14, Setting msExchQueryBaseDN" #To Bind: $user = ([ADSI]"LDAP://$a8").psbase; #To Modify: $user.Properties["msExchQueryBaseDN"].Value = "ou=$a7,ou=Companies,dc=contoso,dc=com"; $user.CommitChanges(); $a9 = $user.Properties["msExchQueryBaseDN"] $a9b =$user.Properties["memberof"] "12 of 14, Display Attributes" " " "Address List Membership: $a3" "Alias: $userAlias" "CustomAttribute1: $a7" "DN: $a8" "Email Addresses: $a10" "Memberof: $a9b" "mxExchQueryBaseDN: $a9" "Offline Address Book: $a4" "UPN: $a5" "OU: $a6" "User Name: $a2" " " "13 of 14, output to HTM file" set-content -path c:\userconfirmation.htm -value "<html> <title>User Confirmation: $userFull</title> <head></head> <body> <h1>User Confirmation: <font color=green>$userfull</font></h1> <table> <tr><td><font size=2>The script will query the user just created and return a list of attributes that are needed to determine if the object has been provisioned corrrectly. Values will be listed in <font color=green>GREEN</font>. If the value is not found, it will not be listed. </td></tr> </table> <br> <table> <tr><td>Address List Membership:</td><td><font color=green>$a3</font></td></tr> <tr><td>Alias:</td><td><font color=green>$useralias</font></td></tr> <tr><td>CustomAttribute1:</td><td><font color=green>$a7</font></td></tr> <tr><td>DistinguishedName:</td><td><font color=green>$a8</font></td></tr> <tr><td>Email Addresses:</td><td><font color=green>$a10</font></td></tr> <tr><td>MemberOf:</td><td><font color=green>$a9b</font></td></tr> <tr><td>msExchQueryBaseDN:</td><td><font color=green>$a9</font></td></tr> <tr><td>Offline Address Book:</td><td><font color=green>$a4</font></td></tr> <tr><td>OU:</td><td><font color=green>$a6</font></td></tr> <tr><td>UPN:</td><td><font color=green>$a5</font></td></tr> </table> </body> </html>" "14 of 14, open HTM file" invoke-item c:\userconfirmation.htm
New<Company>User.ps1
Enter the appropriate company name, the user’s first name, the user’s last name, and the User Principal Name (UPN) when you are prompted.
When you test a user account after you create the new company and users, you should use a computer that is not logged on using the same administrator credentials as those used by the server. For example, do not perform an OWA test from the server on which you created the company and users. This practice helps prevent an issue in which you pass to Exchange the credentials for the local administrator account instead of the credentials for the user account that you are trying to test.
The following sample script must be modified as described in the script remarks in order to make it functional in your specific environment. This script will automate most of the steps required to remove a virtual company from your environment. For data protection purposes, the script will not delete the actual customer data contained in the virtual companies OU or remove the OU itself. Those steps should be performed manually.
Copy the following code into a file and save the file with a descriptive name and the .ps1 extension. It is recommended to name the file DeleteCompany.ps1.
#"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" #"!!!!!!! THIS IS NOT A MICROSOFT SUPPORTED SCRIPT. !!!!!!!!" #"!!!!!!! TEST IN A LAB FOR DESIRED OUTCOME !!!!!!!!" #"!!!!!!! !!!!!!!!!!" #"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" #" " ## Gets the company name ## "Enter the company name:" $CompanyName = [Console]::ReadLine() $CompanyName = $CompanyName.Trim() $eaSave = $ErrorActionPreference $ErrorActionPreference = "SilentlyContinue" " " "=====================================" " 1 of 8,if present, Removing Email Address Policy for $CompanyName" "=====================================" ## Removes a new email address policy ## remove-EmailAddressPolicy $CompanyName " " "=====================================" "2 of 8,if present, Removing the Accepted Domain entry for $CompanyName" "=====================================" ## Removes a new Accepted Domain for the company specified ## remove-AcceptedDomain $CompanyName " " "=====================================" "3 of 8,if present, Removing the Globlal Address List for $CompanyName" "=====================================" ## Removes a Global Address List policy ## remove-globaladdresslist "$CompanyName GAL" " " "=====================================" "4 of 8,if present, Removing the Offline Address Book for $CompanyName" "=====================================" ## !!!! Will need to change the server name here !!!! ## remove-OfflineAddressBook "$CompanyName OAB" " " "=====================================" "5 of 8,if present, Removing the Address List for $CompanyName" "=====================================" remove-AddressList "$CompanyName AL" " " "=====================================" "7 of 8,if present, Removing the security group for $CompanyName" "=====================================" remove-distributiongroup "$CompanyName SG" " " "******************************************" "The $companyName Company has been Removed" "******************************************"
DeleteCompany.ps1
Enter the name of the company to be removed when prompted.
ADSIEdit is included with the Windows 2003 support tools which can be found on the Windows 2003 CD.
By following the recommendations and procedures contained in this white paper, you should be able to successfully configure and maintain segregated address lists in your Exchange 2007 environment.
For the complete Exchange 2007 documentation set, see Exchange Server 2007 Help.
#"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"#"!!!!!!! THIS IS NOT A MICROSOFT SUPPORTED SCRIPT. !!!!!!!!"#"!!!!!!! TEST IN A LAB FOR DESIRED OUTCOME !!!!!!!!"#"!!!!!!! !!!!!!!!!!"#"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"# Changes required before running script:# Change Locations are mentioned in BOLD. If you have any other OU for HOSTING apart from Customers then you would need to search the OU and then perform the neccesary changes searching keyword companies.# - Change the DC name in Step No. 1.# - Change the domain and OU structure to match existing organization in step 6.# - change the database location to the desired database in the new-mailbox cmdlet. You could also leave this set to one database and then move the mailboxes to the desired mailbox store once they are created.# - change domain and OU information in step 11# Once the changes have been made, comment out this line and the ones above using "#" at the beginning of the line.# Checks to see if samAccountName is a dupe and creates appropriate onefunction GetAvailableAccountName([string] $inputName){$returnValue = $null$SamAccountName = $inputName$SamAccountIndex = 0do{$tempUser = $null;# Special case as we don't want to add the index to the first queryif($samAccountIndex -eq 0){$potentialName = $samAccountName}else{$potentialName = [string]::Format("{0}{1}", $samAccountName, $samAccountIndex)}$samUser = Get-User -Filter {SamAccountName -eq $potentialName} -ErrorAction "SilentlyContinue"$mbxUser = Get-Mailbox -Filter {Alias -eq $potentialName} -ErrorAction "SilentlyContinue"$isUnique = ($samUser -eq $null) -and ($mbxUser -eq $null)if(!($isUnique)){# Increment the index$samAccountIndex++;}}while(!($isUnique))if($samAccountIndex -eq 0){$returnValue = $samAccountName}else{$returnValue = [string]::Format("{0}{1}", $samAccountName, $samAccountIndex)}$returnValue}#check for "Companies" OU#----------------------------#----------------------------$eaSave = $ErrorActionPreference$ErrorActionPreference = "stop"#$ErrorActionPreference = "SilentlyContinue""1 of 14"$DC = "dc01""Using DC - $DC to create the mailbox"$context = new-object System.DirectoryServices.ActiveDirectory.DirectoryContext([System.DirectoryServices.ActiveDirectory.DirectoryContextType]::DirectoryServer, $DC)$domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetDomain($context)$root = $domain.psbase.GetDirectoryEntry()# check if the 'Companies' ou exists$orgs = $null$orgs = $root.psbase.Children.psbase.Find("OU=Companies")if ($orgs -eq $null) {" "write-host "Cannot find an OU named 'Companies'"; exit" "}#-----------------------------#-----------------------------" ""2 of 14""Enter User Company Name:"$UserCompany = [Console]::ReadLine().Trim()" "#check for this companies OU#--------------------------------#--------------------------------# find the org itself$newOrg = $null$newOrg = $orgs.psbase.Children.psbase.Find("ou="+$userCompany)if ($newOrg -eq $null) {" "write-host "Cannot find an OU named" $userCompany" "exit}#---------------------------------#---------------------------------"3 of 14""Enter User First Name:"$UserFirst = [Console]::ReadLine()$UserFirst = $UserFirst.Trim()" ""4 of 14""Enter User Last Name:"$UserLast = [Console]::ReadLine()$UserLast = $UserLast.Trim()" ""5 of 14"do{"Enter User UPN:"$UserUPN = [Console]::ReadLine()$userUPN = $UserUPN.Trim()$tmpUser = Get-User -Filter {UserPrincipalName -eq $userUPN}if($tmpUser -ne $null){write-host "The upn already exists in the directory! Please enter a unique UPN" }}while($tmpUser -ne $null)" ""6 of 14, parsing UPN name"" "$useralias = $userUPN.split("@")[0]$userdomain = $userUPN.split("@")[1]$userFull = $UserFirst + " " + $UserLast$UserOU = "CONTOSO.COM/COMPANIES/" + $UserCompany$SamAccountName = $userAlias"7 of 14, creating mailbox"New-Mailbox -Name $UserFull -Alias $UserAlias -OrganizationalUnit $UserOU -UserPrincipalName $UserUPN -SamAccountName $SamAccountName -FirstName $UserFirst -LastName $UserLast -ResetPasswordOnNextLogon $false -Database "Mailbox Database" -domaincontroller $DC"8 of 14, setting customattribute1 to $userCompany"set-mailbox "$userAlias" -customattribute1 "$userCompany" -offlineaddressbook "$userCompany OAB" -domaincontroller $DC -EmailAddressPolicyEnabled $false -emailAddresses ("SMTP:" + $userAlias + "@" + $userDomain) -windowsEmailAddress ($useralias + "@" + $userdomain)"9 of 14, adding $userAlias to $usercompany security group"add-distributiongroupmember "$userCompany SG" -member "$userAlias" -domaincontroller $DC"10 of 14, updating Address List"update-addresslist "$usercompany AL"#=============================# Mailbox Confirmation Section#=============================$a1 = get-mailbox $UserAlias$a2 = $a1.name$a3 = $a1.addresslistmembership$a4 = $a1.OfflineAddressBook$a5 = $a1.userprincipalname$a6 = $a1.organizationalunit$a7 = $a1.customattribute1$a8 = $a1.distinguishedname$a10 = $a1.emailaddresses"11 of 14, Setting msExchQueryBaseDN"#To Bind:$user = ([ADSI]"LDAP://$a8").psbase;#To Modify:$user.Properties["msExchQueryBaseDN"].Value = "ou=$a7,ou=Companies,dc=contoso,dc=com";$user.CommitChanges();$a9 = $user.Properties["msExchQueryBaseDN"]$a9b =$user.Properties["memberof"]"12 of 14, Display Attributes"" ""Address List Membership: $a3""Alias: $userAlias""CustomAttribute1: $a7""DN: $a8""Email Addresses: $a10""Memberof: $a9b""mxExchQueryBaseDN: $a9""Offline Address Book: $a4""UPN: $a5""OU: $a6""User Name: $a2"" ""13 of 14, output to HTM file"set-content -path c:\userconfirmation.htm -value "<html><title>User Confirmation: $userFull</title><head></head><body><h1>User Confirmation: <font color=green>$userfull</font></h1><table><tr><td><font size=2>The script will query the user just created and return a list of attributes that are needed to determine if the object has been provisioned corrrectly. Values will be listed in <font color=green>GREEN</font>. If the value is not found, it will not be listed. </td></tr></table><br><table><tr><td>Address List Membership:</td><td><font color=green>$a3</font></td></tr><tr><td>Alias:</td><td><font color=green>$useralias</font></td></tr><tr><td>CustomAttribute1:</td><td><font color=green>$a7</font></td></tr><tr><td>DistinguishedName:</td><td><font color=green>$a8</font></td></tr><tr><td>Email Addresses:</td><td><font color=green>$a10</font></td></tr><tr><td>MemberOf:</td><td><font color=green>$a9b</font></td></tr><tr><td>msExchQueryBaseDN:</td><td><font color=green>$a9</font></td></tr><tr><td>Offline Address Book:</td><td><font color=green>$a4</font></td></tr><tr><td>OU:</td><td><font color=green>$a6</font></td></tr><tr><td>UPN:</td><td><font color=green>$a5</font></td></tr></table></body></html>""14 of 14, open HTM file"invoke-item c:\userconfirmation.htm