Exchange 2007 Hosted Exchange Project

This script was part of a test project I was involved with back in 2009 setting up a hosted exchange environment.  The project was scrapped by the people paying the bills before it ever went live, partly because 2010 was about to come out, partly because they finally started to believe me about how much it was going to cost to do it right.  Either way these are the hosted client setup scripts that I built for creating new hosting clients as well as creating new users for those clients.

Remember these were early scripts put together to show the client how the system would function, they were intended to be expanded upon and turned into a full management system at a later date.

Since no-one is likely to be building a 2007 hosted Exchange environment at this time I imagine the scripts are not of any direct use anymore, but there are a number of pieces in them that would still make a great reference for someone.

New Hosting Client:

#****************************************************************************"
#****************************************************************************"
#****************************************************************************"

# Script Variables section - complete before deploying

#Domain Controller to connect to
$DCName = "CIS-VAD01"

#top level domain name of AD (ex the local of domain.local)
$DomainTLD = "local"

#Second Level domain name of AD (ex the domain of domain.local)
$DomainSLD = "CIS"

#Domain NetBIOS Name
$DomainNBName = "CIS"

#OU name under root of domain to create security group (Must also match name of Storage Group for Mailbox Databases)
$OUName = "Hosting Clients"

#Exchange Org Name (CN=ORG NAME,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=Domain,DC=local
$OrgName = "Contoso Internet Services"

#Exchange Server Name
$ExSrvName = "CIS-VXSRV01"

#Exchange Administrative Group Name (CN=Exchange Administrative Group (RandomID),CN=Administrative Groups,CN=Contoso Internet Services,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=Domain,DC=local)
$ExAdminID = "Exchange Administrative Group (FYDIBOHF23SPDLT)"

#Path to store mailbox database on exchange server above
$EDBPath = "E:\Exchange Server\Mailbox\Hosting Clients\"

#****************************************************************************"
#****************************************************************************"
#****************************************************************************"

CLS

$CompanyID = read-host "Enter 3 letter company code (Ex. CIS)"
$DomainName = read-host "Enter primary domain name (Ex. Contoso.com)"
$EmailPolicy = read-host "Enter exchange recipient naming policy(Ex. %1g%s)"

CLS

write-host "*******************************************************************"
write-host " "
write-host "1) You should only be performing this if you have been trained on this procedure!"
write-host " "
write-host "2) Do you understand that this will make significant changes to the production system, and will be very difficult to undo if you made any typos?"
write-host " "
write-host "*******************************************************************"
$Answer1 = read-host "Enter Yes! if you understand (Case Sensitive)."

If ($Answer1 -eq "Yes!") {
	CLS
	write-host "The following values will be used:"
	write-host "Company ID: " $CompanyID
	write-host "Domain Name: " $DomainName
	write-host "EMail Generation Policy: " $EmailPolicy
	$Answer2 = read-host "Enter Yes2 if all of the above are correct."

	If ($Answer2 -eq "Yes2") {

#Create OU
$Connect = "LDAP://" + $DCName + "/DC=" + $DomainSLD + ",DC=" + $DomainTLD
$AD = [adsi] $Connect
$OU = $AD.Create("OrganizationalUnit", "OU=" + $CompanyID + ",OU=" + $OUName)
$OU.SetInfo()

#Create UPN
$connect = "LDAP://" + $DCName + "/CN=Partitions,CN=Configuration,DC=" + $DomainSLD + ",DC=" + $DomainTLD
$objGroup = [ADSI] $connect
$objGroup.PutEx(3,"uPNSuffixes",@("$DomainName"))
$objGroup.SetInfo()

#Create Security Group
$GroupName = $CompanyID + "-Users"
$OU = $DomainSLD + "." + $DomainTLD + "/" + $OUName + "/" + $CompanyID
new-DistributionGroup -Name $GroupName -Type 'Security' -OrganizationalUnit $OU -SamAccountName $GroupName  -Alias $GroupName

$connect = "LDAP://" + $DCName + "/cn=" + $GroupName + ",OU=" + $CompanyID + ",OU=" + $OUName + ",DC=" + $DomainSLD + ",DC=" + $DomainTLD
$objGroup = [ADSI] $connect
$objGroup.Put("extensionAttribute1", $CompanyID)
$objGroup.SetInfo()

#Create Accepted Domain Policy
$Name = $CompanyID + "-" + $DomainName
new-AcceptedDomain -Name $Name -DomainName $DomainName -DomainType 'Authoritative'

#Create/Apply EMail address Policy
$Emailformat = "SMTP:" + $EmailPolicy + "@" + $DomainName
new-EmailAddressPolicy -Name $CompanyID -IncludedRecipients 'AllRecipients' -ConditionalCustomAttribute1 $CompanyID -Priority 'Lowest' -EnabledEmailAddressTemplates $Emailformat
update-EmailAddressPolicy -Identity $CompanyID

#Create Address List
$Identity = "\" + $CompanyID
new-AddressList -Name $CompanyID -IncludedRecipients 'AllRecipients' -ConditionalCustomAttribute1 $CompanyID -Container '\'
update-AddressList -Identity $Identity

#Create Offline Address Book
$VD = $ExSrvName + "\OAB (Default Web Site)"
new-OfflineAddressBook -Name $CompanyID -Server $ExSrvName -AddressLists $Identity -PublicFolderDistributionEnabled $false -VirtualDirectories $VD

#Create Global Address List
New-GlobalAddressList -Name $CompanyID -ConditionalCustomAttribute1 $CompanyID -IncludedRecipients AllRecipients

#Set AddressList Permissions
$GroupID = $DomainNBName + "\" + $GroupName

$container = "CN=" + $CompanyID + ",CN=All Global Address Lists,CN=Address Lists Container,CN=" + $OrgName + ",CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=" + $DomainSLD + ",DC=" + $DomainTLD
Add-ADPermission $container -User $GroupID -AccessRights GenericRead, ListChildren -ExtendedRights Open-Address-Book

#enumerate existing GALs to set deny read permissions
$GALs = Get-GlobalAddressList |where {$_.name -ne $CompanyID}

If ($GALs -is [array]) {
	foreach($GAL in $GALs) {

		#deny rights on existing containers to new group id
		$excontainer = "CN=" + $GAL.Name + ",CN=All Global Address Lists,CN=Address Lists Container,CN=" + $OrgName + ",CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=" + $DomainSLD + ",DC=" + $DomainTLD
		Add-ADPermission $excontainer -User $GroupID -Deny -AccessRights GenericRead -ExtendedRights Open-Address-Book

		#deny rights on new containers to existing group ids
		$exGroupID = $DomainNBName + "\" + $GAL.Name + "-Users"
		Add-ADPermission $container -User $exGroupID -Deny -AccessRights GenericRead -ExtendedRights Open-Address-Book
		}

	}
Else {
	$excontainer = "CN=" + $GALs.Name + ",CN=All Global Address Lists,CN=Address Lists Container,CN=" + $OrgName + ",CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=" + $DomainSLD + ",DC=" + $DomainTLD
	Add-ADPermission $excontainer -User $GroupID -Deny -AccessRights GenericRead -ExtendedRights Open-Address-Book
	}

$container = "CN=" + $CompanyID + ",CN=All Address Lists,CN=Address Lists Container,CN=" + $OrgName + ",CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=" + $DomainSLD + ",DC=" + $DomainTLD
Add-ADPermission $container -User $GroupID -AccessRights GenericRead, ListChildren -ExtendedRights Open-Address-Book

#enumerate existing ALs to set deny read permissions
$ALs = Get-GlobalAddressList |where {$_.name -ne $CompanyID}

If ($ALs -is [array]) {
	foreach($AL in $ALs) {

		#deny rights on existing containers to new group id
		$excontainer = "CN=" + $AL.name + ",CN=All Address Lists,CN=Address Lists Container,CN=" + $OrgName + ",CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=" + $DomainSLD + ",DC=" + $DomainTLD
		Add-ADPermission $excontainer -User $GroupID -Deny -AccessRights GenericRead -ExtendedRights Open-Address-Book

		#deny rights on new containers to existing group ids
		$exGroupID = $DomainNBName + "\" + $AL.Name + "-Users"
		Add-ADPermission $container -User $exGroupID -Deny -AccessRights GenericRead -ExtendedRights Open-Address-Book
		}

	}
Else {
	$container = "CN=" + $ALs.Name + ",CN=All Address Lists,CN=Address Lists Container,CN=" + $OrgName + ",CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=" + $DomainSLD + ",DC=" + $DomainTLD
	Add-ADPermission $container -User $GroupID -Deny -AccessRights GenericRead -ExtendedRights Open-Address-Book
	}

$container = "CN=" + $CompanyID + ",CN=Offline Address Lists,CN=Address Lists Container,CN=" + $OrgName + ",CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=" + $DomainSLD + ",DC=" + $DomainTLD
Add-ADPermission $container -User $GroupID -AccessRights GenericRead, ListChildren -ExtendedRights ms-Exch-Download-OAB

#Enable Address Book Root
#disabled - not necessary
#Const ADS_PROPERTY_CLEAR = 1
#Const ADS_PROPERTY_UPDATE = 2
#Const ADS_PROPERTY_APPEND = 3
#Const ADS_PROPERTY_DELETE = 4
#$connect = "LDAP://" + $DCName + "/CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=" + $DomainSLD + ",DC=" + $DomainTLD
#$objGroup = [ADSI] $connect
#$List = "CN=" + $CompanyID + ",CN=All Address Lists,CN=Address Lists Container,CN=" + $OrgName + ",CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=" + $DomainSLD + ",DC=" + $DomainTLD
#$objGroup.PutEx(3,"addressBookRoots",@("$List"))
#$objGroup.SetInfo()

#Create and Mount Mailbox Database
$Filename = $EDBPath + $CompanyID + "\" + $CompanyID + ".edb"
$SG = $ExSrvName + "\" + $OUName
new-mailboxdatabase -StorageGroup $SG -Name $CompanyID -EdbFilePath $FileName
$DBIdentity = "CN=" + $CompanyID + ",CN=" + $OUName + ",CN=InformationStore,CN=" + $ExSrvName + ",CN=Servers,CN=" + $ExAdminID + ",CN=Administrative Groups,CN=" + $OrgName + ",CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=" + $DomainSLD + ",DC=" + $DomainTLD
mount-database -Identity $DBIdentity

#Set Offline Address Book for Database
Set-MailboxDatabase -Identity $DBIdentity -OfflineAddressBook $CompanyID

#Create Public Folder Tree
New-PublicFolder -Name $CompanyID
$Identity = "\" + $CompanyID
Remove-PublicFolderClientPermission -Identity $Identity  -User "Anonymous" -AccessRight CreateItems -Confirm:$false
Remove-PublicFolderClientPermission -Identity $Identity  -User "Default" -AccessRight Author -Confirm:$false
Add-PublicFolderClientPermission -Identity $Identity  -User $GroupName -AccessRight PublishingAuthor

	}
	Else
		{Write-Host "Quitting, re-enter data"}
}
Else
	{Write-Host "Quitting"}

New User for Hosted Client:

#****************************************************************************"
#****************************************************************************"
#****************************************************************************"

# Script Variables section - complete before deploying

#Domain Controller to connect to
$DCName = "CIS-VAD01"

#top level domain name of AD (ex the local of domain.local)
$DomainTLD = "local"

#Second Level domain name of AD (ex the domain of domain.local)
$DomainSLD = "CIS"

#Domain NetBIOS Name
$DomainNBName = "CIS"

#OU name under root of domain to create security group (Must also match name of Storage Group for Mailbox Databases)
$OUName = "Hosting Clients"

#Exchange Org Name (CN=ORG NAME,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=Domain,DC=local
$OrgName = "Contoso Internet Services"

#Exchange Server Name
$ExSrvName = "CIS-VXSRV01"

#Exchange Administrative Group Name (CN=Exchange Administrative Group (RandomID),CN=Administrative Groups,CN=Contoso Internet Services,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=Domain,DC=local)
$ExAdminID = "Exchange Administrative Group (FYDIBOHF23SPDLT)"


#****************************************************************************"
#****************************************************************************"
#****************************************************************************"

CLS
$CompanyID = read-host "Enter 3 letter company code (Ex. CIS)"


$Check = Get-EmailAddressPolicy |where {$_.name -like $CompanyID + "*"}

If ($Check.ConditionalCustomAttribute1 -eq $CompanyID) {
	$Domains = Get-AcceptedDomain |where {$_.name -like $CompanyID + "*"}

	If ($Domains -is [array]) {
	
		$x=0
		foreach($Domain in $Domains) {
			$line = [string] $x
			$Display = $line + ") " + $Domain.DomainName
			Write-Host $Display
			$x = ++$x
			}

		$DomainNum = read-host "Choose line number for accepted domain "
		$DomainNum = [int] $DomainNum
		$DomainName = $Domains[$DomainNum].DomainName

		}
	Else 
		{
		$DomainName = $domains.domainname 
		}


#enter create script here

	$FName = read-host "Enter Users First Name"
	$LName = read-host "Enter Users Last Name"
	$MName = read-host "Enter Users Middle Name (optional)"
	$UName = read-host "Enter Users Logon Name (Defaults to firstname.lastname if blank)"

CLS

	$OAB = "CN=" + $CompanyID + ",CN=Offline Address Lists,CN=Address Lists Container,CN=" + $OrgName + ",CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=" + $DomainSLD + ",DC=" + $DomainTLD

	If ($UName -eq "") {$UName = $FName + "." + $LName}

	$Password = read-host "Enter Users Password (Defaults to 2ChangeMe if blank)"
	If ($Password -eq "") {$Password = "2ChangeMe"}
	$SecurePassword = ConvertTo-SecureString $password -AsPlainText -Force

	$GroupName = $CompanyID + "-Users"
	$DisplayName = $FName + " " + $LName
	$OU = $DomainSLD + "." + $DomainTLD + "/" + $OUName + "/" + $CompanyID
	$LDOU = "OU=" + $CompanyID + ",OU=" + $OUName + ",DC=" + $DomainSLD + ",DC=" + $DomainTLD
	$UPN = $UName + "@" + $DomainName
	$DBName = $ExSrvName + "\" + $OUName + "\" + $CompanyID

	New-Mailbox -Name $DisplayName -Alias $UName -OrganizationalUnit $OU -UserPrincipalName $UPN -SamAccountName $UName -FirstName $FName -LastName $LName -Initials $MName -Password $SecurePassword -ResetPasswordOnNextLogon $false -Database $DBName

	$connect = "LDAP://" + $DCName + "/cn=" + $DisplayName + ",OU=" + $CompanyID + ",OU=" + $OUName + ",DC=" + $DomainSLD + ",DC=" + $DomainTLD
	$objGroup = [ADSI] $connect
	$objGroup.Put("extensionAttribute1", $CompanyID)
	$objGroup.Put("msExchUseOAB", $OAB)
	$objGroup.Put("msExchQueryBaseDN", $LDOU)
	$objGroup.SetInfo()

	$Connection = "LDAP://" + $DCName + "/cn=" + $GroupName + ",OU=" + $CompanyID + ",OU=" + $OUName + ",DC=" + $DomainSLD + ",DC=" + $DomainTLD
	$Group = [adsi] $Connection
	$Group.Add($connect)

	set-user -Identity $UName -Company $CompanyID -Office $CompanyID

#end create script

	}

Else {
	CLS
	write-host "No Matching Email Policy found for this Company ID, Exiting"
}