Lab Setup – Script – Part2

The second article in this series will continue the Lab Setup Script. This part of the script I wrote will cover these options: populating calendar entries, populating task entries, configuring impersonation, mailbox quotas, DLP policies, and adding a disclaimer. In the next article I will cover mobile devices, retention policies, enabling archives, OWA policies and configuring APPs.

Let’s dive right on in:

New, Extended Menu: (circled items are covered in this post)

LabSetup2-01

Populating Calendar Entries
Populating calendar entries requires a bit of EWS programming and not being a programmer, or knowing the interface for EWS very well, I turned to the Internet looking for someone who has (See my article on methodology). After a bit of research I found a good article I’ve used with one customer with great success. I’ve included the code here and referenced the author in the description section of the full script (all sections are collapsed by default):

# Code section for the menu
7 {# 	Populate calendars
	# Create sample calendar entries and exported it to a PST file
	# Import these into random mailboxes
	write-host "This function assumes you have the correct rights." -fore red
	write-host " "
	start-sleep 5
	Create-CalendarEvents
}

# Import calendar events
function Create-CalendarEvents {
    $events = import-csv c:\scripts\calendarevents.csv
    $import = read-host "Do you want to import calendar events into all mailboxes or random mailboxes ['a' or 'r']"
    
    if ($import -eq "a") {
        $mailboxes = (get-mailbox | where {$_.RecipientTypeDetails -ne "DiscoveryMailbox"}).primarysmtpaddress
        foreach ($line in $mailboxes) {
            $primary = $line.local+"@"+$line.domain
            foreach ($line in $events) {
                # get-mailbox | new-calendarevent -subject $line.subject -date $line.date -impersonate
                new-calendarevent -identity $primary -subject $line.subject -date $line.date  -impersonate
            }
            write-host "Calendar entries for $line.displayname have been added." -foregroundcolor green    
        }
    } else {
        $mbxcount = (get-mailbox | where {$_.RecipientTypeDetails -ne "DiscoveryMailbox"}).count
        $range =  get-random -minimum 0 -maximum $mbxcount
        $counter = 0
        $mailbox = (get-mailbox | where {$_.RecipientTypeDetails -ne "DiscoveryMailbox"}).primarysmtpaddress
        while ($counter -lt $range) {
            foreach ($line in $events) {
                            $address = $mailbox[$counter]
                $primary = $address.local+"@"+$address.domain
                get-mailbox $mailbox[$counter] | new-calendarevent -subject $line.subject -date $line.date -impersonate
            }
            $counter++
            write-host "Calendar entries for $mailbox[$counter] have been added." -foregroundcolor green    
        }
    }
} # End Create Calendar Items Function

# Create Calendar Entries

function new-calendarevent { 

    [CmdletBinding(DefaultParametersetName='Identity')] 

    param( 
        [Parameter(Position=0, ParameterSetName='Identity')] 
        $Identity, 

        [Parameter(Position=1, Mandatory=$true)] 
        $Subject, 

        [Parameter(Position=2, Mandatory=$true)] 
        $Date, 

        [Parameter(Position=3)] 

        [Switch]$Impersonate, 

        [Parameter(Position=4)] 
        $ExchangeVersion = 'Exchange2013_CU7', 

        [Parameter(Position=5, ParameterSetName='Pipeline', ValueFromPipelineByPropertyName=$true)] 
        $PrimarySmtpAddress, 

        [Parameter(Position=6)] 
        [System.Management.Automation.PSCredential] 
        $Credential, 
        [Parameter(Position=7)] 
        $EWSUrl  
    ) 

    begin { 
        #Load the EWS Assembly 
        Add-Type -Path "C:\Program Files\Microsoft\Exchange Server\V15\Bin\Microsoft.Exchange.WebServices.dll"
    } 

    process { 
        #Is the identity coming from the pipeline? 
        if($PsCmdlet.ParameterSetName -eq 'Pipeline') { 
            $Identity = $PrimarySmtpAddress.ToString() 
        } 

        #Create the ExchangeService object 
        $service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService -ArgumentList ([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::$ExchangeVersion) 

        #If Credential parameter used, set the credentials on the $service object 
        if($Credential) { 
            $service.Credentials = New-Object Microsoft.Exchange.WebServices.Data.WebCredentials -ArgumentList $Credential.UserName, $Credential.GetNetworkCredential().Password 
        } 

        #If EWSUrl parameter not used, locate the end-point using autoD 
        if(!$EWSUrl) { 
            $service.AutodiscoverUrl($Identity, {$true}) 
        } 
        else { 
            $service.Url = New-Object System.Uri -ArgumentList $EWSUrl 
        }         

        #If Impersonation parameter used, impersonate the user 
        if($Impersonate) { 
            $ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId -ArgumentList ([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress),$Identity 
            $service.ImpersonatedUserId = $ImpersonatedUserId 
        } 

        #Configure the start and end time for this all day event 
        $start = (get-date $date) 
        $end = $start.addhours(24) 

        #Create and save the appointment 
        $appointment = New-Object Microsoft.Exchange.WebServices.Data.Appointment -ArgumentList $service 
        $appointment.Subject = $Subject 
        $appointment.Start = $Start 
        $appointment.End = $End 
        $appointment.IsAllDayEvent = $true 
        $appointment.IsReminderSet = $false 
        $appointment.Categories.Add('Holiday') 
        $appointment.Location = 'United States' 
        $appointment.LegacyFreeBusyStatus = [Microsoft.Exchange.WebServices.Data.LegacyFreeBusyStatus]::Free 
        $appointment.Save([Microsoft.Exchange.WebServices.Data.SendInvitationsMode]::SendToNone)  
    }  
} 

A sample run-through of Option 7:

LabSetup2-02

This section of code pulls from a list of holidays/calendar entries stored in a CSV file:

LabSetup2-03

For calendar entries you can add them to all mailboxes (option ‘a’) or to random mailboxes (option ‘r’). The list of mailboxes that have calendar entries are displayed as the script processes the mailbox. This option does require impersonation so make sure that the user account has the correct rights to perform this action.

Populating Task Entries

# Code section for the menu

8 {#	Populate Tasks
	# Create sample calendar entries and exported it to a PST file
	# Import these into random mailboxes
	write-host "This function assumes you have the correct rights." -fore red
	write-host " "
	start-sleep 5
	Create-Tasks
}

# Code section - Initial Function (decision making)

# Import Tasks
function Create-Tasks {
    $tasks = import-csv c:\scripts\tasks.csv
    $import = read-host "Do you want to import calendar events into all mailboxes or random mailboxes ['a' or 'r']"
        
    if ($import -eq "a") {
        $mailboxes = (get-mailbox | where {$_.RecipientTypeDetails -ne "DiscoveryMailbox"}).primarysmtpaddress
        foreach ($line in $mailboxes) {
            $primary = $line.local+"@"+$line.domain
            foreach ($line2 in $tasks) {
                # get-mailbox | new-task -subject $line.subject -date $line.date -impersonate
                new-task -identity $primary -subject $line2.subject -startdate $line2.startdate -enddate $line2.enddate -impersonate
            }
            write-host "Task entries for $line.displayname have been added." -foregroundcolor green    
        }
    } else {
        $mbxcount = (get-mailbox | where {$_.RecipientTypeDetails -ne "DiscoveryMailbox"}).count
        $range =  get-random -minimum 0 -maximum $mbxcount
        $counter = 0
        $mailbox = (get-mailbox | where {$_.RecipientTypeDetails -ne "DiscoveryMailbox"}).primarysmtpaddress
        while ($counter -lt $range) {
            foreach ($line in $tasks) {
                $address = $mailbox[$counter]
                $primary = $address.local+"@"+$address.domain
                get-mailbox $primary | new-task -subject $line.subject -startdate $line.startdate -enddate $line.enddate -impersonate
            }
            write-host "Task entries for $primary have been added." -foregroundcolor green
            $counter++
        }
    }
} # End Create Tasks Function

# Code section - Initial Function (decision making)
# Create Task Entries

function new-task { 

    [CmdletBinding(DefaultParametersetName='Identity')] 

    param( 
        [Parameter(Position=0, ParameterSetName='Identity')] 
        $Identity, 

        [Parameter(Position=1, Mandatory=$true)] 
        $subject, 

        [Parameter(Position=2, Mandatory=$true)] 
        $StartDate, 

        [Parameter(Position=3, Mandatory=$true)]
        $EndDate,

        [Switch]$Impersonate, 

        [Parameter(Position=4)] 
	# UPDATED to Exchange 2013
        $ExchangeVersion = 'Exchange2013_SP1', 

        [Parameter(Position=5, ParameterSetName='Pipeline', ValueFromPipelineByPropertyName=$true)] 
        $PrimarySmtpAddress, 

        [Parameter(Position=6)] 
        [System.Management.Automation.PSCredential] 
        $Credential, 
        [Parameter(Position=7)] 
        $EWSUrl  
    ) 

    begin { 
        #Load the EWS Assembly - UPDATED to Exchange 2013
        Add-Type -Path "C:\Program Files\Microsoft\Exchange Server\V15\Bin\Microsoft.Exchange.WebServices.dll"
    } 

    process { 
        #Is the identity coming from the pipeline? 
        if($PsCmdlet.ParameterSetName -eq 'Pipeline') { 
            $Identity = $PrimarySmtpAddress.ToString() 
        } 

        #Create the ExchangeService object 
        $service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService -ArgumentList ([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::$ExchangeVersion) 

        #If Credential parameter used, set the credentials on the $service object 
        if($Credential) { 
            $service.Credentials = New-Object Microsoft.Exchange.WebServices.Data.WebCredentials -ArgumentList $Credential.UserName, $Credential.GetNetworkCredential().Password 
        } 

        #If EWSUrl parameter not used, locate the end-point using autoD 
        if(!$EWSUrl) { 
            $service.AutodiscoverUrl($Identity, {$true}) 
        } 
        else { 
            $service.Url = New-Object System.Uri -ArgumentList $EWSUrl 
        }         

        #If Impersonation parameter used, impersonate the user 
        if($Impersonate) { 
            $ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId -ArgumentList ([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress),$Identity 
            $service.ImpersonatedUserId = $ImpersonatedUserId 
        } 

        #Create and save the task
        $task = New-Object Microsoft.Exchange.WebServices.Data.Task -ArgumentList $service 
        $task.Subject = $subject
        $task.StartDate = $startdate
        $task.DueDate = $enddate
        $task.Save([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Tasks)
        # ([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Notes)  
    }  
} 

A sample run-through of Option 8:

LabSetup2-04

This section of code pulls from a list of task entries stored in a CSV file:

LabSetup2-05

For task entries you can add them to all mailboxes (option ‘a’) or to random mailboxes (option ‘r’). The list of mailboxes that have task entries are displayed as the script processes the mailbox. This option does require impersonation so make sure that the user account has the correct rights to perform this action.

Configure Impersonation
Impersonation can be used for many functions in Exchange, in the case of this script I use impersonation to handle certain tasks that if the right is missing, will fail. This step will either enable your current account or a different account. The script also checks to see if there is an existing impersonation role configured before creating one.

# Code section for the menu
20 {# Assign impersonation rights to the current user account
        add-impersonation
}

# Impersonation Function
function add-impersonation {
	$answer = read-host "Does your user account need the impersonation right before proceeding [y or n]"
	if ($answer -eq "y") {
		$user = [Environment]::UserName
		# Create Management Scope for impersonation
		if ((get-managementscope "impersonation") -eq $null) {
			New-ManagementScope –Name:Impersonation –RecipientRestrictionFilter {RecipientType -eq "UserMailbox"}
		}
		#Assign impersonation to a user
		New-ManagementRoleAssignment –Role:ApplicationImpersonation –User:$user –CustomRecipientWriteScope:Impersonation
	} else {
        	$answer2 = read-host "Does another user account need the impersonation right before proceeding [y or n]"
        	if ($answer2 -eq "y") {
			$user = read-host "Enter the name of the account that needs impersonation rights"
			# Create Management Scope for impersonation
			if ((get-managementscope "impersonation") -eq $null) {
				New-ManagementScope –Name:Impersonation –RecipientRestrictionFilter {RecipientType -eq "UserMailbox"}
			}
		#Assign impersonation to a user
		New-ManagementRoleAssignment –Role:ApplicationImpersonation –User:$user –CustomRecipientWriteScope:Impersonation
		}
	}
} # End of add-impersonation

LabSetup2-10
Adding DLP Policies
This section is based on my three part series where I call my XML script from the main lab setup script:

# Code section for the menu
9 {#	DLP Policy Creation -ForegroundColor Red
        # This location is where ever you downloaded the script to
        invoke-expression  "c:\scripts\XMLScript-Lab-1.3.ps1"
}

A sample run through of the script looks just like my article on this script that I’ve done before:

LabSetup2-06

At the very end I can import the XML file as a new Rule Classification for DLP:

LabSetup2-07

Then the script will create a DLP rule based on this criteria:

LabSetup2-12

Configure Mailbox Quotas
Script for the option is as follows:

# Code section for the menu
11 {#	Configure quotas
	configure-quotas
}

# Quotas Function
function configure-quotas {
    write-host "Enter your Quota values:"
    $iwq = read-host "Issue Warning Quota [in MB, unlimited]"
    if ([string]$iwq -ne "unlimited") {
        [string]$iwq = [string]$iwq+" MB"
    }
    [string]$psq = read-host "Prohibit Send Quota [in MB]"
    if ($psq -ne "unlimited") {
        [string]$psq = [string]$psq+" MB"
    }
    [string]$psrq = read-host "Prohibit Send/Receive Quota [in MB]"
    if ([string]$psrq -ne "unlimited") {
        [string]$psrq = [string]$psrq+" MB"
    }
    $answer = read-host "Do you want to apply the policies to all users or random users [a or r]"

    if ($answer -eq "a") {
        $mailboxes = (get-mailbox | where {$_.RecipientTypeDetails -ne "DiscoveryMailbox"}).primarysmtpaddress
        foreach ($line in $mailboxes) {
            $primary = $line.local+"@"+$line.domain
            set-mailbox $primary -ProhibitSendQuota $psq -ProhibitSendReceiveQuota $psrq -IssueWarningQuota $iwq -UseDatabaseQuotaDefaults $false
            write-host "The mailbox for $primary has had their quotas modified as requested:" -foregroundcolor green
            get-mailbox $primary | ft ProhibitSendQuota, ProhibitSendReceiveQuota, IssueWarningQuota, UseDatabaseQuotaDefaults
        }
        write-host "Quotas configured for all mailboxes as requested."

    } else {
        $mbxcount = (get-mailbox | where {$_.RecipientTypeDetails -ne "DiscoveryMailbox"}).count
        $range =  get-random -minimum 0 -maximum $mbxcount
        $counter = 0
        $mailbox = (get-mailbox | where {$_.RecipientTypeDetails -ne "DiscoveryMailbox"}).primarysmtpaddress
        while ($counter -lt $range) {
            $address = $mailbox[$counter]
            $primary = $address.local+"@"+$address.domain
            set-mailbox $primary -ProhibitSendQuota $psq -ProhibitSendReceiveQuota $psrq -IssueWarningQuota $iwq -UseDatabaseQuotaDefaults $false
            write-host "The mailbox for $primary has had their quotas modified as requested:" -foregroundcolor green
            get-mailbox $primary | ft ProhibitSendQuota, ProhibitSendReceiveQuota, IssueWarningQuota, UseDatabaseQuotaDefaults
        }
        write-host "Quotas configured for $range mailboxes as requested."
    }
    start-sleep 5
} # End of Quotas function

In this script, the Quotas option is rather simplified with either setting the three Quota values for all mailboxes or random mailboxes. Enter the number of MB needed for each value or use Unlimited. There is no check to validate the values at this time, but may be added in a future version of the script.

Here is a sample run through of the option:

LabSetup2-08

The script will report the changes made as they are made:

LabSetup2-09

Now you have quotas to test against in a lab environment.

Configure Disclaimer Text

# Code from the menu
12 {#	Configure disclaimers
	Check-OldDisclaimers
	Configure-NewDisclaimers
}

# Check for Old Disclaimers
function Check-OldDisclaimers {
    $rulecheck = (Get-TransportRule).ApplyHtmlDisclaimerText
    $rulecheck2 = get-transportrule | where {$_.ApplyHtmlDisclaimerText -ne $null}
    if ($rulecheck -eq $null) {
        write-host " "
        write-host "There are no disclaimers in place now." -foregroundcolor green
        write-host " "
    } else {
        foreach ($line in $rulecheck2) {
            write-host " "
            write-host "There is a transport rule in place called $line that is a disclaimer rule." -ForegroundColor Yellow
            write-host " "
        }
    }
}

# Add New Disclaimers
function Configure-NewDisclaimers {
    $name = read-host "Name of the disclaimer rule"
    $DisclaimerNameCheck = get-transportrule | where {$_.name -eq $name}
    if ($DisclaimerNameCheck -eq $null) {
        $text = read-host "Disclaimer text or HTML"
        New-TransportRule -FromScope 'NotInOrganization' -ApplyHtmlDisclaimerLocation 'Append' -ApplyHtmlDisclaimerText $text -ApplyHtmlDisclaimerFallbackAction 'Wrap' -Name $name -StopRuleProcessing:$false -Mode 'Enforce' -Comments '
' -RuleErrorAction 'Ignore' -SenderAddressLocation 'Header' 
    } else {
        write-host "There is a rule with the same name." -nonewline
        write-host " Please try the option again." -ForegroundColor Red
        write-host " "
        Configure-NewDisclaimers
    }
}

The disclaimer part of this script is pretty simplistic right now. There are a couple of configurable options – The name of the rule and the text of the disclaimer. Other options are hardcoded, like the location (Append), fall back action (wrap), mode (enforce), etc.

Here is a sample run of the script:

LabSetup2-11

At the end you can see the rule is created. I also have a duplicate name check in the script to prevent those error messages from cropping up.

Scripts
Test Lab Script Version 1.2
XML Creation Script

**rename files with a .ps1 extension.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s