Quantcast
Channel: Exchange – Microsoft Technologies Blog
Viewing all 214 articles
Browse latest View live

Import Legacy exchange DN from CSV

$
0
0

Hi Readers,

There can be a situation where you are migrating from another exchange organization & you have to import legacy exchange DN.

This is required so that users does’nt get delivery failure when they reply to old messages or send to cached outlook contacts.

Just extract the script on any server that has exchange management tools installed.

the script will get extracted as below (you can find the sample inside it)

execute the script as below

output will be logged in logs folder.

extract the script from below location

http://gallery.technet.microsoft.com/scriptcenter/Import-Legacy-exchange-DN-e8e8052d

Script code :-

############################################################################################### 
##                                                                                             
##           Author: Vikas Sukhija                                                         
##           Date: 07-10-2012                                                       
##           Description:- This script is used for Migration of mailboxes                      
##           (Importing Legacy DN)                                                              
################################################################################################ 

# Add exchange Shell 

If ((Get-PSSnapin | where {$_.Name -match "Exchange.Management"}) -eq $null) 
{ 
    Add-PSSnapin Microsoft.Exchange.Management.PowerShell.Admin 
} 

# Import CSV file that is populated with user id (email address) & Legacy DN 

$now=Get-Date -format "dd-MMM-yyyy HH:mm" 

# replace : by - 

$now = $now.ToString().Replace(“:”, “-”) 

$data = import-csv $args[0] 

# Loop thru the data from CSV 

foreach ($i in $data) 

{ 

$Log1 = ".\logs\" + "legacyDN" + $now + ".log" 
$lDN = "X500:" 
$legacyDN = $lDN + $i.legacyExchangeDN 
$mailbox = get-mailbox $i.userid 
$mailbox.emailaddresses+=$legacyDN 
$mailbox | set-mailbox 
Write-host "$legacyDN has been added to $mailbox" 
add-content $Log1 "$legacyDN has been added to $mailbox" 

} 

####################################################################################


Regards
Sukhija Vikas


Send HTML Email and attachment Powershell

$
0
0

Hi Readers,

Sharing a sweet code to send HTML email via powershell.

Attached is a very simple method for sending the html email.

zip file contains script & html file (you can edit in MS word according to your requirement).

Most of the parameters that  are required to send email are used, you can use what ever you require.

Extract the zip file & Check the sample.

If you search on Internet you will find complex method in which scripters have used html code inside the script.

I have used a very simple method by creating the word file & saving it as html.

Script also sends attachment, if you want to send attachment then change the path accordingly in variables. (# Hash the things that you don’t require in your script email)

############################################################################### 

###########Define Variables######## 

$fromaddress = "donotreply@labtest.com" 
$toaddress = "Aishwarya.Rawat@labtest.com" 
$bccaddress = "Vikas.sukhija@labtest.com" 
$CCaddress = "Mahesh.Sharma@labtest.com" 
$Subject = "ACtion Required" 
$body = get-content .\content.htm 
$attachment = "C:\sendemail\test.txt" 
$smtpserver = "smtp.labtest.com" 

#################################### 

$message = new-object System.Net.Mail.MailMessage 
$message.From = $fromaddress 
$message.To.Add($toaddress) 
$message.CC.Add($CCaddress) 
$message.Bcc.Add($bccaddress) 
$message.IsBodyHtml = $True 
$message.Subject = $Subject 
$attach = new-object Net.Mail.Attachment($attachment) 
$message.Attachments.Add($attach) 
$message.body = $body 
$smtp = new-object Net.Mail.SmtpClient($smtpserver) 
$smtp.Send($message) 

#################################################################################

Script download Location:-

http://gallery.technet.microsoft.com/scriptcenter/Send-HTML-Email-Powershell-6653235c

Regards
SUkhija Vikas

Exchange Health Status Check

$
0
0

Hi Readers,

Today I am sharing a amazing script that I & my Colleague has written to reduce Team’s work for daily checking list.

Also We utilize it after maintenance activities.

This script is compatible with exchange 2007 server & do the following tasks.

  • Check CCR status & which are active nodes.
  • Storage Group Status (If it is healthy or not) -Copy status
  • Mail flow tests from all CCR’s
  • Mail queue on all Transport servers

This report is sent in email in the following format:-

Download & extract the zip file :- http://gallery.technet.microsoft.com/scriptcenter/Exchange-Health-Status-86c3a8a6

Define the following variables in ExchangeDailyCheckList.ps1

$reportpath = “\\networkshare\folder\CMSReport.htm”

$smtphost = “smtp server”

$from = “ExchangeStatus@labtest.com”

$to = “Vikas.sukhija@labtest.com”

Define the variable in Get-CMS-Status.ps1 inside CMSScripts folder

$report = “\\networkshare\folder\CMSReport.htm”

Note:-  Network share should be same for both scripts for the solution to work.

Now just run the batch file for the magic to begin, enter the user id & password (Administrator id)

Assumption is that you have  rights on all exchange servers in your enviornment.

What does it do :-

It detects the exchange CCR servers & active nodes , copies get-cms-status script to temp folder of active nodes, run the script remotely via psexec i.e inside the folder you downloaded, reports the output in cmsreport.htm at networkpath. (it will only copy the file first time & then for every other time it only checks if it doesnt exist then copies it to c:\temp of active node.

First time script will thro red error because report cmsreport.htm doesnt exists.

Please rate it if it worked for you.

Below is one of the script that has been used to accomplish the Full solution.

Full solution can be extracted from:-

http://gallery.technet.microsoft.com/scriptcenter/Exchange-Health-Status-86c3a8a6

############################################################################# 
#       Author: Mahesh Sharma 
#       Reviewer: Vikas SUkhija       
#       Date: 06/10/2013 
#    Modified:06/19/2013 - made it to run from any path 
#       Description: ExChange Health Status 
############################################################################# 

########################### Add Exchange Shell############################## 

If ((Get-PSSnapin | where {$_.Name -match "Exchange.Management"}) -eq $null) 
{ 
    Add-PSSnapin Microsoft.Exchange.Management.PowerShell.Admin 
} 

###########################Define Variables################################## 

$reportpath = "\\networkshare\folder\CMSReport.htm"  
$smtphost = "smtp server"  
$from = "ExchangeStatus@labtest.com"  
$to = "Vikas.sukhija@labtest.com" 

###############################HTml Report Content############################ 
$report = $reportpath 

Clear-Content $report  
Add-Content $report "<html>"  
Add-Content $report "<head>"  
Add-Content $report "<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>"  
Add-Content $report '<title>Exchange Status Report</title>'  
add-content $report '<STYLE TYPE="text/css">'  
add-content $report  "<!--"  
add-content $report  "td {"  
add-content $report  "font-family: Tahoma;"  
add-content $report  "font-size: 11px;"  
add-content $report  "border-top: 1px solid #999999;"  
add-content $report  "border-right: 1px solid #999999;"  
add-content $report  "border-bottom: 1px solid #999999;"  
add-content $report  "border-left: 1px solid #999999;"  
add-content $report  "padding-top: 0px;"  
add-content $report  "padding-right: 0px;"  
add-content $report  "padding-bottom: 0px;"  
add-content $report  "padding-left: 0px;"  
add-content $report  "}"  
add-content $report  "body {"  
add-content $report  "margin-left: 5px;"  
add-content $report  "margin-top: 5px;"  
add-content $report  "margin-right: 0px;"  
add-content $report  "margin-bottom: 10px;"  
add-content $report  ""  
add-content $report  "table {"  
add-content $report  "border: thin solid #000000;"  
add-content $report  "}"  
add-content $report  "-->"  
add-content $report  "</style>"  
Add-Content $report "</head>"  
Add-Content $report "<body>"  
add-content $report  "<table width='100%'>"  
add-content $report  "<tr bgcolor='Lavender'>"  
add-content $report  "<td colspan='7' height='25' align='center'>"  
add-content $report  "<font face='tahoma' color='#003399' size='4'><strong>CMS Status Report</strong></font>"  
add-content $report  "</td>"  
add-content $report  "</tr>"  
add-content $report  "</table>"  

add-content $report  "<table width='100%'>"  
Add-Content $report  "<tr bgcolor='IndianRed'>"  
Add-Content $report  "<td width='10%' align='center'><B>Identity</B></td>"  
Add-Content $report  "<td width='5%' align='center'><B>State</B></td>"  
Add-Content $report  "<td width='20%' align='center'><B>OperationalMachines</B></td>"  
Add-Content $report  "<td width='15%' align='center'><B>FailedResources</B></td>"  
Add-Content $report  "<td width='15%' align='center'><B>FailedReplicationHostNames</B></td>"  

Add-Content $report "</tr>"  

##############################Get ALL CCR's################################## 

$inputCMS = Get-ExchangeServer | where {$_.IsMemberOfCluster -eq "Yes"} | select name 

######################### Create UI Button for userid & Password############## 

[void][System.Reflection.Assembly]::LoadWithPartialName(  
    "System.Windows.Forms")  
[void][System.Reflection.Assembly]::LoadWithPartialName(  
    "Microsoft.VisualBasic")  

$Form = New-Object System.Windows.Forms.Form  
$Button = New-Object System.Windows.Forms.Button  
$TextBox1 = New-Object System.Windows.Forms.TextBox  
$TextBox2 = New-Object System.Windows.Forms.TextBox  
$Label1 = New-Object System.Windows.Forms.Label  
$Label2 = New-Object System.Windows.Forms.Label  

$Form.Text = "Enter Credentials"  
$Form.StartPosition =   
    [System.Windows.Forms.FormStartPosition]::CenterScreen  

$Label1.Text = "Domain\User Name"  
$Label1.Top = 50  
$Label1.Left = 25  

$Label2.Text = "Password"  
$Label2.Top = 90  
$Label2.Left = 25  

$TextBox1.Text = ""  
$TextBox1.Top = 50  
$TextBox1.Left = 150  

$Textbox2.Passwordchar = "*" 
$TextBox2.Text = ""  
$TextBox2.Top = 90  
$TextBox2.Left = 150  

$Button.Text = "Run!!"  
$Button.Top = 130  
$Button.Left = 115  
$Button.Width = 70  

$Button_Click =   
{  
        $User = $TextBox1.Text 
    $Password = $TextBox2.Text 
      $form.close()   
}  

$Form.Controls.Add($Label2)  
$Form.Controls.Add($Label1)  
$Form.Controls.Add($Button)  
$Form.Controls.Add($TextBox1)  
$Form.Controls.Add($TextBox2)  
$Button.Add_Click($Button_Click)  

$Form.ShowDialog() 

#####################################Active Cluster Nodes############################################### 

foreach($node in $inputCMS) { 

$anode = $node.name 

$anode = Get-WmiObject win32_ComputerSystem -ComputerName $anode 

$actnode = $anode.name 

$actnode 

$tempfolder = Test-Path \\$actnode\c$\temp 

Write-host "$actnode tempfolder status $tempfolder" 

if($tempfolder -like "False") { 

Write-host "Temp folder doesnt exist on $actnode, creating Temp folder" 

New-Item -ItemType directory -Path \\$actnode\c$\temp 

} 

else { 

Write-host "temp folder exists on $actnode" 

} 

$scstatus = Test-Path \\$actnode\c$\temp\Get-CMS-Status.ps1 

if($scstatus -like "False") { 

Write-host "Get-CMS-Status script doesnt exist on $actnode, copying it to Temp folder" 

Copy-Item .\CMSScripts\Get-CMS-Status.ps1 \\$actnode\c$\temp 

} 

else { 

Write-host "Get-CMS-Status scriptexists on $actnode" 

} 

.\psexec.exe \\$actnode -u $user -p $password   cmd /c "echo . | powershell c:\temp\get-cms-status.ps1" 

} 

add-content $report  "</table>"  

################################################################################################################ 
################################################################################################################ 

$CMSList = $inputCMS 
$TestCMSMailFlow =  $inputCMS 

$report = $reportpath 

Add-Content $report "<html>"  
Add-Content $report "<head>"  
Add-Content $report "<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>"  
Add-Content $report '<title>Exchange Status Report</title>'  
add-content $report '<STYLE TYPE="text/css">'  
add-content $report  "<!--"  
add-content $report  "td {"  
add-content $report  "font-family: Tahoma;"  
add-content $report  "font-size: 11px;"  
add-content $report  "border-top: 1px solid #999999;"  
add-content $report  "border-right: 1px solid #999999;"  
add-content $report  "border-bottom: 1px solid #999999;"  
add-content $report  "border-left: 1px solid #999999;"  
add-content $report  "padding-top: 0px;"  
add-content $report  "padding-right: 0px;"  
add-content $report  "padding-bottom: 0px;"  
add-content $report  "padding-left: 0px;"  
add-content $report  "}"  
add-content $report  "body {"  
add-content $report  "margin-left: 5px;"  
add-content $report  "margin-top: 5px;"  
add-content $report  "margin-right: 0px;"  
add-content $report  "margin-bottom: 10px;"  
add-content $report  ""  
add-content $report  "table {"  
add-content $report  "border: thin solid #000000;"  
add-content $report  "}"  
add-content $report  "-->"  
add-content $report  "</style>"  
Add-Content $report "</head>"  
Add-Content $report "<body>"  
add-content $report  "<table width='100%'>"  
add-content $report  "<tr bgcolor='Lavender'>"  
add-content $report  "<td colspan='7' height='25' align='center'>"  
add-content $report  "<font face='tahoma' color='#003399' size='4'><strong>Storage Group Status Report</strong></font>"  
add-content $report  "</td>"  
add-content $report  "</tr>"  
add-content $report  "</table>"  

add-content $report  "<table width='100%'>"  
Add-Content $report "<tr bgcolor='IndianRed'>"  
Add-Content $report  "<td width='25%' align='center'><B>Identity</B></td>"  
Add-Content $report "<td width='25%' align='center'><B>Copy Status</B></td>"  
Add-Content $report  "<td width='25%' align='center'><B>Copy Queue Lenght</B></td>"  
Add-Content $report  "<td width='25%' align='center'><B>Reply Queue Lenght</B></td>"  
Add-Content $report "</tr>"  

########################################################################################################## 
############################################## SG Copy Status ############################################ 

foreach ($CMSName in $CMSlist)  
{  

$CMSName = $CMSName.Name 

        $FullStatus = Get-StorageGroupCopyStatus -Identity $CMSName\* 

        Foreach ($status in $Fullstatus) 
        { 

            if ($status.SummaryCopyStatus -eq "Healthy") 
            { 
            $Identity = $status.identity 
            $Copystatus =  $status.SummaryCopyStatus  
            $copylength =  $status.copyqueuelength 
            $replylength = $status.ReplayQueueLength 
            Add-Content $report "<tr>"  
            Add-Content $report "<td bgcolor= 'GainsBoro' align=center>  <B> $Identity</B></td>"  
                 Add-Content $report "<td bgcolor= 'Aquamarine' align=center>  <B>$copystatus</B></td>"  
            Add-Content $report "<td bgcolor= 'GainsBoro' align=center>  <B>$copylength</B></td>"  
            Add-Content $report "<td bgcolor= 'GainsBoro' align=center>  <B>$replylength</B></td>"  
            Add-Content $report "</tr>"  
            } 

            else  
            { 
            $Identity = $status.identity 
            $Copystatus =  $status.SummaryCopyStatus  
            $copylength =  $status.copyqueuelength 
            $replylength = $status.ReplayQueueLength 
            Add-Content $report "<tr>"  
            Add-Content $report "<td bgcolor= 'GainsBoro' align=center>  <B> $Identity</B></td>"  
                 Add-Content $report "<td bgcolor= 'Red' align=center>  <B>$copystatus</B></td>"  
            Add-Content $report "<td bgcolor= 'GainsBoro' align=center>  <B>$copylength</B></td>"  
            Add-Content $report "<td bgcolor= 'GainsBoro' align=center>  <B>$replylength</B></td>"  
            Add-Content $report "</tr>"  
            } 

        } 

} 

################################################################################################################## 
############################################## Test mail Flow For CMS ############################################ 

add-content $report  "<tr bgcolor='Lavender'>"  
add-content $report  "<td colspan='7' height='25' align='center'>"  
add-content $report  "<font face='tahoma' color='#003399' size='4'><strong>Mail Flow Test Report</strong></font>"  
add-content $report  "</td>"  
add-content $report  "</tr>" 

add-content $report  "</tr>"  
add-content $report  "</table>"  
add-content $report  "<table width='100%'>"  
Add-Content $report "<tr bgcolor='IndianRed'>" 
Add-Content $report  "<td width='25%' align='center'><B>Result</B></td>"  
Add-Content $report "<td width='25%' align='center'><B>Message Latency Time</B></td>"  
Add-Content $report  "<td width='25%' align='center'><B>IsRemoteTest</B></td>"  
Add-Content $report "</tr>"  

Foreach ($CMS in $TestCMSMailFlow) 
{ 

$flow = Test-MailFlow -Identity $CMS.Name 

$result = $flow.TestMailflowResult 
$time = $Flow.MessageLatencyTime 
$remote =  $Flow.IsRemoteTest 
Add-Content $report "<tr>"  
Add-Content $report "<td bgcolor= 'GainsBoro' align=center>  <B> $result</B></td>"  
Add-Content $report "<td bgcolor= 'GainsBoro' align=center>  <B>$time</B></td>"  
Add-Content $report "<td bgcolor= 'GainsBoro' align=center>  <B>$remote</B></td>"  

Add-Content $report "</tr>" 

} 

##################################################################################################################### 
############################################## Get Queue For HUB Servers ############################################ 

add-content $report  "<tr bgcolor='Lavender'>"  
add-content $report  "<td colspan='7' height='25' align='center'>"  
add-content $report  "<font face='tahoma' color='#003399' size='4'><strong>Mail Queue Status</strong></font>"  
add-content $report  "</td>"  
add-content $report  "</tr>" 

add-content $report  "</tr>"  
add-content $report  "</table>"  
add-content $report  "<table width='100%'>"  
Add-Content $report "<tr bgcolor='IndianRed'>" 
Add-Content $report  "<td width='25%' align='center'><B>Identity</B></td>"  
Add-Content $report "<td width='25%' align='center'><B>Delivery Type</B></td>"  
Add-Content $report  "<td width='25%' align='center'><B>Status</B></td>"  
Add-Content $report "<td width='25%' align='center'><B>Message Count</B></td>"  
Add-Content $report  "<td width='25%' align='center'><B>Next Hop Domain</B></td>" 
Add-Content $report "</tr>"  

Foreach ($Queue in $GetHub = Get-TransportServer | get-Queue) 
{ 

$Identity = $Queue.Identity 
$DeliveryType = $Queue.DeliveryType 
$Status = $Queue.Status 
$MSgCount =  $Queue.Messagecount 
$NextHopDomain = $Queue.NextHopDomain 

Add-Content $report "<tr>"  
Add-Content $report "<td bgcolor= 'GainsBoro' align=center>  <B> $Identity</B></td>"  
Add-Content $report "<td bgcolor= 'GainsBoro' align=center>  <B>$DeliveryType</B></td>"  
Add-Content $report "<td bgcolor= 'GainsBoro' align=center>  <B>$Status</B></td>"  
Add-Content $report "<td bgcolor= 'GainsBoro' align=center>  <B>$MSgCount</B></td>"  
Add-Content $report "<td bgcolor= 'GainsBoro' align=center>  <B>$NextHopDomain</B></td>"  

Add-Content $report "</tr>" 

} 

########################################################################################################################### 
######################################################### Send Mail ####################################################### 

Add-content $report  "</table>"  
Add-Content $report "</body>"  
Add-Content $report "</html>" 

$subject = "Exchange Status Check Report"  
$body = Get-Content $reportpath 
$smtp= New-Object System.Net.Mail.SmtpClient $smtphost  
$msg = New-Object System.Net.Mail.MailMessage $from, $to, $subject, $body  
$msg.isBodyhtml = $true  
$smtp.send($msg)  

###################################################Exchange Test Complete##################################################

Regards

Sukhija Vikas


Exchange Active sync Message Size Limit

$
0
0

Hi Readers,

Sharing a small issue that has occurred in our environment as no admin have thought about it previously.

Message size limits that are set for our environment is 25 MB but some of the sales users  Complained that

they are not able to attach document to message that is more then 10 MB in size. We have tested this & found the same thing.

Issue was that in the web.config file (C:\Program Files\Microsoft\Exchange Server\ClientAccess\Sync)

<httpRuntime maxRequestLength=”10240″/> was set to 10 MB.

We have changed it to 25600(25 MB) for resolving the issue.

webconfig

Regards

Sukhija Vikas


Update Group Members from CSV

$
0
0

Hi All,

Today I am sharing my old script that I had used for updating the group members from CSV file.

I was performing the same activity today so thought of sharing it.

You just have to Prepare CSV as below:-

 

after that just define group name inside the script.

#############################

$grp =

##############################

This script requires quest management shell.

http://www.quest.com/powershell/activeroles-server.aspx

Execute script as below:

below is the link to the zip file along with script & example csv

http://gallery.technet.microsoft.com/scriptcenter/Update-Group-Members-from-46e27c78

Script Code:-

########################################################################################### 
##                                                                                             
##           Author: Vikas Sukhija                                                         
##           Date: 26-11-2012                                                        
##           Description:- If user is not a member of group this script add it after reading    
##           from CSV                                                                                
########################################################################################### 
#Add Quest Shell... 

If ((Get-PSSnapin | where {$_.Name -match "Quest.ActiveRoles"}) -eq $null) 
{ 
    Add-PSSnapin Quest.ActiveRoles.ADManagement 
} 

#####define Group######## 

$grp="Group Name" 

######################### 

# import csv file 

$data = import-csv $args[0] 

$Can = “CN=$grp” 

Write-host $Can 

#Check if usr belogs to group in csv 

foreach ($i in $data) 

{ 

$user=get-qaduser $i.userid 

  if (($user.memberof -like “$Can,*”)) 

  { 

  write-host “$user is a member & will not be added to $grp group” 

  } 

  else 

  { 

  write-host “$user is not a member & will be added to $grp group” 

  add-qadgroupmember $grp $user   

  } 

} 
########################################################################################

 

Regards

Sukhija Vikas

 


Users Missing from Exchange GAL

$
0
0

Hi All,

There has been situations where users are missing from Global Address List.

I myself  have faced this a few times now. In our environment it only happened when user was rehired.(re-enabled) –>(this happened rarely but when we researched a bit ,finding was –> user was re-enabled)

So thought of sharing the solution which is very simple but is not known to many.

just run the following command

Update-GlobalAddressList -identity “Default Global Address List”

Better to run this command during off-peak hours as for big enterprises it can take long time to finish.

There is one other situation Where user has different email address displayed in email tab(exchange console) & different in email tab of AD  console.

We first resolved that issue & than ran the above command to update the user in GAL.

Regards

Sukhija Vikas


Exchange ActiveSync – Report

$
0
0

Hi All,

This script I have used to extract activesync details from exchange 2007 server.

below are the details:-

Userid

DeviceType

DeviceID

DeviceUserAgent

FirstSyncTime

LastSuccessSync

Identity

DeviceModel

DeviceFriendlyName

DeviceOS

Extract the zip file & run the batch file.

http://gallery.technet.microsoft.com/scriptcenter/Exchange-ActiveSync-Report-92279541

here is the report:

PowerShell
############################################################################# 
#       Author: Vikas Sukhija 
#       Date: 07/31/2013 
#       Description: Extract the Active Sync stats 
############################################################################# 

# Add Exchange Shell... 

If ((Get-PSSnapin | where {$_.Name -match "Exchange.Management"}) -eq $null) 
{ 
    Add-PSSnapin Microsoft.Exchange.Management.PowerShell.Admin 
} 

#format Date 

$date = get-date -format d 
$date = $date.ToString().Replace(“/”, “-”) 

$output = ".\" + "ActivesyncReport_" + $date + "_.csv" 

#create a collection to hold results(dynamic array) 

$Collection = @() 
Get-CASMailbox -resultsize unlimited | where{$_.ActiveSyncEnabled -eq "True"} | foreach-object{ 
$user = get-user $_.name 
$devices = Get-ActiveSyncDeviceStatistics -Mailbox $_.Identity | select DeviceType,DeviceID,DeviceUserAgent,FirstSyncTime,LastSuccessSync, 
Identity,DeviceModel,DeviceFriendlyName,DeviceOS 
$devices | foreach-object { 

$coll = “” | select Userid,DeviceType,DeviceID,DeviceUserAgent,FirstSyncTime,LastSuccessSync, 
Identity,DeviceModel,DeviceFriendlyName,DeviceOS 

$coll.Userid = $user.name 
$coll.DeviceType = $_.DeviceType 
$coll.DeviceID = $_.DeviceID 
$coll.DeviceUserAgent = $_.DeviceUserAgent 
$coll.FirstSyncTime = $_.FirstSyncTime 
$coll.LastSuccessSync = $_.LastSuccessSync 
$coll.Identity = $_.Identity 
$coll.DeviceModel = $_.DeviceModel 
$coll.DeviceFriendlyName = $_.DeviceFriendlyName 
$coll.DeviceOS = $_.DeviceOS 

$Collection += $coll 

} 

} 

#export the collection to csv , change the path accordingly 

$Collection | export-csv $output 

#######################################################################################
 
 

Regards

Sukhija Vikas


Exchange 2013 What’s New

$
0
0

Hi Readers,

I was going thru Exchange 2013 recently , a bit late but as we say better late then never.

Microsoft has introduced some noticeable differences & we are back to days of exchange 2003 where we have frontend

& backend server concepts.(in some manner)

  • Hub Transport server is gone now, feature has been distributed between CAS/Mailbox servers.
  • ECP/Exchange management console is also gone, EAC is introduced (Exchange Admin center)
  • Public folder console is also gone, It is now part of EAC.
  • Edge Transport server is also not available currently but you can use 2007 & 2010 edge transport server with exchange 2013 as of now.
  • Microsoft Exchange search engine has been replace with Fast Search in Exchange 2013.
  • Built-in DLP , for protecting users from sending personal information such as credit cards.
  • Outlook Webapp has been greatly improved for phablet/tablets.
  • Offline outlook web access (Very Cool feature)

There are many more changes but these are the ones that I have found to be very different.

 

Regards

Sukhija Vikas



Exchange GAL error Analysis – Eventid 9325

$
0
0

Hi Readers,

If you want to troubleshoot:- Why some users are not available in Offilne address book & also have issues with

Default Global address List in exchange then this post might interests you.

First of all go to exchange management console & enable the diagnostics logging of Offline address book generator server

to medium.

When the offilne address book is generated you will see below kind of events in the eventvwr.

For analyzing it automatically I have written the power-shell solution(link to download is below) which will email you the entries that are having issues.

http://gallery.technet.microsoft.com/scriptcenter/Exchange-Address-Book-9f828d87

Please edit the script code & add relevant email addresses & smtp server (defined at end of .ps1 script)

edit batch file :- (enter the server name on which OAB is generated)

powershell .\eventAnalysis.ps1 Application server1 9325

 

Code:- 

######################################################################## 
#       Author: Vikas Sukhija 
#       Date: 10/10/2013 
#       Description: Analyze OAB errors 
######################################################################## 
#######################Define Parameters################################ 

Param ( 

$eventtype, 
$computerName, 
$eventid 

) 

#########################Add Exchange Shell############################# 

If ((Get-PSSnapin | where {$_.Name -match "Exchange.Management"}) -eq $null) 
{ 
    Add-PSSnapin Microsoft.Exchange.Management.PowerShell.Admin 
} 

#########################Add log files################################# 

$date = get-date -format d 
$date = $date.tostring() 
$date = $date.replace("/","-") 

$log1 = ".\logs\" + "EventAnalysis" + $date + "_.log" 
$log2 = ".\logs\" + "OABissues" + $date + "_.log" 

#######################get event id & split the message ################# 
$date = get-date  
$date = $date.ToShortDateString() 

$collevent = Get-EventLog -LogName $eventtype -ComputerName $computerName ` 
 -after $date | Where {$_.Eventid -eq $eventid} 

$time = get-date -format t 
$collevent.count 
$eventcount = $collevent.count 
Add-content $log1 "$time - Number of Events - $eventcount" 

foreach($event in $collevent)  { 

$evn = $event.Message 

$evn1 = $evn -replace "OALGen will skip user entry " 

$evn2 = $evn1 -replace "in address","=" 

$evn3 = $evn2.split("=") 

$evn4= $evn3[0].trim() 

$str = $evn4.substring(1,$evn4.length-2) 

write-host $str 
$time = get-date -format t 

add-content $log1 "$time - User mentioned in eventid - $str" 

$mailbox = get-mailbox  $str 

if($mailbox -ne $null) 

{ 
$time = get-date -format t 
$alias = $mailbox.alias 

Write-host "$time - $alias mailbox has issues with OAB" 
add-content $log1 "$time - $alias mailbox has issues with OAB" 
add-content $log2 "$alias mailbox has issues with OAB" 

} 
} 
#####################Send email to Messaging Team###################### 

$email = "Vikas.Sukhija@labtest.com" 
$from = "donotreply@labtest.com" 
$subject = "Oab Errors to be fixed" 
$body = get-content $log2 | out-string 
$smtpserver ="smtpserver" 

$message = new-object Net.Mail.MailMessage 
$smtp = new-object Net.Mail.SmtpClient($smtpserver) 

$message.From = $from 
$message.To.Add($email) 
$message.body = $body 
$message.subject = $subject 

$smtp.Send($message) 

########################################################################

Regards

Sukhija Vikas


Upgrade Distribution Group to Exchange 2010 Version

$
0
0

Hi Readers,

We have found that there are many DL’s in our organization that are still on old versions.

How to find DL versions:-

Log on to exchange 2010 management shell:

$collect = Get-DistributionGroup -ResultSize unlimited | select Name,samaccountname,exchangeversion

$collect | export-csv c:\exportDl.csv

Now you have two options to upgrade

1. upgrade all Lists at ones

Get-DistributionGroup -ResultSize unlimited | Set-DistributionGroup -forceupgrade

2.  Do some of the lists to see how it goes like I have done only 250 to first check

Set-DistributionGroup “DLName”  -forceupgrade

you can use notepad++ & you don’t have to write any script, follow below screen shot.

step1: replace ^(.+)$ with “\1” (Regular expression should be selected at below)

Capture1

step2:

Capture2

step3: After replace it will look like below

Capture3

Now enter these in Shell:)

Regards

SUkhija Vikas


Bulk Enable Unified Messaging Mailboxes

$
0
0

As I am getting my hands on Unified Messaging, I have started loving the feature & want to quickly deploy it for the users but we have a bit different setup, so script needs tweaking..

We already have a Lync that uses SIP & now we are integrating Avaya with UM (not Lync) that also uses SIP

Thats why While enabling users for UM ,Exchange throws below error:

To fix it, we just enable the user by selecting Automatically-generated SIP resource identifier:


After account is enabled we go inside the Email Tab & Edit the EUM section, replace the email address inside it with

+number@domain.com (SIP generated by Avaya)

So In the script We have to cover this error as well:), logic has been placed to modify EUM.

Download it from below link :

https://gallery.technet.microsoft.com/scriptcenter/Bulk-Enable-Unified-7ef82387

update the UMenable.csv file with users (id,extension) & change the variables:

$extn = “123” + $extension

$asip = “+123” + $extension + “@” + “domain.com”

$pin = “123456”

$umpol = “Global Dial Plan Default Policy”

$eum = “EUM:$asip;phone-context=Global Dial Plan.domain.com”

Now run the script & it will enable all users in the csv , will show on screen success/failures as well as logs it inside the logs folder.

You can modify the script as per your requirements, as there can be  differences in the setup.

########################################################### 
#        Author: Vikas Sukhija (http://msexchange.me)     
#        Date: 3/30/2016 
#        Reviewer: 
#        Desc: Bulk Enable UM Mailboxes 
########################################################### 
 
#--------For Log Files-------------- 
 
$date = get-date -format d  
$date = $date.ToString().Replace(“/”, “-”)  
$time = get-date -format t  
$time = $time.ToString().Replace(":""-")  
$time = $time.ToString().Replace(" """)  
 
$logs = ".\Logs" + "\" + "UMEnable" + $date + "_" + $time + "_.log" 
 
###################import modules########################### 
 
If ((Get-PSSnapin | where {$_.Name -match "Microsoft.Exchange.Management.PowerShell.E2010"}) -eq $null) 
{ 
    Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 
} 
 
Start-Transcript -Path $logs 
$error.clear() 
 
###########import CSV############################## 
 
$data = import-csv .\UMenable.csv 
 
foreach($i in $data) { 
 
$networkid = $i.Networkid 
$extension = $i.Extension 
 
$extn = "123" + $extension 
$asip = "+123" + $extension + "@" + "domain.com" 
$pin = "123456" 
$umpol = "Global Dial Plan Default Policy" 
$eum = "EUM:$asip;phone-context=Global Dial Plan.domain.com" 
 
$chkmbx = get-mailbox $networkid  -ea silentlycontinue 
 
if($chkmbx){ 
 
$alias = $chkmbx.Alias 
 
Enable-ummailbox -id $alias -Pin $pin -PinExpired $True -ummailboxpolicy $umpol -extensions $extn 
 
For($i = 1; $i -le "5"$i++){ sleep 1;Write-Progress -Activity "Enaling UM for $alias with ext $extn" -status "$i" -percentComplete ($i /10*100)} 
 
$chgeum = get-mailbox $alias 
$chgeum.EmailAddresses.Item(1) = $eum 
set-mailbox $alias -emailaddresses $chgeum.EmailAddresses 
 
if($error){ 
Write-host "Error on Enabling User $networkid for Unified messaging with $extn" -foregroundcolor yellow 
$error.clear()} 
else{ 
Write-host "Enabled User $networkid for Unified messaging with $extn" -foregroundcolor green} 
} 
 
else 
{  
Write-host "User $networkid doen'nt have a mailbox" -foregroundcolor Red 
 
} 
 
} 
stop-transcript 
######################################################    
Regards
Sukhija Vikas

Restricted Distribution Group access Excel Report

$
0
0

Sharing a script that have been recently written by one of my colleague & that has been reviewed & enhanced further by me.

There was a requirement to extract the Send To access List for a set of Distribution lists. DL Names should appear as sheet Names & Access list identities should show in the sheet as tabular format.

Here is the SAMPLE:

Download & extract the script from below link, update the Distribution Lists in Dls.txt

https://gallery.technet.microsoft.com/scriptcenter/Restricted-Distribution-f63de63f

Update the location to save the excel file

$FinalExcelLocation =”C:\Scripts\ManualScripts\RestrictionReportXL\restrictedgroupsreport.xlsx”

update the customattribute as per your environment , I have used 10 as per the environment in question for employeeid extraction.

Run the script & it will lauch the excel & start updating the results:)

It will also extract the members from the groups that are inserted in send to access.

 

Prerequisites: Exchange 2010 Management Shell & Quest Active Directory Shell

############################################################################ 
#        Author: Prabhat Tiwari 
#        Reviewer: Vikas Sukhija 
#        Date: 3/24/2016 
#        Modified: 3/28/2016 
#        Modified: 3/30/3016 
#        Update: Logic is updated to use DNs instead of display names 
#        Update: Include gorup members 
#        Description: Report of Send to Restrictions in Excel format/ 
#        Multiple seets 
############################################################################ 
 
#--------For Log Files-------------- 
 
$date = get-date -format d  
$date = $date.ToString().Replace(“/”, “-”)  
$time = get-date -format t  
$time = $time.ToString().Replace(":""-")  
$time = $time.ToString().Replace(" """)  
 
$logs = ".\Logs" + "\" + "Restricted_DL_Details" + $date + "_" + $time + "_.txt" 
 
###################import modules########################### 
 
If ((Get-PSSnapin | where {$_.Name -match "Microsoft.Exchange.Management.PowerShell.E2010"}) -eq $null) 
{ 
    Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 
} 
 
If ((Get-PSSnapin | where {$_.Name -match "Quest.ActiveRoles.ADManagement"}) -eq $null) 
{ 
    Add-PSSnapin Quest.ActiveRoles.ADManagement 
} 
 
 
Start-Transcript -Path $logs 
######################################################################### 
 
function truncate-string([string]$value, [int]$length) 
{ 
    if ($value.Length -gt $length) { $value.Substring(0, $length) } 
    else { $value } 
} 
 
$DLs = Get-Content ".\DLs.txt" 
$xl = New-Object -ComObject Excel.Application 
$FinalExcelLocation ="C:\Scripts\RestrictionReportXL\restrictedgroupsreport.xlsx" 
$wb=$xl.Workbooks.Add() 
$sh$wb.Worksheets.Item(1) 
$ws=$wb.ActiveSheet 
$xl.Visible=$true 
$cells=$ws.Cells 
$row=1 
$column=1 
$i=1 
 
foreach($DL in $DLs) 
{ 
        $SName = "Sheet" + $i 
                
        if($i -gt 3) 
        { 
        $sh = $wb.WorkSheets.Add() 
        $wc = $wb.Worksheets.Item($SName) 
        $wc.Activate() 
        $tdl = truncate-string $DL 31 
        $wc.Name= $tdl 
        } 
        Else 
        { 
        $wc = $wb.Worksheets.Item($i) 
        $wc.Activate() 
        $tdl = truncate-string $DL 31 
        $wc.Name= $tdl 
        } 
        $i++ 
        $row =1 
        $column=1 
 
        $wc.cells.Item($row,$column) = "Type" 
 
        $wc.cells.Item($row,$column+1) = "UserName" 
 
        $wc.cells.Item($row,$column+2) = "DisplayName" 
 
        $wc.cells.Item($row,$column+3) = "EmployeeID" 
 
        $wc.cells.Item($row,$column+4) = "EmailID" 
 
        Write-host "processing......$DL" -foregroundcolor green 
        $resusers= (Get-DistributionGroup -Identity $DL).AcceptMessagesOnlyFromSendersorMembers | %{$_.distinguishedname} 
         
foreach($resuser in $resusers) 
        { 
         
    $chkmbx = get-mailbox $resuser -ea silentlycontinue 
 
    if($chkmbx){ $resmbx = $chkmbx 
 
    $resmbxemail = $resmbx.PrimarySmtpAddress.Local + "@" + $resmbx.PrimarySmtpAddress.Domain 
         $wc.cells.Item($row+1,$column) = "Mailbox"     
         $wc.cells.Item($row+1,$column+1) = $resmbx.Name 
         $wc.cells.Item($row+1,$column+2) = $resmbx.DisplayName 
         $wc.cells.Item($row+1,$column+3) = $resmbx.Customattribute10 
         $wc.cells.Item($row+1,$column+4) = $resmbxemail 
     $row=$row +1} 
     
    $chkdl = get-distributiongroup $resuser -ea silentlycontinue 
     
    if($chkdl){ $resdl = $chkdl 
 
        $dlemail = $resdl.PrimarySmtpAddress.Local + "@" + $resdl.PrimarySmtpAddress.Domain 
                $wc.cells.Item($row+1,$column) = "DL" 
                $wc.cells.Item($row+1,$column+1) = $resdl.Name 
                $wc.cells.Item($row+1,$column+2) = $resdl.DisplayName 
                $wc.cells.Item($row+1,$column+4) = $dlemail 
                $row=$row +1 
 
    $qadmems = get-qadgroupmember -identity $resdl.samaccountname -indirect -sizelimit 0 | where{$_.type -eq "user"}     
     
    foreach($qadmem in $qadmems){ 
          
    $chkmbx1 = get-mailbox $qadmem.Name -ea silentlycontinue 
     
    if($chkmbx1){ $resmbx1 = $chkmbx1 
     $resmbxemail1 = $resmbx1.PrimarySmtpAddress.Local + "@" + $resmbx1.PrimarySmtpAddress.Domain 
         $wc.cells.Item($row+1,$column) = "Mailbox"     
         $wc.cells.Item($row+1,$column+1) = $resmbx1.Name 
         $wc.cells.Item($row+1,$column+2) = $resmbx1.DisplayName 
         $wc.cells.Item($row+1,$column+3) = $resmbx1.Customattribute10 
         $wc.cells.Item($row+1,$column+4) = $resmbxemail1 
     $row=$row +1} 
    } 
                 
      } 
 
} 
$wc.Columns.Item(1).columnWidth = 24 
$wc.Columns.Item(2).columnWidth = 24 
$wc.Columns.Item(3).columnWidth = 24 
$wc.Columns.Item(4).columnWidth = 24 
$wc.Columns.HorizontalAlignment = -4131 
$wc.rows.item(1).Font.Bold = $True 
 
$row =1 
$column=$column+1 
 
} 
 
$wb.saveas($FinalExcelLocation$xl.Workbooks.close() 
$xl.quit() 
 
 
Stop-Transcript 
######################################################################################

Regards

Sukhija Vikas

http://msexchange.me


Exchange 2010 Create and Apply Retention Policy

$
0
0

Today in this blog post, we will create Retention policy for Voice Mails in Exchange environment. As per our organization standards we don’t want to retain the Voice Emails beyond  30 days, therefore we will create a policy & will apply it to Unified Messaging mailboxes.

Note: please don’t use GUI on any step for creating these policies as we have seen issues when policy is  created via GUI (when applying those desired result was not achieved)

This is a 3 step process:

  1.  Create a new Retention Policy Tag: The Retention Policy for voicemail can only be setup using shell and this option is not available in EMC.

Shell Command:

New-RetentionPolicyTag -Name “Delete Voicemail after 30 days” -Type All -Comment “Voicemail older than 30 days will be deleted” -MessageClass Voicemail -RetentionEnabled $true -AgeLimitForRetention 60 -RetentionAction DeleteAndAllowRecovery

2. Create a new Retention Policy:

Shell Command:

New-RetentionPolicy “VoicemailRetentionPolicy” –RetentionPolicyTagLinks “Delete Voicemail after 30 days”

You can verify from Exchange management Console if these are created:(under organization section)

Capture

Now policy has been created but you want to apply it to only Unified Messaging users so here is the script that will assist you.

https://gallery.technet.microsoft.com/scriptcenter/Exchange-2010-Apply-f3edfd2e

This Script can be used to apply the retention policy on exchange 2010 UM mailboxes & also assists in applying to any new ones.

You can modify it according to your needs, We used it for Unified Messaging retention policy.

Change the Policy Name inside .ps1 as per your environment.

$pol = “VoicemailRetentionPolicy”

run the batch file or schedule the script via task scheduler

Script will apply the policy to any new UM mailboxes that are without retention, It also will show you on screen output as well as logs in csv inside the logs foler.

 

############################################################################# 
#       Author: Alex Rodrick 
#    Reviewer: Vikas Sukhija 
#       Date: 4/14/2016 
#       Description: Apply Voice email retetion policy 
############################################################################# 
 
# Add Exchange Shell... 
 
If ((Get-PSSnapin | where {$_.Name -match "Microsoft.Exchange.Management.PowerShell.E2010"}) -eq $null) 
{ Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010} 
 
 
#format Date 
 
$date = get-date -format d 
$date = $date.ToString().Replace(“/”, “-”) 
 
$output = ".\logs\" + "UMretentiongApplied_" + $date + "_.csv" 
 
$pol = "VoicemailRetentionPolicy" 
 
$ummbx = Get-UMMailbox -Resultsize:Unlimited | Get-Mailbox  | Where-Object{$_.RetentionPolicy -ne $pol}  | Select Name,Alias 
 
if($ummbx -ne $null){ 
foreach($i in $ummbx) 
  { 
   Write-host "Processing ..."$i.Name"..." -foregroundcolor green 
   Set-Mailbox $i.Alias -RetentionPolicy $pol 
  } 
 
$ummbx | export-csv $output -notypeinformation 
} 
 
else { 
Write-host " Nothing to Process" - foregroundcolor magenta 
 
} 
 
 
 
  
#############################################################################

Regards

Sukhija Vikas

http://msexchange.me

 


Monitoring Unified Messaging Worker Process Port Number

$
0
0

Unified Messaging worker process in Exchange uses either port 5065 & 5067, we had some issues with Avaya session manager that it was not able to redirect to these ports after making an initial connection on port 5060.

Therefore till the problem can be fixed Avaya team was doing hard coding of the port numbers (5065 /5067) but issue here is these port number changes between  5065 & 5067.

GIF-How-a-face-changes-with-changing-light

Again powershell has came as a rescue here & we have built a nice workaround, if port changes than Avaya team gets alerted & they change the port at their end.

For example:

If initially port is 5065 & for some reason after Unified Messaging server reboot port changes to 5067 , alert is being generated.

To achieve this goal we need something as telnet to programmatically test the port numbers so here is the powershell script that we embedded in our solution.

http://blogs.technet.com/b/wsnetdoc/archive/2011/11/07/windows-powershell-script-test-port.aspx

Download & extract the solution from below link:

https://gallery.technet.microsoft.com/scriptcenter/Unified-Messaging-Port-de7b57dc

Update the UMsrvsWport.txt as shown below(script can handle multiple servers)

Update the UMportMon.ps1 file with email addresses & smtp server

$smtpServer = “smtpserver”

$fromadd = “SystemsMonitoring@labtest.com”
$email1 = “Sukhija1@labtest.com”

Schedule the script from task scheduler every 15 -30 minutes & now when ever port changes you will get alert as below:

######################################################################### 
#            Author: Vikas Sukhija 
#            Date: 4/4/2016 
#            Reviewer: 
#            Desc: Monitor Port for unified messsaging &  
#            send alert if it changes 
#            Refrence: http://blogs.technet.com/b/wsnetdoc/archive/2011/11/07/windows-powershell-script-test-port.aspx 
######################################################################### 
#--------For Log Files-------------- 
 
$date = get-date -format d  
$date = $date.ToString().Replace(“/”, “-”)  
$time = get-date -format t  
$time = $time.ToString().Replace(":""-")  
$time = $time.ToString().Replace(" """)  
 
$logs = ".\Logs" + "\" + "UMporttest" + $date + "_" + $time + "_.log" 
 
$smtpServer = "smtpserver" 
$fromadd = "SystemsMonitoring@labtest.com" 
 
$email1 = "Sukhija1@labtest.com" 
 
$port1 = "5065" 
$port2 = "5067" 
 
 
Start-Transcript -Path $logs  
 
################LOad Test Port Function###################### 
 
write-host "Loading test port function" -foregroundcolor green 
 
. .\test-port.ps1 
 
$arrsrvpo = @() 
 
$umsrvs = gc .\UMsrvsWport.txt 
 
$umsrvs | foreach-object { 
 
$srv = $_.split(":")[0] 
$port = $_.split(":")[1] 
 
 
#####################Test ports now#################### 
 
if($port1 -eq $port) { 
Write-host "$port1 is the current port on server $srv" -foregroundcolor green 
 
$tport1 = Test-Port -computer $srv -port $port1 -tcp 
$tport2 = Test-Port -computer $srv -port $port2 -tcp 
 
if(($tport1.open -like $false-and ($tport2.open -like $true)){ 
 
$msg = new-object Net.Mail.MailMessage 
$smtp = new-object Net.Mail.SmtpClient($smtpServer) 
 
#Mail sender 
$msg.From = $fromadd 
#mail recipient 
$msg.To.Add($email1$msg.Subject = "Open Critical: Port $port1 is not open on $srv - Pls change it in avaya session manager to $port2" 
$msg.Body = "Port $port1 is not open on $srv - Pls change it in avaya session manager to $port2" 
$smtp.Send($msg) 
 
#################update ports file################## 
$arrsrvpo +$srv + ":" + $port2 
 
    } 
else$arrsrvpo +$srv + ":" + $port1} 
 
} 
 
if($port2 -eq $port) { 
 
Write-host "$port2 is the current port on server $srv" -foregroundcolor green 
 
$tport1 = Test-Port -computer $srv -port $port1 -tcp 
$tport2 = Test-Port -computer $srv -port $port2 -tcp 
 
if(($tport2.open -like $false-and ($tport1.open -like $true)){ 
 
$msg = new-object Net.Mail.MailMessage 
$smtp = new-object Net.Mail.SmtpClient($smtpServer) 
 
#Mail sender 
$msg.From = $fromadd 
#mail recipient 
$msg.To.Add($email1) 
 
$msg.Subject = "Open Critical: Port $port2 is not open on $srv - Pls change it in avaya session manager to $port1" 
$msg.Body = "Port $port2 is not open on $srv - Pls change it in avaya session manager to $port1" 
$smtp.Send($msg) 
 
#################update ports file################## 
 
$arrsrvpo +$srv + ":" + $port1 
    } 
else$arrsrvpo +$srv + ":" + $port2} 
 
} 
 
} 
 
$arrsrvpo > ".\UMsrvsWport.txt" 
 
stop-transcript 
 
##############################################################
Regards
Sukhija Vikas

DAG Creation Installation Notes

$
0
0

Today I am sharing the brief notes that you can refer for creating the Database Availability Group for Exchange Environment. We have used it for 2010 environment – win 2008 r2sp1 (changed to make it generic).

  1. Copy the installation files to the Server

2. Check Powershell version should be 2.0 ($psversiontable)

3. Run Set-ExecutionPolicy unrestricted in powershell. (you can change it later)

4. Open Powershell & install Win_PreReqs_MBX.ps1 (extract the scripts from below path)

https://1drv.ms/u/s!Aqor_aWWYXrDgRmMXHZ34G518Z-B

5. Install  _WinR2SP1_Cluster_HotFix & _FilterPack (included in above download)

6.  Install Fail-over clustering Feature

7. Set the Service Net.TcpPort Sharing Service to Automatic

8.  Set the Windows Firewall Service to automatic and start the service

9. Check Private/Public NICs (private NIC should not have DNS registration check)

10. Change the binding order of NICs, Public should be on Top.

11. Run setup.com & choose languages on DVD , Custom install(automatically install required features) – Choose the installation path (I generally avoid installation on system drive)

12.  Select Mailbox Role –> finish wizard /restart

13.  Install latest service pack/Rollups /restart

14.  Add free busy fix registry & Max session  (this can be environment specific  – optional)

Download the registry from here:

https://1drv.ms/u/s!Aqor_aWWYXrDgRoUQjWWHnT7L9kN

Setting for Private/Public NIC interfaces

Feature MAPI Network Setting Replication Network Setting
Name Public Private
Teamed As per enviornment NA
Client for Microsoft Networks Enabled Disabled
QoS Packet Scheduler Enabled Enabled
File and Printer Sharing for Microsoft Networks Enabled Disabled
IPv6 Enabled Enabled
IPv4 Enabled Enabled
Link-Layer Topology Discovery Mapper I/O Driver Enabled Enabled
Link-Layer Topology Discovery Responder Enabled Enabled

Follow the same procedure on other node.

15. Now we can proceed further for DAG creation:

New-DatabaseAvailabilityGroup -Name DAG01 -WitnessServer WSServer -WitnessDirectory I:\DAG_FSW\DAG01 -DatabaseAvailabilityGroupIpAddresses 192.168.14.11, 192.168.14.12

16. Thru Exchange management console Configure DAG (Manage membership)

17.  Update DAG Configuration

Set-DatabaseAvailabilityGroup -identity DAG01 -AlternateWitnessServer wsserver2  -AlternateWitnessDirectory I:\DAG_FSW\DAG01 -DatacenterActivationMode DagOnly -networkcompression enabled

18.  Configure Dag Networks now  from Exchange management console, remove the default created networks & create MAPI/Replication networks.

if you want step by step info on how to create new networks & collapse default ones here is the link from other blogger, you can find plenty on the internet

Configuring DAG Networks in Exchange 2010

19.  Create the Mailbox databases

New-MailboxDatabase -Name “DAG01_Database01” -EdbFilePath J:\DAG01_Database01\DAG01_Database01.edb -LogFolderPath J:\DAG01_DatabaseLog01

Mount-Database -Identity “DAG01_Database01

Add-MailboxDatabaseCopy -Identity DAG01_Database01 -MailboxServer Node02

20.  Set activation preferences

Set-MailboxDatabaseCopy -Identity DAG01_Database01\Node02 -ActivationPreference 2

Now you can setup default quotas, Journaling, Quota notification schedules.

This is our default check list for DAG creation, its just a  brief to do kind of list so that we don’t forget what is required.

I-check-my-student-load-balance

Regards

Sukhija Vikas

http://msexchange.me



Mailbox Move Agent

$
0
0

Sharing a script that I named as Mailbox agent, it is a package of 3 scripts:

1-SubmitMailBoxMoveRequests.ps1

2-ResumeMailBoxMove.ps1

3-ClearCompleteMailBoxMove.ps1

These we used during mailbox moves from old dags to newly created dags for exchange 2010.

update 1-SubmitMailBoxMoveRequests.ps1 script with OLDDAG/NewDAG name

$mbxsrvsrc = “OLDdag01”

$mbxsrvdst = “Newdag01”

Script will check the $countperday value & from each databse migrate the number of  malboxes (based on the value) to all destination databases.

Example: If DAGOLD has 4 databases & value for $countperday = 10

than 10 mailboxes from each DB will be migrated to destination databses.

if DAGNEW has 10 databases than 1 mailbox will be moved to db1, 2nd will move to db2 & soon…

Mailboxes will be equally distributed among all destination DBs. (this will be all automatic)

1-SubmitMailBoxMoveRequests.ps1  –> This will submit the requests & suspends after 95% completion

2-ResumeMailBoxMove.ps1 –> This will resume the request based on geography if required, just update the $region.

example: $region = “United Kingdom” (keep its value as * if you don’t want to use region)

3-ClearCompleteMailBoxMove.ps1 –> This will clear the completed requests.

All these scripts will send report in email, so please update the email variables inside the scripts.

$smtpserver = 

$from = 

$email1 = 

Extract the scripts from below link, hopefully these will work for you & will make mailbox moves easy.

https://gallery.technet.microsoft.com/scriptcenter/Mailbox-Move-Agent-08921668

 

you can also filter out the mailboxes that you want to move by updating the submit script, below is the example:

that I used to avoid migration of certain mailboxes & also just migrate the ones above 10 MB quota.

$mbx += get-mailbox -database $db -resultsize $countperday | where{(($_.MailboxMoveStatus -like “None”) -and ($_.Name -notlike “sys*”) -and ($_.ProhibitSendQuota -gt “10 MB”))}

 

 

Regards

Sukhija Vikas

http://msexchange.me


Kernel for Exchange Server Recovery

$
0
0

This week I was reviewing the recovery software for Exchange environment & I can say that   Kernel for Exchange Server Recoveryis one of the best /economical software.

By using this software you can extract PST from edb database, save it to Exchange/o365, save it to Public folder/ Archive mailbox.

I have tested the SAVE it to PST option & it works like a charm, This software can also be used in the environment where you take backup of exchange using Snapshot technology & than you can use snapshot restore /extract the PST from edb to restore the particular mailbox.

Installation/Configuration is quite simple, I just grabbed the binary file of the software which was just 17.7 MB in size & started installation.

Here are the Step by step instructions along with screen shots(OS I have chosen is windows 2008 R2)

1

Click Next to follow the Wizard

2

Accept the License Agreement to move further

3

Select the installation path or just click next to choose the default location.

4

Click Next

5

Follow the wizard further

6

8

Click Finish & launch the Kernel for Exchange Recovery.

9

Now enter the activation details:

10

I received the below error because outlook was not installed on the system so I installed outlook 2010.

11

After outlook 2010 installation , I have launched the software again & this time there were no errors, select the EDB file from which you want to extract user PST.

13

I just followed the standard option as recommended.

14

After you will click finish you will be able to see all mailboxes inside the EDB file.

15

Now just click save to PST option & select the mailbox that you want to convert to PST file.

18

Follow the wizard & pst will be restored.

19

You can also check the HTML report on how many items were restored specific to particular folder.

Software is very simple & also have very simple Licensing requirements that you can find on below link: (prices are also not high)

http://www.nucleustechnologies.com/buy-exchange-server-recovery.php

There are three different types of Licenses:

Corporate License As the name suggests its for the single orgnaizations but they can install it on multiple machines.

Corporate License (Premium) with premium verison you get 24*7 support as well as added benefit of migrating data to office 365.

Technician License  This is for IT organizations that take Annual  maintenance contracts for other organizations. I think free lancers/Consultants will also benefit from this licensing model but do check with the vendor.

If you are using SAN & still using traditional backup for mailbox recovery/ single item recovery (example : thru backupexec/netbackup), you can get rid of them by implementing snapshot based backup & for restore mechanism just restore the snapshot ,map the LUN to the server where Kernel for Exchange recovery is installed & do a mailbox recovery.

This software supports outlook version from 97 to 2016 & exchange version from 5.0 to 2016. It is gold award winner from popular msexchange.org

Apart from Kernel for Exchange Recovery there is Kernel Exchange Suite as well, which includes OST to PST, PST & Bkf repair in addition to EDB recovery, I did’t got the chance to explore the other parts of the Suite but as I have worked thru EDB recovery so I can easily say that other recovery tools in the suite would be similar (simpler in installation, configuration & working).

Regards

Sukhija Vikas

http://msexchange.me


office 365 Hybrid email Routing

$
0
0

As engaged with office 365 migration therefore I am learning more & more about office 365 and one of the interesting topic is email routing to & from exchange online /on-premise.

There are two options that are suggested by Hybrid wizard

  • Typical
  • Centralized

8

When you select Typical , internal mail flow i.e

Exchange online to Exchange on-premise & vice versa happens thru Hybrid servers but internet email from  Exchange online routes using EOP & from Exchange on-premise routes whatever you have already defined in connectors (example: third party gateways). This is also known as Decentralized routing.

When you select “Enable Centralized mail transport” , internal mail flow i.e

Exchange online to Exchange on-premise & vice versa happens thru Hybrid servers along with internet email , That’s why it is called Centralized routing & is generally selected by enterprise customers as they want to control the flow for different security purposes.

When you run the hybrid wizard what it  does is create connectors in on-prem/ cloud environment based on the option you choose.

You can edit these connectors based on your requirements for mail routing.( be cautious as it will impact routing)

capture

For example:

In one configuration where we were using third-party cloud as email gateway , we have Chosen Typical mail flow & after that added a connector on EOP to route all the internet email via third party gateway ( you need to do settings on third party device so that it can accept email for relay from office 365). This configuration had removed the extra overhead of routing the email internally & than reaching third party.

You have to select Partner organization when configuring the out bound connector from EOP to Internet.

There are other solutions that happen while you work thru the setup for enterprises, As per Microsoft Recommendation they need direct connection(NAT ) from exchange online to hybrid hub servers , no devices should interfere in between the mailflow as that can alter the headers. Only supported device if your organization doesn’t want to direct NAT SMTP is having edge servers in the DMZ.

Here is what we have done for one organization & Microsoft told us that they will not assist in this configuration but if it will work than its fine.

We have reverse proxy the 443 as well as port 25 behind F5 & made it work , This can cause performance issues with large enterprises during mailbox moves as well as SMTP traffic performance can get affected that’s why MS or other cloud members always ask for direct connection but some time situation doesn’t favor because of security concerns raised by the organization so you need to think outside the box & mitigate the concerns.

 

Regards

Sukhija Vikas

http://msexchange.me

 

 


How to identify who accessed mailboxes in Exchange 2010

$
0
0

Introduction

In large organizations mailboxes may be accessed by a number of people besides the owners – including delegates and administrators. Because of this, proper auditing of mailbox access needs to be carried out in order to defend against the misuse of critical information. Mailbox audit logging (available from Exchange 2010 SP1 onwards) helps to track mailbox access and meet regulatory compliances mandates. Below are the steps you need to take to audit mailbox access:

Step 1 – To check whether mailbox audit logging is enabled

To verify whether auditing is enabled on a mailbox, run:

Get-Mailbox –Identity <mailbox name> | Format-List *audit*

Note: Mailbox auditing on mailboxes is disabled by default.

For example:

Get-Mailbox –Identity TestUser1 | Format-List *audit*

Step 2 – To enable mailbox audit logging for a mailbox

To enable mailbox audit logging, run the command in the following syntax in Exchange Management Shell:

Set-Mailbox -Identity “<mailbox name>” -AuditEnabled $True

 

Note: The audit logs are stored for 90 days by default.

For example:

Set-Mailbox -Identity “TestUser5” -AuditEnabled $True

 

 Step 3 – To enable mailbox audit logging for specified users and specified operations

 To enable mailbox auditing for specified operations by the administrator, delegates or owner, follow the syntax:

Set-Mailbox -Identity “<mailbox name>” -AuditAdmin <opeartion1>, <operation2> -AuditEnabled $True

 

Set-Mailbox -Identity “<mailbox name>” -AuditDelegate <opeartion1>, <operation2> -AuditEnabled $True

 

Set-Mailbox -Identity “<mailbox name>” -AuditOwner <opeartion1>, <operation2> -AuditEnabled $True

 

For example:

Set-Mailbox -Identity “TestUser3” -AuditAdmin HardDelete, SoftDelete -AuditEnabled $True
Set-Mailbox -Identity “TestUser3” -AuditDelegate SendAs, SendOnBehalf -AuditEnabled $True
Set-Mailbox -Identity “TestUser3” -AuditOwner MoveToDeletedItems -AuditEnabled $True

Step 4– To view the mailbox audit log data (for a single mailbox)

To view the mailbox audit log data, run:

Search-MailboxAuditLog -Identity <mailbox name> -LogonTypes <Admin, Delegate> -ShowDetails -StartDate <mm/dd/yyyy> -EndDate <mm/dd/yyyy> -ResultSize <size>

 

For example:

Search-MailboxAuditLog -Identity TestUser5 -LogonTypes Admin, Delegate -ShowDetails -StartDate 09/01/2016 -EndDate 09/06/2016 -ResultSize 1

Step 5 – To get the audit log data by email (as XML file) for one or more mailboxes

To get the audit log data by email (as XML file) for one or more mailboxes, run:

New-MailboxAuditLogSearch -Mailboxes “<mailbox1 name>”,”<mailbox2 name>” -LogonTypes <Admin, Delegate> -StartDate <mm/dd/yyyy> -EndDate <mm/dd/yyyy> -StatusMailRecipients “<email id>” -ShowDetails

 

 

For example:

New-MailboxAuditLogSearch  -Mailboxes “TestUser5” -LogonTypes Admin, Delegate -StartDate 09/01/2016 -EndDate 09/06/2016 -StatusMailRecipients administrator@www.vdoc.com -ShowDetails

Step 6 – To disable mailbox auditing

To disable mailbox auditing, use:

Set-Mailbox -Identity “<mailbox name>” -AuditEnabled $false

For example:

Set-Mailbox -Identity “TestUser1” -AuditEnabled $false

Conclusion:

From a security and compliance standpoint, it’s important for organizations to track who accesses mailboxes and what actions they take once inside. From 2010 SP1 onwards, Microsoft Exchange provides a mailbox auditing facility to make this a possibility. However, it can be time consuming and the reports generated are not very user friendly. Automated Exchange auditing solutions, like LepideAuditor for Exchange Server, provide more detailed and easy-to-read mailbox access reports to help organizations easily meet regulatory compliances challenges.

Author:
Ajit Singh is associated with Lepide Software as a Manager – Marketing Operations. Lepide Software provides solutions for change auditing and compliance, server migration and Exchange recovery.


Change ActiveSync Policy Based on AD group

$
0
0

There has been a requirement that we need to change the policy of certain users & need to automate the process based on AD group.

We have written below script to do this job, this script uses QAD AD Shell & Exchange management shell.

It fetches group members from the AD group export them in csv (so that it can compare afterwards & only changes are processed)

When running the script for the first time it will generate a CSV file of group members (empty the whole file except one user that you can process manually)

After that you can just schedule the script it will run incrementally.

  • When ever new user is added to the group –> Active sync policy will be updated
  • When user is removed from the group –> Activesync policy will be changed to default
  • Recycle logs after 30 days
  • If error occurs than send alert.

Download & extract the script from below link

https://gallery.technet.microsoft.com/scriptcenter/Change-ActiveSync-Policy-10840be7

Update the below values as per customer’s environment:

———————————————————————–

$smtpServer = “smtpserver”

$fromadd = “DoNotReply@labtest.com”

$email1 = “VikasS@labtest.com”

 

$Asyncpol = “ActiveSync Policy”

$defAsyncpol = “Default ActiveSync Policy”

$group = “AD Group”

——————————————————————————

Thanks to “Lazy Admin” as incremental code has been taken from one of his blog post.

http://www.lazywinadmin.com/

 

###################################################################### 
#               Author: Vikas Sukhija(http://msexchange.me) 
#               Date:- 03/16/2016 
#        Reviewer:- 
#               Description:- Change activesync policy based on  
#               a particular AD group. 
###################################################################### 
 
$date1 = get-date -format d 
$date1 = $date1.ToString().Replace("/","-"$dir".\logs" 
$limit = (Get-Date).AddDays(-30) 
 
$logs = ".\Logs" + "\" + "Processed_" + $date1 + "_.log" 
 
$smtpServer = "smtpserver" 
$fromadd = "DoNotReply@labtest.com" 
$email1 = "VikasS@labtest.com" 
 
Start-Transcript -Path $logs 
 
######Add Quest Shell & define attrib/ group value############ 
 
If ((Get-PSSnapin | where {$_.Name -match "Quest.ActiveRoles.ADManagement"}) -eq $null) 
{ 
    Add-PSSnapin Quest.ActiveRoles.ADManagement 
} 
 
#######Add exchange Shell ############################## 
 
If ((Get-PSSnapin | where {$_.Name -match "Microsoft.Exchange.Management.PowerShell.E2010"}) -eq $null) 
{ 
    Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 
} 
 
$Asyncpol = "ActiveSync Policy" 
$defAsyncpol = "Default ActiveSync Policy" 
 
$group = "AD Group" 
 
################################################################# 
 
$groupmem = Get-QADGroupMember $group -sizelimit 0 
 
$groupmem 
 
$Statefile = "$($group)-Name.csv" 
 
 
# If the file doesn't exist, create it 
 
   If (!(Test-Path $Statefile)){   
                $groupmem | select Name | Export-csv $Statefile -NoTypeInformation  
                } 
 
# Check Changes 
$Changes =  Compare-Object $groupmem $(Import-Csv $StateFile-Property Name |  
                Select-Object Name, 
                    @{n='State';e={ 
                        If ($_.SideIndicator -eq "=>"){ 
                            "Removed" } Else { "Added" } 
                        } 
                    } 
 
$Changes | foreach-object{ 
          
    if($_.state -eq "Added") { 
 
        Write-host "$Asyncpol will be updated to "$_.Name"" -foregroundcolor green 
           $checkasync = Get-CASMailbox -Identity $_.Name 
        if($checkasync.ActiveSyncEnabled -eq $true){ 
    Set-CASMailbox -Identity $_.Name -ActiveSyncMailboxPolicy $Asyncpol}} 
     
     
        if($_.state -eq "Removed") { 
        $userid = "$_.Name" 
        Write-host "$Asyncpol will be removed from "$_.Name"" -foregroundcolor Red 
    $checkasync = Get-CASMailbox -Identity $_.Name 
        if($checkasync.ActiveSyncEnabled -eq $true){ 
    Set-CASMailbox -Identity $_.Name -ActiveSyncMailboxPolicy $defAsyncpol}} 
     
      } 
 
$groupmem | select Name | Export-csv $StateFile -NoTypeInformation 
 
###########################Recycle########################################## 
 
$path = $dir  
  
Get-ChildItem -Path $path  | Where-Object {   
$_.CreationTime -lt $limit } | Remove-Item -recurse -Force  
 
#######################Report Error######################################### 
if ($error -ne $null) 
      { 
#SMTP Relay address 
$msg = new-object Net.Mail.MailMessage 
$smtp = new-object Net.Mail.SmtpClient($smtpServer) 
 
#Mail sender 
$msg.From = $fromadd 
#mail recipient 
$msg.To.Add($email1$msg.Subject = "Activesync Policy Script error" 
$msg.Body = $error 
$smtp.Send($msg$error.clear() 
       } 
  else 
 
      { 
    Write-host "no errors till now" 
      } 
 
$path = ".\logs\" 
$limit = (Get-Date).AddDays(-30) #for log recycling 
 
########################Recycle logs ###################################### 
 
Get-ChildItem -Path $path  | Where-Object {   
$_.CreationTime -lt $limit } | Remove-Item -recurse -Force  
stop-transcript 
 
##########################################################################

Regards

Sukhija Vikas

http://msexchange.me


Viewing all 214 articles
Browse latest View live