MVP - Most Valuable Professional
rss

Just can't get enough of IT

This blog is about mostly anything in IT. But the primary focuses are Microsoft Technologies like Exchange, Office 365, Azure and Cloud Security.
Last updated: 20174-02-22

Description

This is the Exchange 2013+ version of the Exchange 2010 version found here.

This script removes orphaned mobile device partnerships from Exchange Server 2013+ user mailboxes. Run the script as a scheduled task to maintain your Exchange Server environment properly.

This script utilizes a settings.xml file to configure

  • SMTP settings for email reports
  • Threshold values for mobile devices
    • Default number of allowed devices per user: 5
    • Defaul number of aged devices to be removed: 1
    • Default threshold for unsynchronized devices: 150 days

Settings.xml (default)

<?xml version="1.0"?>
<Settings>
  <EmailSettings>	
    <SMTPServer>smtp.mcsmemail.de</SMTPServer>
    <SMTPPort>25</SMTPPort>
    <MailFrom>postmaster@mcsmemail.de</MailFrom>
    <MailTo>postmaster@mcsmemail.de</MailTo>
  </EmailSettings>
  <OtherSettings>
	<!-- MobileDeviceLimit defines the overall threshold of mobile devices for a single user to synchronize. Default is 5. -->
	<MobileDeviceLimit>5</MobileDeviceLimit>

	<!-- AgedDeviceLimit defines the threshold of allowed aged devices for a single user to be removed. Default is 1. -->
	<AgedDeviceLimit>1</AgedDeviceLimit>

	<!-- Time threshold in days to identify old mobile devices, Be default devices not synchronized for 150 days will be removed -->
    <LastSyncDays>150</LastSyncDays>
  </OtherSettings>
</Settings>

Steps being executed by the script:

  1. Fetch all user mailboxes hosted on Exchange Server 2013 or later
  2. Iterate through each user mailbox and determine the number of mobile devices and the number of devices which have not synchronized since 150 days
  3. Remove mobile device registration, if a user has more than the allowed number of devices in total and a minimum of 1 device that has not synced within 150 days and the -ReportOnly switch has not been used
  4. Optionally, write a CSV export of identified mobile devices to disk | Use -ReportOnly switch
  5. Optionally, send an email report | Use -SendMail switch

Examples

# EXAMPLE 1
# Remove old mobile device partnerships without sending a report email

 .\Remove-MobileDevicePartnership.ps1 

# EXAMPLE
# Remove old mobile device partnerships and send a report email

# .\Remove-MobileDevicePartnership.ps1 -SendMail

Version History

  • 1.0, Initial community release
  • 1.1, ReportOnly switch added

Links

Follow

 

 

Read More »

When you've enabled the Exchange scripting agent extension agents, it is required to copy the configuration file to each Exchange server. Paul Cunningham's script helps you to achive this goal pretty easily.

But if you have installed the Exchange 2013 Management Tools on additonal servers, these servers are not fetched using the Get-ExchangeServer cmdlet. But when you install a Cumulative Update the existence of the extension agent config file is checked. And this even on a server having only the Exchange Management Tools installed.

Therefore the following PowerShell code provides an easy and simple way to add additonal server having the Exchange 2013+ Management Tools installed (aka Admin Servers, Monitoring Servers, Job Servers, etc.). The script uses a filter to select Exchange 2013 servers only, as the script has been extended in an environment having still active Exchange 2007 servers.

The following PowerShell snippet displays only the changes, which need to be added to Paul's original script starting row 68.

# Original PowerShell code
# $exchangeservers = Get-ExchangeServer

# Select all Exchange 2013 servers only, restrict properties to Name and AdminDisplayName
$exchangeservers = Get-ExchangeServer | ?{$_.AdminDisplayVersion -like "Version 15.0*"} | Select Name, AdminDisplayVersion

# Add additional servers as needed

$manualServers = @()
# Copy and modify as needed
$manualServers += (New-Object PSObject -Property @{Name="EXSRV2010";AdminDisplayVersion="Version 14"})
$manualServers += (New-Object PSObject -Property @{Name="EXSRV2013-01";AdminDisplayVersion="Version 15"})
$manualServers += (New-Object PSObject -Property @{Name="EXSRV2013-02";AdminDisplayVersion="Version 15"})

# Combine arrays
$exchangeservers = $exchangeservers + $manualServers

# End Modification

$report = @()

[string]$date = Get-Date -F yyyyMMdd-HHmmss

Enjoy extending the Exchange PowerShell cmdlets.

Links

Questions? Just leave a comment.

Read More »

Description

This script helps you to monitor message flow in a NoSpamProxy environment using a PRTG custom PowerShell sensor.

This custom sensor contains the following five channels:

  • In/Out Success
    Total of inbound/outbound successfully delivered messages over the last X minutes
  • Inbound Success
    Number of inbound successfully delivered messages over the last X minutes
  • Outbound Success
    Number of outbound successfully delivered messages over the last X minutes
  • Inbound PermanentlyBlocked
    Number of inbound blocked messages over the last X minutes
  • Outbound DeliveryPending
    Number of outbound messages with pending delivery over the last X minutes

The default interval is five minutes. But you might want to change the interval as needed for your environment.

These channels can easily be modified and additional channels can be added as well.

NoSpamProxy is a powerful anti-spam gateway solution providing additonal functionality like centralized S/MIME and PGP encryption for on-premises and Exchange Online deployments.

PRTG is a industry standard system monitoring solution.

Examples

The script itself does not take any additional attributes and is called by PRTG probe.

To verify your setup, you easily execute the PowerShell script. It returns a Xml result.

PS C:\Scripts> .\Get-NoSpamProxyPrtgData.ps1
<prtg>
  <result>
    <channel>In/Out Success</channel>
    <value>0</value>
    <unit>Count</unit>
  </result>
  <result>
    <channel>Inbound Success</channel>
    <value>0</value>
    <unit>Count</unit>
  </result>
  <result>
    <channel>Outbound Success</channel>
    <value>0</value>
    <unit>Count</unit>
  </result>
  <result>
    <channel>Inbound PermanentlyBlocked</channel>
    <value>0</value>
    <unit>Count</unit>
  </result>
  <result>
    <channel>Inbound DeliveryPending</channel>
    <value>0</value>
    <unit>Count</unit>
    <limitmaxwarning>10</limitmaxwarning>
    <limitmode>1</limitmode>
  </result>
</prtg>

The PRTG channel configuration

PRTG channel using a custom sensor

The following screenshot shows PRTG example graphs.

NoSpamProxy monitored using a PRTG custom sensor

Notes

The custom PowerShell script must be saved to the following location of the PRTG probe:

[INSTALLPATH]\PRTG Network Monitor\Custom Sensors\EXEXML

Ensure to have the PowerShell execution policy set correctly. Otherwise the PRTG service won't be able to execute the PowerShell script.

Ensure that the service account used by the PRTG probe has access to the script and is a member of the NoSpamProxy Monitoring Administrators security group.

Version History

  • 1.0, Initial community release

Links

Additional Credits

Additional credits go to Brian Addicks, https://github.com/brianaddicks/prtgshell

Follow

Read More »

Description

This script fetches the disk volume (Win32_Volume) information via WMI and shows the results in the PowerShell command line window. Optionally, you can have the report sent as an Html email to a recipient of your choice.

The switch -AllExchangeServer simplifies gathering the disk volume information across all Exchange servers in your environment.

The following screenshot shows the command line output when using

.\Get-Diskpace.ps1 -ComputerName MYSERVER

Get-Diskspace command line output

The following screenshot shows an example of the html email output when using

.\Get-Diskpace.ps1 -ComputerName MYSERVER -SendMail -MailFrom postmaster@sedna-inc.com -MailTo exchangeadmin@sedna-inc.com -MailServer mail.sedna-inc.com

Get-Diskspace email example

Examples

# EXAMPLE 1
# Get disk information from computer MYSERVER in MB

Get-Diskpace.ps1 -ComputerName MYSERVER -Unit MB

# EXAMPLE 2
# Get disk information from all Exchange servers and send html email

Get-Diskpace.ps1 -AllExchangeServer -SendMail -MailFrom postmaster@sedna-inc.com -MailTo exchangeadmin@sedna-inc.com -MailServer mail.sedna-inc.com

Version History

  • 1.0, Initial community release
  • 1.1,  Email reports added
  • 1.11, Send email issue fixed
  • 1.12, PowerShell hygiene applied

Links

Follow

Additional Note

This Powershell script has been optimized using the ISESteroids™ add-on. Learn more about ISESteroids™ here.

Read More »

There are three different ways to configure new Exchange user mailboxes after these have been created.

  • The classic manual administrator approach (keeps your job safe, but is it fun?)
  • The workflow based approach using some kind of IDM workflow solution (keeps the IDM consultant's job safe)
  • The scripting agent approach by extending the Exchange cmdlets (keeps your job safe, is fun, keeps you in control and get's you more free time)

The Exchange cmdlet extension is controlled by a scripting agent configuration file and a organizational setting to enable/disable the scripting agent.

Preparation

A scripting agent configuration file sample (ScriptingAgentConfig.xml.sample) is located in

  • $exinstall\Bin\CmdletExtensionAgents

The sample needs to be renamed to ScriptingAgentConfig.xml, to be picked up the PowerShell engine.

As always, a slight reminder: Test any modification in a test environment first, before you use the extension in a production environment.

After succesfull testing and deployment, you need to enable the scripting agent using

Enable-CmdletExtensionAgent "Scripting Agent"

Example

Even thought that you can extend mostly any Exchange cmdlet, this example covers the extension of the New-Mailbox and Enable-Mailbox cmdlets in a multi domain and multi AD site environment.

This extension disables the following CAS mailbox settings, after a new mailbox has been created:

  • ActiveSync
  • IMAP4
  • POP3
  • MAPI over HTTP

What does the example do?

  • Extension is named MailboxProvisioning and handles the cmdlets New-Mailbox and Enable-Mailbox
  • Is called on trigger OnComplete
    • The extension code is called after the original cmdlet has finished
  • Code is executed, if the original cmdlet was successfully finished
  • Code is executed, if the mailbox created is not an archive
  • A slight delay of 10 seconds ensures that domain controller activities have been finished
    • Can be adjusted or even removed, depending on your environment
  • Try to fetch at least on of three user parameters to identify the user mailbox
    • Checking for Identity, Name, Alias
  • Fetch a list of all domain controllers in the current AD site where the Exchange server is located
  • Iterate through the list of domain controllers and try to fetch the new CAS mailbox
    • If fetched, remember the domain controller's FQDN
  • Change the CAS mailbox settings as needed and use the remembered domain controller as DC to write to

 

<?xml version="1.0" encoding="utf-8" ?>
  <Configuration version="1.0">
	<Feature Name="MailboxProvisioning" Cmdlets="New-Mailbox,Enable-Mailbox">
		<ApiCall Name="OnComplete">
			If ($succeeded) {
				if (!($provisioningHandler.UserSpecifiedParameters.Archive -eq $true)) {
					# delay execution for 10 seconds, adjust as needed
					Start-Sleep -s 10
					
					# validate parameters to use a not null parameter
					if ($provisioningHandler.UserSpecifiedParameters["Identity"] -ne $null) {
						$user = $provisioningHandler.UserSpecifiedParameters["Identity"].ToString()
					}
					elseif ($provisioningHandler.UserSpecifiedParameters["Name"] -ne $null) {
						$user = $provisioningHandler.UserSpecifiedParameters["Name"].ToString()
					}
					else {
						$user = $provisioningHandler.UserSpecifiedParameters["Alias"].ToString()
					}
						
					# view entire forest in a multi domain environment
					Set-AdServerSettings -ViewEntireForest:$true
					
					# fetch domain controllers in AD site}
					$server = Get-ExchangeServer $env:computername
					$DCs = Get-DomainController | ?{$_.adsite -eq $server.site}
					
					$CasMailbox = $null
					foreach($d in $DCs) {
						while($CasMailbox -eq $null) {
							# find a valid domain controller having the updated user object
							$CasMailbox = Get-CASMailbox $user -DomainController $d.dnshostname -ErrorAction SilentlyContinue
							# fetch DCs FQDN
							$WriteDC = $d.DnsHostName
							break
						}
					}
					
					try {
						# set CAS features as needed
						Set-CasMailbox $user -ActiveSyncEnabled:$false -ImapEnabled:$false -PopEnabled:$false -MapiHttpEnabled:$false -DomainController $WriteDC -ErrorAction SilentlyContinue
					}
					catch {}
				}
			}
		</ApiCall>
	</Feature>
</Configuration>

Notes

After adding the PowerShell code to the ScriptingAgentConfig.xml file, the file needs to be distributed across all Exchange servers. For distribution of the scripting agent configuration file I personally recommend Paul Cunningham's PowerShell script.

Be aware of the fact, that the scripting agent Xml is being validated using a strict schema validation. The scripting agent Xml is case sensitive, as noted here.

Links

Read More »