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

ADD additional SMTP Email Address Exchange Hybrid

$
0
0

When you run Hybrid Wizard for setting up Exchange onpremise to Exchange online integration, one of the step –> updates the email address policy to include

alias@domain.mail.microsoft.com.

 This adds additional email address to all the users that have Automatically update Email adddresses based on e-mail address policy is checked.

There are always mailboxes in the enviornment where this policy is set to false for reasons.

This nice litte script will update those mailboxes with the required email adddress along with logging & reporting.

Download & extract the zip file from below link , update the .ps1 :

https://gallery.technet.microsoft.com/scriptcenter/ADD-additional-SMTP-b3c3a055

#update the values as per your enviornment

$hybemaildom = “@domain.mail.onmicrosoft.com” 

$email1 = “VikasS@labtest.com”

$from = “EolemailFix@labtest.com”

$smtpserver = “smtpserver”

Run the batch file or run the .ps1 in the exchange shell. Execution scope is only the mailboxes that have email address policy set to false.

CSV report will be sent on email address specified & will also be saved in report folder.

Note: Script has been tested with exchange2010 but should work with other versions as well.

<#     
    .NOTES 
    =========================================================================== 
     Created on:       10/19/2016 12:30 PM 
     Created by:       Diwakar Sharma 
          Reviewed by:   Vikas Sukhija (http://msexchange.me) 
     Organization:      
     Filename:   Additional SMTP o365       
    =========================================================================== 
    .DESCRIPTION 
        This script will be used to add additional SMTP addtess for o365 hybrid setup. 
        There are situation where Email policy is uncheked so this script can be utilized. 
#> 
################Add Snapin & Logs/ variables######################### 
$Error.clear() 
If ((Get-PSSnapin | where { $_.Name -match "Microsoft.Exchange.Management.PowerShell.E2010" }) -eq $null) 
{ 
    Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 
} 
$date1 = get-date -format d 
$date1 = $date1.ToString().Replace("/""-"$time = get-date -format t 
 
$time = $time.ToString().Replace(":""-"$time = $time.ToString().Replace(" """) 
 
$log = ".\logs" + "\" + "Ps_log_" + $date1 + "_" + $time + "_.log" 
$report1 = (Get-Location).path + "\" + "Report" + "\" + "Report_Hybemail" + $date1 + "_" + $time + "_.csv" 
 
$hybemaildom = "@domain.mail.onmicrosoft.com" 
$collection = @() 
 
$email1 = "VikasS@labtest.com" 
$from = "EolemailFix@labtest.com" 
$smtpserver = "smtpserver" 
 
Start-Transcript -Path $log 
 
#############get all mailboxes where policy is not applied##### 
 
$AliasAll = Get-Mailbox -ResultSize Unlimited | Where { $_.EmailAddressPolicyEnabled -ne "True" } | select Alias,emailaddresses 
$Error.clear() 
Foreach ($Als in $AliasAll) 
{ 
    Write-Host "Processing ..............."$Als.alias"" -ForegroundColor green 
    $mcoll = "" | select Alias, hybemail, Status 
    $AddSMTP = $Als.Alias + $hybemaildom 
    $mcoll.Alias = $Als.Alias 
    $mcoll.hybemail = $AddSMTP 
    $AddSMTP 
    $alladdreses = $Als.EmailAddresses | select -ExpandProperty addressstring 
    if($alladdreses -contains $AddSMTP){ 
    $mcoll.Status = "already Present" 
    } 
    else{ 
    $Error.clear() 
    Set-Mailbox $Als.Alias -EmailAddresses @{ add = $AddSMTP } 
    if ($error) 
    { 
        $mcoll.Status = "Error" 
        $Error.clear() 
    } 
    else 
    { 
        $mcoll.Status = "Success" 
    }} 
    $collection+=$mcoll 
} 
$collection | Export-Csv $report1 -NoTypeInformation 
#############Send Report############################## 
$msg = new-object Net.Mail.MailMessage 
$smtp = new-object Net.Mail.SmtpClient($smtpServer$msg.From = $from 
$attach = new-object Net.Mail.Attachment($report1$msg.To.Add($email1$msg.Subject = "Exchange Online Emal Address Fix Report" 
$msg.Body = "Exchange Online Emal Address Fix Report" 
$msg.Attachments.Add($attach$smtp.Send($msgget-date 
Stop-Transcript 
################################################################

Regards

Sukhija Vikas

http://msexchange.me



Email Address Change Monitor

$
0
0

This Script has been Written to fullfil one of the App Team request, Here is the requirement:

  • For any user if Primary SMTP address changes, a notification to be sent to them.
  • Alert notification should include the Previous & Changed value.
  • Format should be CSV.

They require it as they need to update the details in the Application if Primary SMTP address alters.

Here is the powershell magic 🙂

Extract the Zip file from below link

Update the .ps1 file variables:

$limit = (Get-Date).AddDays(-60) #for report recycling

$email1 = “VikasS@labtest.com”

$from = “EmailAddressChange@labtest.com”

$smtpserver = “smtpserver”

Note: Script is using CustomAttribute11 & matching it to $regex = ‘^\d+$’ (integer) i.e. all mailboxes that have employeeid.

This can be changed as per your organization.

First time when the script is run it creates a State-Email.csv file, this is the state file and on next run it compares the newly fetched data with the previous state file to capture the changes which it sends to the specified email in .csv format.

Transcript will be stored in Logs folder & report will be kept inside Report , these will get recycled every 60 days.

Create a schedule Task to run it daily or as per your requirements.(Note: don’t forget to fill start in field when scheduling the batch file)

Note: Script has been tested with Exchange 2010 but should work with other versions as well, just change the shell parameter.

Exchange management Shell is a requirement for this script.

 

<#     
    .NOTES 
    =========================================================================== 
     Created on:       12/8/2016 4:19 PM 
     Created by:       Vikas Sukhija 
     Organization:      
     Filename:         EmailAddressChange.ps1 
    =========================================================================== 
    .DESCRIPTION 
        This Script will monitor changes in Primary SMTP address of Users, 
        if there is a change then responsible team will be notified. 
#> 
################Add Modules Exchange############################# 
$error.clear() 
If ((Get-PSSnapin | where { $_.Name -match "Microsoft.Exchange.Management.PowerShell.E2010" }) -eq $null) 
{ 
    Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 
} 
 
###############ADD Logs & Variables################################ 
$date1 = get-date -format d 
$date1 = $date1.ToString().Replace("/""-"$time = get-date -format t 
 
$time = $time.ToString().Replace(":""-"$time = $time.ToString().Replace(" """) 
 
$log = (Get-Location).Path + "\Logs" + "\" + "Processed_PS_Logs" + $date1 + "_" + $time + "_.log" 
$report1 = (Get-Location).Path + "\Report" + "\" + "Report_Emchange" + $date1 + "_" + $time + "_.csv" 
 
$limit = (Get-Date).AddDays(-60) #for report recycling 
$path1 = (Get-Location).Path + "\Logs" 
$path2 = (Get-Location).Path + "\Report" 
 
$email1 = "VikasS@labtest.com" 
$from = "EmailAddressChange@labtest.com" 
$smtpserver = "smtpserver" 
 
$collmbx = @() 
$collection = @() 
$collection1 = @() 
$Statefile = ".\State-Email.csv" 
$regex = '^\d+$' 
 
################Email Function##################### 
 
function Send-Email 
{ 
    [CmdletBinding()] 
    param 
    ( 
        $From, 
        [array]$To, 
        [array]$bcc, 
        [array]$cc, 
        $body, 
        $subject, 
        $attachment, 
        $smtpserver 
    ) 
    $message = new-object System.Net.Mail.MailMessage 
    $message.From = $from 
    if ($To -ne $null) 
    { 
        $To | ForEach-Object{ 
            $to1 = $_ 
            $to1 
            $message.To.Add($to1) 
        } 
    } 
    if ($cc -ne $null) 
    { 
        $cc | ForEach-Object{ 
            $cc1 = $_ 
            $cc1 
            $message.CC.Add($cc1) 
        } 
    } 
    if ($bcc -ne $null) 
    { 
        $bcc | ForEach-Object{ 
            $bcc1 = $_ 
            $bcc1 
            $message.bcc.Add($bcc1) 
        } 
    } 
    $message.IsBodyHtml = $True 
    if ($subject -ne $null) 
    { 
        $message.Subject = $Subject 
    } 
    if ($attachment -ne $null) 
    { 
        $attach = new-object Net.Mail.Attachment($attachment) 
        $message.Attachments.Add($attach) 
    } 
    if ($body -ne $null) 
    { 
        $message.body = $body 
    } 
    $smtp = new-object Net.Mail.SmtpClient($smtpserver) 
    $smtp.Send($message) 
} 
################################################################ 
if ($error) 
{ 
    Write-Host "Error in initialization"; 
    Send-Email -To $email1 -From $from -subject "Email Address Change Script initialization failure" -smtpserver $smtpserver 
    timeout 10; exit 
} 
 
Start-Transcript -path $log 
get-date 
################ Collect All mailboxes########################### 
 
$collmbx = get-mailbox -resultsize unlimited | where{ $_.CustomAttribute11 -match $regex } | select Name, CustomAttribute11, PrimarySMTPAddress 
$collmbx += get-remotemailbox -resultsize unlimited | where{ $_.CustomAttribute11 -match $regex } | select Name, CustomAttribute11, PrimarySMTPAddress 
if ($error) 
{ 
    Write-Host "Error in Fetching mailboxes data from Exchnage"; 
    Send-Email -To $email1 -From $from -subject "Email Address Change error fetching mailboxes" -smtpserver $smtpserver 
    Stop-Transcript; timeout 10; exit 
} 
If (!(Test-Path $Statefile)) 
{ 
    $collmbx | select Name, CustomAttribute11,PrimarySMTPAddress | Export-csv $Statefile -NoTypeInformation 
} 
 
#########################Start comparison########################## 
 
$stcsv = import-csv $Statefile 
$coll = @() 
 
$Changes = Compare-Object $stcsv $collmbx -property CustomAttribute11,PrimarySMTPAddress | 
Select-Object CustomAttribute11, PrimarySMTPAddress, @{ 
    n = 'State'; e = { 
        If ($_.SideIndicator -eq "=>") { "Current" } 
        elseif ($_.SideIndicator -eq "<=") { "Previous" } 
        else { "Ignore" } 
    } 
} 
################################################################### 
if ($changes) 
{ 
    $Changes | foreach-object{ 
        $mcoll = "" | select Name, CustomAttribute11, PreviousSMTP, NewSMTP 
        if ($_.state -eq "Previous") 
        { 
            $cus1 = $_.CustomAttribute11 
            $Name = ($collmbx | where{$_.CustomAttribute11 -eq $cus1}).name 
            $PreviousSMTP = $_.PrimarySMTPAddress 
            foreach ($chg in $Changes) 
            { 
                if (($cus1 -eq $chg.CustomAttribute11) -and ($chg.state -eq "Current")) 
                { 
                    $NewSMTP = $chg.PrimarySMTPAddress 
                    $mcoll.Name = $Name 
                    $mcoll.CustomAttribute11 = $cus1 
                    $mcoll.PreviousSMTP = $PreviousSMTP 
                    $mcoll.NewSMTP = $NewSMTP 
                     
                } 
            } 
             
        } 
        $collection +$mcoll 
         
    } 
    $collection1 = $collection | where{ $_.name -ne $null } 
    if ($collection1) { $collection1$collection1 | Export-Csv $report1 -NoTypeInformation } 
} 
 
$collmbx | Export-Csv $Statefile -NoTypeInformation # new state 
 
if($collection1){Send-Email -To $email1 -From $from -subject "Email Address Changes" -attachment $report1 -smtpserver $smtpserver} 
 
#################################################### 
if ($error) 
{ 
    Send-Email -To $email1 -From $from -subject "Email Address Change error Report" -body $Error -smtpserver $smtpserver 
} 
 
Get-ChildItem -Path $path1 | Where-Object { 
    $_.CreationTime -lt $limit 
} | Remove-Item -recurse -Force 
 
Get-ChildItem -Path $path2 | Where-Object { 
    $_.CreationTime -lt $limit 
} | Remove-Item -recurse -Force 
 
get-date 
Stop-Transcript
Thanks for Reading
Sukhija Vikas

 


Enable/Disable ActiveSync based on AD group membership

$
0
0

As We have marched towards the New Year so thought of sharing something different that will make you think –> yes there are distinct ways to solve the same problem.

The Script that I am sharing Today has assisted us in decreasing the execution time from 11-12 hours to just 5 -10 minutes. I know that sounds amazing:)

We had a previous script running in our environment which was based on logic:

Enable ActiveSync only for users in a Active Directory group and disable it for all mailboxes not in that group.

https://gallery.technet.microsoft.com/scriptcenter/EnableDisable-ActiveSync-69142cc8 – this is good work by the script author

This script was fetching all group members & was than comparing with all the mailboxes in the enviornment to find out

the mailboxes which needs to be enabled/Disabled for Activesync.

For Big environments that approach takes too much time & that too in hours.(example more than 35000 mailboxes – it was taking 11-12 hours)

I researched / found a good way to handle it & that too in minutes , this is required as we run the script daily.

Approach is to use CSVDE along with Exchange Powershell:

We have formed two queries:

To find Disabled mailboxes that needs to be enabled :

 User should be a mailbox user — (mail=*)(homeMDB=*) , member of required ADgroup, msExchOmaAdminWirelessEnable value is 4,5,6 or 7

$FindDisabledQuery = “(&(objectCategory=user)(objectClass=user)(mail=*)(homeMDB=*)(memberOf=CN=ADGroup,OU=DistributionLists,OU=Exchange,DC=labtest,DC=com)(|(msExchOmaAdminWirelessEnable=4)(msExchOmaAdminWirelessEnable=5)(msExchOmaAdminWirelessEnable=6)(msExchOmaAdminWirelessEnable=7)))”

To find Enabled Mailboxes that needs to be disabled:

User should be a mailbox user — (mail=*)(homeMDB=*) ,not disabled –!userAccountControl=514, not member of required ADgroup,

$FindEnabledQuery = “(&(objectCategory=user)(objectClass=user)(mail=*)(homeMDB=*)(!userAccountControl=514)(!memberOf=CN=ADGroup,OU=DistributionLists,OU=Exchange,DC=labtest,DC=com)(|(!msExchOmaAdminWirelessEnable=*)(msExchOmaAdminWirelessEnable=0)(msExchOmaAdminWirelessEnable=1)(msExchOmaAdminWirelessEnable=2)(msExchOmaAdminWirelessEnable=3)))”

What my script is doing is: getting input of these two queries via CSV import & than processing it.

Getting extract of these two queries just takes less than 5 minutes.

Download the script from below link, extract it & edit the variables as per your environment.

https://gallery.technet.microsoft.com/scriptcenter/EnableDisable-ActiveSync-6dfc70a1

$group = “CN=ADGroup,OU=DistributionLists,OU=Exchange,DC=labtest,DC=com”
$FindDisabledQuery = “(&(objectCategory=user)(objectClass=user)(mail=*)(homeMDB=*)(memberOf=CN=ADGroup,OU=DistributionLists,OU=Exchange,DC=labtest,DC=comm)(|(msExchOmaAdminWirelessEnable=4)(msExchOmaAdminWirelessEnable=5)(msExchOmaAdminWirelessEnable=6)(msExchOmaAdminWirelessEnable=7)))”

$FindEnabledQuery = “(&(objectCategory=user)(objectClass=user)(mail=*)(homeMDB=*)(!userAccountControl=514)(!memberOf=CN=ADGroup,OU=DistributionLists,OU=Exchange,DC=labtest,DC=com)(|(!msExchOmaAdminWirelessEnable=*)(msExchOmaAdminWirelessEnable=0)(msExchOmaAdminWirelessEnable=1)(msExchOmaAdminWirelessEnable=2)(msExchOmaAdminWirelessEnable=3)))”

$countofchanges = “100” # if count is more than this number than just send alert & not process any mailboxes.
$email1 = “VikasS@labtest.com”

$from = “donotreply@labtest.com”

$smtpserver = “smtpserver”

###Logs will be placed in logs folder & CSV queries will be in temp folder – these will be recycled after 60 days, which you can also change inside the script by just changing the number(-60)

Script will also send email about the changes it has done i.e. users that are enabled for activesync and users that are disabled for activesync.

capture

You can schedule the script to run daily (don’t forget to fill start in field)

Here is the code:

<#     
    .NOTES 
    =========================================================================== 
      
     Created on:       12/1/2016 2:28 PM 
     Created by:       Vikas Sukhija 
     Organization:      
     Filename:         EnableActiveSync.ps1 
    =========================================================================== 
    .DESCRIPTION 
        Enable ActiveSync only for users in a Active Directory group and  
        disable it for all mailboxes not in that group 
#> 
$error.clear() 
#####################Fuunctions################### 
function ProgressBar { 
    [CmdletBinding()] 
    param 
    ( 
        $Title 
    ) 
    For ($i = 1; $i -le "10"$i++) { 
        Start-Sleep 1; 
        Write-Progress -Activity $Title -status "$i" -percentComplete ($i /10 * 100) 
    } 
} 
 
function Send-Email { 
    [CmdletBinding()] 
    param 
    ( 
        $From, 
         
        $To1, 
         
        $To2, 
         
        $To3, 
         
        $bcc, 
         
        $cc, 
         
        $body, 
         
        $subject, 
         
        $attachment, 
         
        $smtpserver 
    ) 
    $message = new-object System.Net.Mail.MailMessage 
    $message.From = $from 
    if ($To1 -ne $null) { 
        $message.To.Add($To1) 
    } 
    if ($To2 -ne $null) { 
        $message.To.Add($To2) 
    } 
    if ($To3 -ne $null) { 
        $message.To.Add($To3) 
    } 
    if ($cc -ne $null) { 
        $message.CC.Add($cc) 
    } 
    if ($bcc -ne $null) { 
        $message.Bcc.Add($bcc) 
    } 
    $message.IsBodyHtml = $True 
    if ($subject -ne $null) { 
        $message.Subject = $Subject 
    } 
    if ($attachment -ne $null) { 
        $attach = new-object Net.Mail.Attachment($attachment) 
        $message.Attachments.Add($attach) 
    } 
    if ($body -ne $null) { 
        $message.body = $body 
    } 
    $smtp = new-object Net.Mail.SmtpClient($smtpserver) 
    $smtp.Send($message) 
} 
###########Add Exchnage Snapin ###################### 
If ((Get-PSSnapin | Where-Object { $_.Name -match "Microsoft.Exchange.Management.PowerShell.E2010" }) -eq $null) { 
    Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 
} 
if ($error) { ProgressBar -Title "Exit - Exchnage Shell not loaded"exit } 
###############ADD Logs and variables ############### 
$date1 = get-date -format d 
$date1 = $date1.ToString().Replace("/""-"$time = get-date -format t 
 
$time = $time.ToString().Replace(":""-"$time = $time.ToString().Replace(" """) 
 
$log = (Get-Location).Path + "\Logs" + "\" + "Processed_PS_AS" + $date1 + "_" + $time + "_.log" 
$log1 = (Get-Location).Path + "\Logs" + "\" + "Enabled_Disabled_AS" + $date1 + "_" + $time + "_.log" 
 
$csv1 = (Get-Location).Path + "\Temp" + "\" + "DisabledUsers" + $date1 + "_" + $time + "_.csv" 
$csv2 = (Get-Location).Path + "\Temp" + "\" + "EnabledUsers" + $date1 + "_" + $time + "_.csv" 
 
$group = "CN=ADGroup,OU=DistributionLists,OU=Exchange,DC=labtest,DC=com" 
 
$FindDisabledQuery = "(&(objectCategory=user)(objectClass=user)(mail=*)(homeMDB=*)(memberOf=CN=ADGroup,OU=DistributionLists,OU=Exchange,DC=labtest,DC=comm)(|(msExchOmaAdminWirelessEnable=4)(msExchOmaAdminWirelessEnable=5)(msExchOmaAdminWirelessEnable=6)(msExchOmaAdminWirelessEnable=7)))" 
$FindEnabledQuery = "(&(objectCategory=user)(objectClass=user)(mail=*)(homeMDB=*)(!userAccountControl=514)(!memberOf=CN=ADGroup,OU=DistributionLists,OU=Exchange,DC=labtest,DC=com)(|(!msExchOmaAdminWirelessEnable=*)(msExchOmaAdminWirelessEnable=0)(msExchOmaAdminWirelessEnable=1)(msExchOmaAdminWirelessEnable=2)(msExchOmaAdminWirelessEnable=3)))" 
 
$countofchanges = "100" 
 
$email1 = "VikasS@labtest.com" 
$from = "donotreply@labtest.com" 
$smtpserver = "smtpserver" 
 
$limit = (Get-Date).AddDays(-60) #for report recycling 
$path1 = (Get-Location).Path + "\Logs" 
$path2 = (Get-Location).Path + "\Temp" 
 
Start-Transcript -Path $log 
####################CSVDE Processing################## 
 
if (Get-DistributionGroup $group) { 
     
    CSVDE -$csv1 -r $FindDisabledQuery -"sAMAccountName, msExchOmaAdminWirelessEnable" 
     
    CSVDE -$csv2 -r $FindEnabledQuery -"sAMAccountName, msExchOmaAdminWirelessEnable" 
     
} 
else { 
    Write-Host "Exiting Script as group doesn't exist" -ForegroundColor Red 
    ProgressBar -Title "Exiting Script as group doesn't exist" 
    Exit 
} 
if ($error) { ProgressBar -Title "Exit - CSVDE Export Error"exit } 
##############Enable ActiveSync Processing########### 
if (Test-Path $csv1) { 
    $data = Import-Csv $csv1 
    if ($error) { ProgressBar -Title "Exit - Import CSV Error"exit } 
    if ($data.count -lt $countofchanges) { 
        if ($data -ne $null) { 
            foreach ($i in $data) { 
                if (Get-CASMailbox $i.sAMAccountName) { 
                    Set-CASMailbox -Identity $i.sAMAccountName -ActiveSyncEnabled:$true 
                    $dt = get-date 
                    $sm = $i.sAMAccountName 
                    Write-Host "$sm is enabled for ActiveSYnc" -ForegroundColor Green 
                    Add-Content $log1 "$dt -- $sm is enabled for ActiveSYnc" 
                } 
                else { 
                    Write-Host ""$i.sAMAccountName" is not mailbox" -ForegroundColor Yellow 
                } 
            } 
        } 
         
    } 
    else { 
        Write-Host "Count of changes are more than $countofchanges" -ForegroundColor Yellow 
        Send-Email -From $from -To1 $email1 -subject "Disable ACtiveSync - Count of changes are more than $countofchanges" -smtpserver $smtpserver 
    } 
} 
 
##############Disable ActiveSync Processing########### 
if (Test-Path $csv2) { 
    $data = Import-Csv $csv2 
    if ($error) { ProgressBar -Title "Exit - Import CSV Error"exit } 
    if ($data.count -lt $countofchanges) { 
        if ($data -ne $null) { 
            foreach ($i in $data) { 
                if (Get-CASMailbox $i.sAMAccountName) { 
                    Set-CASMailbox -Identity $i.sAMAccountName -ActiveSyncEnabled:$false 
                    $dt = get-date 
                    $sm = $i.sAMAccountName 
                    Write-Host "$sm is Disabled for ActiveSYnc" -ForegroundColor Yellow 
                    Add-Content $log1 "$dt -- $sm is Disabled for ActiveSYnc" 
                } 
                else { 
                    Write-Host ""$i.sAMAccountName" is not mailbox" -ForegroundColor Yellow 
                } 
            } 
        } 
         
    } 
    else { 
        Write-Host "Count of changes are more than $countofchanges" -ForegroundColor Yellow 
        Send-Email -From $from -To1 $email1 -subject "Disable ACtiveSync - Count of changes are more than $countofchanges" -smtpserver $smtpserver 
    } 
} 
if (Test-Path $log1) { 
    Send-Email -From $from -To1 $email1 -subject "Manage-ActiveSync Log" -attachment $log1 -smtpserver $smtpserver 
} 
##################Recycle logs################# 
if ($error) {Send-Email -From $from -To1 $email1 -subject "Error - Manage Active Sync" -body $error -smtpserver $smtpserver} 
     
Get-ChildItem -Path $path1 | Where-Object { 
    $_.CreationTime -lt $limit 
} | Remove-Item -recurse -Force 
 
Get-ChildItem -Path $path2 | Where-Object { 
    $_.CreationTime -lt $limit 
} | Remove-Item -recurse -Force 
 
Stop-Transcript 
#########################################################

Thanks for reading

Sukhija Vikas

http://SysCloudPro.com


Office 365 groups Write back without Azure AD Premium

$
0
0

As discussed in previous post on Office 365 group that there are customer requirements where they want that on-premise users should be able to send email to office 365 groups but they need Group write-back feature which is part of Azure ad premium & they need to be at-least on Exchange 2013.

There is workaround of creating a corresponding mail contact for each office 365 group in on-premise Environment.(Target address would be .mail.onmicrosft.com)

If we follow the work around than admins have to monitor manually and than ADD/Delete the corresponding mail contacts in their On-premise Environment which is kind of a PAIN.

Thanks to Powershell, with some innovation I was able to built the first version of Office 365 Group Write Back that can be scheduled via task Scheduler. This will monitor any New Office 365 groups and Create a corresponding mail contacts , also if Office 365 group is deleted it will perform the delete.

Requirements for this Solution:

  • Separate OU Named “Office 365 Groups” (you can pick your own name)
  • Remove this OU from AAD synchronization.
  • One of the CustomAttribute (I am using CustomAttribute1 for storing GUID)
  • Rights on Exchange Online.
  • Rights on On-premise for creating/removing mail contacts in the above OU.

Solution Logic:

  • Fetch all Office 365 groups from Exchange Online.
  • Fetch all Mail contacts in Office 365 groups OU in On-premise.
  • Compare the GUID with Onpremsie mail contact.
  • If group contact is not present in onpremise than create it.
  • ADD Alias@domain.mail.onmicrosoft.com to office 365 group if not already present.
  • If group contact is present in onpremise but no corresponding group on cloud than delete it.
  • Any exceptions/errors are captured
  • Count of changes in a day if exceed certain value code will exit.
  • Report of Changes will be generated & sent on email.

Download the Solution ZIP file from below Link:

https://gallery.technet.microsoft.com/scriptcenter/Office-365-groups-Write-7f0dc4e3

capture

Update O365GrpWrtBack.ps1

LaunchEOL -user “EolAdmin@domain.com” -Encrypted “01000000d”

I have included the encryptpass inside the solution, just run the batch file & encrypt the password that you can use above to schedule the script.(encrypted password will get stored in securepassword.txt)

Note: This encryption step needs to be done from account/server from which you will schedule the script.

capture

$hybmaildomain = “@domain.mail.onmicrosoft.com” ##for target Address (mail routing)

$o365groupsOU = “domain.com/o365Groups” ##OU for Creating/deleting mail Contacts
$countofchanges = “10” ## count of changes.

$email1 = “VikasS@labtest.com”
$from = “o365GroupWriteBack@labtest.com”
$smtpserver = “smtpserver”

After changing all these as per your environment , we are all set.

Schedule the Batch file & don’t forget to fill start in folder.

capture

You will notice that All mail contacts corresponding to office 365 groups will be created.

If you have any that you have manually created, please update the GUID for them in cutomattribute1 so that these are not deleted.
capture

PowerShell Code:

<#     
    .NOTES 
    =========================================================================== 
     Created on:       1/6/2017 10:46 AM 
     Created by:       Vikas Sukhija (http://syscloudpro.com) 
     Organization:      
     Filename:         O365GrpWrtBack.ps1 
    =========================================================================== 
    .DESCRIPTION 
        This Script will writeback the Office 365 Groups as Mailcontacts 
        to onpremise enviornment so that email routing can happen from onpremise  
        Users to Office365 Groups 
#> 
##############Load Functions & modules################# 
$Error.clear() 
. .\LoadFunctions.ps1 
 
If ((Get-PSSnapin | where { $_.Name -match "Microsoft.Exchange.Management.PowerShell.E2010" }) -eq $null) 
{ 
    Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 
} 
 
LaunchEOL -user "EolAdmin@domain.com" -Encrypted "01000000d" 
if ($error) { ProgressBar -title "Error loading Functions" -timer 10; exit } 
 
#########Variables and Logs ######### 
$log = Write-Log -Name "Transcript_o365group""o365_group_log" -Ext log -folder logs 
$report = Write-Log -Name "Report_o365groups""Report_Contacts" -Ext csv -folder report 
$hybmaildomain = "@domain.mail.onmicrosoft.com" 
$Collection = @() 
$o365groupsOU = "domain.com/o365Groups" 
$countofchanges = "10" 
 
$email1 = "VikasS@labtest.com" 
$from = "o365GroupWriteBack@labtest.com" 
$smtpserver = "smtpserver" 
 
Start-Transcript -Path $log[0] 
#######Fetch all office 365 groups#### 
try 
{ 
    $o365groups = Get-EOLUnifiedGroup -ResultSize:unlimited | select Alias, DisplayName, Guid, EmailAddresses, PrimarySmtpAddress, RequireSenderAuthenticationEnabled, AccessType, ManagedBy, ManagedByDetails -ErrorAction Stop 
} 
catch 
{ 
    $_ 
    $exception = $_.Exception.Message 
    $date = get-date 
    Add-Content $log[1] "$date - Error Fetching all Unified groups" 
    Add-Content $log[1] $exception 
    Send-Email -From $from -To $email1 -subject "O365 group writeback Error fetching Groups" -smtpserver $smtpserver -body $exception 
    break 
} 
############Fetch All Mail Contacts#### 
try 
{ 
    $o365onpremContacts = Get-MailContact -OrganizationalUnit $o365groupsOU -ResultSize:unlimited | select Alias, DisplayName, CustomAttribute1, EmailAddresses, PrimarySmtpAddress, RequireSenderAuthenticationEnabled -ErrorAction Stop 
} 
catch 
{ 
    $_ 
    $exception = $_.Exception.Message 
    $date = get-date 
    Add-Content $log[1] "$date - Error Fetching all Unified groups" 
    Add-Content $log[1] $exception 
    Send-Email -From $from -To $email1 -subject "O365 group writeback Error fetching Contacts" -smtpserver $smtpserver -body $exception 
    break 
} 
 
if ($o365onpremContacts) 
{ 
    try 
    { 
        ######################Find Additions and Deletions########### 
        $cmpo365groups = $o365groups | select Alias, guid 
        $cmpo365onpremContacts = $o365onpremContacts | select Alias, @{ n = 'guid'; e = { $_.customattribute1 } } 
         
        $Changes = Compare-Object $cmpo365groups $cmpo365onpremContacts -property guid | 
        Select-Object guid, @{ 
            n = 'State'; e = { 
                If ($_.SideIndicator -eq "=>") { "Delete" } 
                elseif ($_.SideIndicator -eq "<=") { "ADD" } 
                else { "Ignore" } 
            } 
        } 
        if ($changes) 
        { 
            $Changes | Export-Csv $report[0] -NoTypeInformation 
        } 
    } 
    catch 
    { 
        $_ 
        $exception = $_.Exception.Message 
        $date = get-date 
        Add-Content $log[1] "$date - Error Finding Changes" 
        Add-Content $log[1] $exception 
        Send-Email -From $from -To $email1 -subject "O365 group writeback Error Finding Changes" -smtpserver $smtpserver -body $exception 
        break 
    } 
 
####Process Changes######### 
    if ($changes) 
    { 
        if ($Changes.count -ge $countofchanges) 
        { 
            Write-Host "Exit as Changes are more than $countofchanges" 
            ProgressBar -Title "Exit as Changes are more than $countofchanges" -Timer 10 
            Send-Email -From $from -To $email1 -subject "O365 group writeback Exit - Changes are more than $countofchanges" -smtpserver $smtpserver 
            Exit 
        } 
        else 
        { 
            $Changes | ForEach-Object{ 
                $uniqueid = $_.guid 
                $getgrp = $o365groups | where{ $_.guid -eq $uniqueid } 
                $getmailcontact = $o365onpremContacts | where{ $_.customattribute1 -eq $uniqueid } 
                $alscontact = $getmailcontact.Alias 
                $Als = $getgrp.Alias 
                $Disp = $getgrp.DisplayName 
                $hybemail = $Als + $hybmaildomain 
                $umeamil = $getgrp.emailaddresses 
                $prim = $getgrp.primarysmtpaddress 
                $sendout = $getgrp.RequireSenderAuthenticationEnabled 
                $mcoll = "" | select Alias, DisplayName, guid, PrimarySmtp, Status 
                if ($_.state -eq "ADD") 
                { 
                    ####ADD the mail.onmicrosft address to Unified group/create Contact#### 
                    Try 
                    { 
                        if ($umeamil -contains "smtp:$hybemail") 
                        { 
                             
                            New-MailContact -Name $Disp -Alias $Als -ExternalEmailAddress $hybemail -OrganizationalUnit $o365groupsOU 
                            ProgressBar -Title "Creating Mail contact $Disp" -Timer 10 
                            while (!(Get-MailContact $Als -ErrorAction SilentlyContinue)) 
                            { 
                                ProgressBar -Title "Creating Mail contact $Disp" -Timer 10 
                            } 
                            Set-MailContact -Identity $Als -RequireSenderAuthenticationEnabled:$sendout -customattribute1:$uniqueid 
                            $chckpem = (get-mailcontact $als).emailaddresses | Select -ExpandProperty addressstring 
                            if ($chckpem -contains $prim) 
                            { 
                                Write-Host "Primary $prim Address is alredy Present in $Als" -ForegroundColor Green 
                            } 
                            else 
                            { 
                                Write-Host "Primary $prim Address will be added to $Als" -ForegroundColor Green 
                                Set-MailContact -Identity $Als -EmailAddresses @{ add = $prim } 
                            } 
                        } 
                        else 
                        { 
                            set-eolunifiedgroup -identity $Als -EmailAddresses @{ add = $hybemail } 
                            New-MailContact -Name $Disp -Alias $Als -ExternalEmailAddress $hybemail -OrganizationalUnit $o365groupsOU 
                            ProgressBar -Title "Creating Mail contact $Disp" -Timer 10 
                            while (!(Get-MailContact $Als -ErrorAction SilentlyContinue)) 
                            { 
                                ProgressBar -Title "Creating Mail contact $Disp" -Timer 10 
                            } 
                            Set-MailContact -Identity $Als -RequireSenderAuthenticationEnabled:$sendout -customattribute1:$uniqueid 
                            $chckpem = (get-mailcontact $als).emailaddresses | Select -ExpandProperty addressstring 
                            if ($chckpem -contains $prim) 
                            { 
                                Write-Host "Primary $prim Address is alredy Present in $Als" -ForegroundColor Green 
                            } 
                            else 
                            { 
                                Write-Host "Primary $prim Address will be added to $Als" -ForegroundColor Green 
                                Set-MailContact -Identity $Als -EmailAddresses @{ add = $prim } 
                            } 
                        } 
                        $mcoll.Alias = $als 
                        $mcoll.DisplayName = $disp 
                        $mcoll.guid = $uniqueid 
                        $mcoll.primarysmtp = $prim 
                        $mcoll.status = "Created" 
                    } 
                    catch 
                    { 
                        $exception = $_.Exception.Message 
                        $date = get-date 
                        Add-Content $log[1] "$date - Exception occured Processing $Disp" 
                        Add-Content $log[1] $exception 
                        Send-Email -From $from -To $email1 -subject "O365 group writeback Exception occured Processing $Disp" -smtpserver $smtpserver -body $exception 
                        $mcoll.Alias = $als 
                        $mcoll.DisplayName = $disp 
                        $mcoll.guid = $uniqueid 
                        $mcoll.primarysmtp = $prim 
                        $mcoll.status = "Error" 
                    } 
                     
                } 
                if ($_.state -eq "Delete") 
                { 
                    try 
                    { 
                        Remove-MailContact -Identity $alscontact -Confirm:$false 
                        $mcoll.Alias = $alscontact 
                        $mcoll.DisplayName = $getmailcontact.DisplayName 
                        $mcoll.guid = $uniqueid 
                        $mcoll.primarysmtp = $getmailcontact.PrimarySMTPAddress 
                        $mcoll.status = "Removed" 
                        ProgressBar -Title "Removing Mail contact $alscontact" -Timer 10 
                    } 
                    catch 
                    { 
                        $exception = $_.Exception.Message 
                        $date = get-date 
                        Add-Content $log[1] "$date - Exception occured deleting $alscontact" 
                        Add-Content $log[1] $exception 
                        Send-Email -From $from -To $email1 -subject "O365 group writeback Exception occured deleting $alscontact" -smtpserver $smtpserver -body $exception 
                        $mcoll.Alias = $alscontact 
                        $mcoll.DisplayName = $getmailcontact.DisplayName 
                        $mcoll.guid = $uniqueid 
                        $mcoll.primarysmtp = $getmailcontact.PrimarySMTPAddress 
                        $mcoll.status = "Error" 
                    } 
                } 
                $Collection +$mcoll 
            } 
        } 
    } 
    if ($Collection) 
    { 
        $Collection | Export-Csv $report[1] -NoTypeInformation 
        Send-Email -From $from -To $email1 -subject "O365 group writeback Report" -smtpserver $smtpserver -attachment $report[1] 
    } 
} 
else 
{ 
    Write-Host "All Contacts will be Created" -ForegroundColor Green 
    try 
    { 
 $o365groups | ForEach-Object{ 
 $Disp = $_.DisplayName
 $Als = $_.Alias
 $hybemail = $Als + $hybmaildomain
 $uniqueid = $_.guid
 $sendout = $_.RequireSenderAuthenticationEnabled
 $prim = $_.primarysmtpaddress
 $umeamil = $_.emailaddresses
 if ($umeamil -notcontains "smtp:$hybemail")
 {
 set-eolunifiedgroup -identity $Als -EmailAddresses @{ add = $hybemail }
 }
            New-MailContact -Name $Disp -Alias $Als -ExternalEmailAddress $hybemail -OrganizationalUnit $o365groupsOU 
            while (!(Get-MailContact $Als -ErrorAction SilentlyContinue)) 
            { 
                ProgressBar -Title "Creating Mail contact $Disp" -Timer 10 
            } 
            Set-MailContact -Identity $Als -RequireSenderAuthenticationEnabled:$sendout -customattribute1:$uniqueid 
            $chckpem = (get-mailcontact $als).emailaddresses | Select -ExpandProperty addressstring 
            if ($chckpem -contains $prim) 
            { 
                Write-Host "Primary $prim Address is alredy Present in $Als" -ForegroundColor Green 
            } 
            else 
            { 
                Write-Host "Primary $prim Address will be added to $Als" -ForegroundColor Green 
                Set-MailContact -Identity $Als -EmailAddresses @{ add = $prim } 
            } 
        } 
         
    } 
    catch 
    { 
        $_ 
        $date = get-date 
        Add-Content $log[1] "$date - Error Creating All Contacts" 
        Add-Content $log[1] $exception 
        Send-Email -From $from -To $email1 -subject "O365 group writeback Error Creating All Contacts" -smtpserver $smtpserver -body $exception 
    } 
     
} 
RemoveEOL 
Stop-Transcript 
############################################################# 

Thanks for Reading

Sukhija Vikas

http://syscloudpro.com

 

 

 

 


Mystery of Dynamic Distribution Lists Exchange Hybrid

$
0
0

Today, I am sharing a situation where we had to tweak the Hybrid solution to make existing Dynamic Distribution lists utilized in one of the customer Environment.

As office 365/Exchange online administrators, We all know that Dynamic Distributions lists are not synchronized via AAD synchronization or you can say not supported, either you have to create the Dynamic DLs in the cloud environment or create a mail contact for each dynamic DLs and point it to on-premise DLs.

Creation of Dynamic Distribution Lists on Exchange online is not always an option if your Dynamic Lists are based on Non Filterable Attributes.

We need to Create Mail Contacts for all Dynamic Distribution Lists in the online environment but that has not resolved the mail routing issues because Customer was not directly using the Dynamic Distribution lists & was nesting these under the Normal Distribution groups.

So when these Normal groups are synchronized with cloud, their members are null and email sent to them land no where.

Here are the mitigation steps that We have done & will be valid for majority of Customers facing the above issue:

This Step will include the Remote Mailboxes (mailboxes that have been moved to Exchange Online)

capture

  • Create Mail contacts for each Dynamic Distribution List in Exchange Online environment.

capture

Both of the steps are widely known & documented on various blogs, here are the extra steps that we have performed to mitigate the issue in this particular case.

  • Move the Normal Distribution groups that have nested dynamic Lists to Do Not Sync OU (Create OU that will unchecked for Sync) inside Azure Active Directory Synchronization.

capture

  • Create the Normal Distribution groups with Same Name in Exchange Online.
  • ADD the Legacy Exchange DN address(extract from OnPremise DL) to Normal DL in online.

capture

  • Nest the Created Mail Contacts(Created for Dynamic Distribution lists) to the Normal Distribution List Created Online.

When above is followed -> Migrated users can use the same experience for Dynamic Distributions groups as he/She was having when account was On-premise. I will be sharing the other similar situations along with the solutions in future posts 🙂

Thanks for Reading

Sukhija Vikas

http://SysCloudPro.com


Stellar Exchange Toolkit

$
0
0

Today lets get our hands dirty on one of the Vendor software Stellar Exchange Toolkit“. Initial thoughts after looking at the software was that its handy & cost effective (single software is compatible with all the versions of exchange starting from 2003)

It boasts below features:

  • Stellar Phoenix Mailbox Exchange Recovery
  • Stellar Mailbox Extractor for Exchange Server
  • Stellar OST to PST Converter
  • Stellar Mailbox Extractor for Exchange Backup
  • Stellar Phoenix Password Recovery for MS Exchange

There are other software in the market as well that does similar things & these all need to redesign/innovate their programs as more customers are choosing o365  and moving away from Exchange.

For this blog lets concentrate on Stellar Exchange Toolkit with its advantages & disadvantages:

giphy

Pros:

  • Easy installation with familiar look & feel.

capture

  • Haven’t asked for any additional requirements
  • GUI design is Simple & self explanatory

capture

  • Tested mailbox extractor from offline edb & it does what it says.capture
  • Option of adding multiple EDBs
  • Option for connecting online for extracting mailboxes (only offline is available in many other softwares)
  • Extract/Export the emails in multiple file formats

capture

  • Winner of msexchange.org award.

Cons:

  • Data extraction taking bit of time as compare with other software I have tested.

On the whole its a simple software,easy to use & economical for Exchange organizations, one simple life time license validity with single pricing model.

For more detailed information refer to product website: https://www.stellarinfo.com/email-tools/exchange-toolkit/buy-now.php

Regards

Sukhija Vikas

http://SysCloudPro.com

 


Shared Mailbox Creation

$
0
0

Sharing a script that we have written to create Shared mailboxes. You can customize it as per your needs.

This script is a great example of using DSMOD/DSADD in powershell.

It does plenty of things , many of these are dependent on the process used in the enviornment so this can act as a sample code.

  • Check if mailbox already exists (if exists, script will exit)
  • Create Shared mailbox
  • Update Notes section with owner details in shared mailbox
  • Update the standard Description: Disabled Window Resource Account-Mailbox
  • Update Custom attribute10 to None
  • Create Full Access group
  • Create Send As group
  • Update Description for Full Access group
  • Update Description for Send As Access group
  • Update members of Full Access group
  • Update members of Send As Access group
  • Apply Full Access permissions to Full Access group
  • Apply Sendas Access permissions to SendAs Access group
  • Nest Sendas group in full access Group

To achieve all of this above you need to prepare the CSV file first:

  • CSV name should always be MailboxDetails.csv & to be placed at the root before execution.

Fields in CSV file (Avoid spaces)

MailboxName – Avoid special characters like & , @ etc. 

AliasName – No spaces in between words Example: India Test  is invalid but IndiaTest is valid

PriOwner – ADD single Samaccountname

SecOwner – ADD single Samaccountname

FullAccess – Add multiple “Samaccountname” names separated by coma

SMMBXOU – Organizational Unit can have below values depending on the region (In this OU shared mailboxes will be placed)

OU=Resource,OU=EUROPE,DC=labtest,DC=com

GroupsOU – Organizational Unit can have below values depending on the region (In this OU groups will be placed)

OU=Groups,OU=EUROPE,DC=labtest,DC=com

Note: Exchange2010 Shell/ DS utilities are required for Succesful execution

Download & extract the solution from below link:(Example CSV is already presnt in side it)

https://gallery.technet.microsoft.com/scriptcenter/Shared-Mailbox-Creation-47254b39

Update the below variables & you are good to execute the batch file 🙂

$Dom = “@labtest.com”
$email1 = “VikasS@labtest.com”, “PrabhatT@labtest.com”

$from = “SharedMailboxCreation@labtest.com”

$smtpserver = “SMTP server”

 

PowerShell
<#     
    .NOTES 
    =========================================================================== 
     Created on:       11/27/2016  
     Reviewed on:   12/27/2016 
     Created by:       Prabhat Tiwari/Vikas Sukhija 
     Reviewed by:   Vikas Sukhija (http://syscloudpro.com) 
     Organization:      
     Filename:         NewSharedMailBox.ps1 
    =========================================================================== 
    .DESCRIPTION 
        This script will take inputs from CSV file & will create the Shared mailbox 
        along with full access/ send as groups and providing them appropriate permissions. 
#> 
$error.clear() 
##################Load Modules############### 
If ((Get-PSSnapin | where { $_.Name -match "Microsoft.Exchange.Management.PowerShell.E2010" }) -eq $null) 
{ 
    Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010 
} 
############################Logs ############### 
$date1 = get-date -format d 
$date1 = $date1.ToString().Replace("/""-"$time = get-date -format t 
 
$time = $time.ToString().Replace(":""-"$time = $time.ToString().Replace(" """) 
 
$log = (Get-Location).Path + "\Logs" + "\" + "Processed_SHDMBX_" + $date1 + "_" + $time + "_.log" 
$report1 = (Get-Location).Path + "\Report" + "\" + "Report_SHDMBX_" + $date1 + "_" + $time + "_.csv" 
$report2 = (Get-Location).Path + "\Logs" + "\" + "CSV_Created" + $date1 + "_" + $time + "_.csv" 
 
$limit = (Get-Date).AddDays(-60) #for report recycling 
$path1 = (Get-Location).Path + "\Logs" 
$path2 = (Get-Location).Path + "\Report" 
 
################Variables#################### 
$UserList = Import-Csv ".\MailboxDetails.csv" | where{ $_.MailboxName -ne "" } 
$description = "Disabled Window Resource Account-Mailbox" 
$Dom = "@labtest.com" 
 
$email1 = "VikasS@labtest.com""PrabhatT@labtest.com" 
$from = "SharedMailboxCreation@labtest.com" 
$smtpserver = "SMTP server" 
 
$collection = @() 
 
Copy-Item ".\MailboxDetails.csv" $report2 
#############Load Functions################ 
################Email Function##################### 
 
function Send-Email 
{ 
    [CmdletBinding()] 
    param 
    ( 
        $From, 
        [array]$To, 
        [array]$bcc, 
        [array]$cc, 
        $body, 
        $subject, 
        $attachment, 
        $smtpserver 
    ) 
    $message = new-object System.Net.Mail.MailMessage 
    $message.From = $from 
    if ($To -ne $null) 
    { 
        $To | ForEach-Object{ 
            $to1 = $_ 
            $to1 
            $message.To.Add($to1) 
        } 
    } 
    if ($cc -ne $null) 
    { 
        $cc | ForEach-Object{ 
            $cc1 = $_ 
            $cc1 
            $message.CC.Add($cc1) 
        } 
    } 
    if ($bcc -ne $null) 
    { 
        $bcc | ForEach-Object{ 
            $bcc1 = $_ 
            $bcc1 
            $message.bcc.Add($bcc1) 
        } 
    } 
    $message.IsBodyHtml = $True 
    if ($subject -ne $null) 
    { 
        $message.Subject = $Subject 
    } 
    if ($attachment -ne $null) 
    { 
        $attach = new-object Net.Mail.Attachment($attachment) 
        $message.Attachments.Add($attach) 
    } 
    if ($body -ne $null) 
    { 
        $message.body = $body 
    } 
    $smtp = new-object Net.Mail.SmtpClient($smtpserver) 
    $smtp.Send($message) 
} 
################################################### 
function ProgressBar 
{ 
    [CmdletBinding()] 
    param 
    ( 
        $Title 
    ) 
    For ($i = 1; $i -le "10"$i++) 
    { 
        Start-Sleep 1; 
        Write-Progress -Activity $Title -status "$i" -percentComplete ($i /10 * 100) 
    } 
} 
 
#############################Loaded Functions###### 
if ($error) { ProgressBar -title "Exiting - error loading modules/functions"exit } 
 
Start-Transcript -Path $log 
##########Import the values from CSV file ########## 
 
foreach ($User in $UserList) 
{ 
    $SharedMailboxName = $User.MailboxName 
    $SharedMailboxName = $SharedMailboxName.trim() 
    $SharedMailboxAlias = $User.AliasName 
    $SharedMailboxAlias = $SharedMailboxAlias.trim() 
    $POwner = $User.PriOwner 
    $POwner = $POwner.trim() 
    $SOwner = $User.SecOwner 
    $FullAccess = $user.FullAccess 
    $FullAccess = $FullAccess.trim() 
    $Users = $FullAccess.Split(",") 
    $SMMBXOU = $User.SMMBXOU 
    $GroupsOU = $User.GroupsOU 
     
    $FGroup = "FullAccess-" + $SharedMailboxAlias 
    $SGroup = "SendAs-" + $SharedMailboxAlias 
    $UPN = $SharedMailboxAlias + $Dom 
     
    if ($SOwner) 
    { 
        $SOwner = $SOwner.trim() 
        $Owner = "Primary Owner : " + $POwner + ", " + " BUO : " + $SOwner 
    } 
    Else 
    { 
        $Owner = "Primary Owner : " + $POwner 
    } 
     
    $mcoll = "" | select Name, Processed, AlreadyExists, Created, Notes, Description, CustomAttribute10, FullAccessGroup, SendASAccessGroup, FullaccesGrpDesc, SendAsAccessGrpDesc, FullAccessGroupmem, FullAccessGroupInvalidmembers, SendASAccessGroupMem, SendASAccessGroupInvalidmembers, FullaccessPermission, SendasPermission, Nesting 
    $mcoll.Name = $SharedMailboxName 
     
    if ($error) 
    { 
        ProgressBar -title "$user will not be processed" 
        $mcoll.Processed = "Error" 
    } 
    else 
    { 
        $mcoll.Processed = "Processed" 
        #####Check if mailbox already exists############ 
         
        if ((Get-Mailbox $SharedMailboxName -ErrorAction SilentlyContinue) -or (Get-Mailbox $SharedMailboxAlias -ErrorAction SilentlyContinue)) 
        { 
            ProgressBar -Title "Mailbox $SharedMailboxName Already exits" 
            $mcoll.AlreadyExists = "Yes" 
        } 
        else #############Create Shared mailbox################### 
        { 
            $mcoll.AlreadyExists = "No" 
            $Error.clear() 
            New-Mailbox -Name:$SharedMailboxName -UserPrincipalName:$UPN -Alias:$SharedMailboxAlias -OrganizationalUnit $SMMBXOU -Shared 
            if ($Error) 
            { 
                Write-Host "Error creating Shared mailbox" -ForegroundColor yellow 
                $mcoll.Created = "Error" 
            } 
            else 
            { 
                 
                while (!(Get-User $SharedMailboxAlias -ErrorAction SilentlyContinue)) 
                { 
                    ProgressBar -Title "Creating Shared mailbox $SharedMailboxAlias" 
                } 
                ProgressBar -Title "Creating Shared mailbox $SharedMailboxAlias" 
                ProgressBar -Title "Creating Shared mailbox $SharedMailboxAlias" 
                $mcoll.Created = "Created" 
                ############Update the Notes & Description############ 
                ProgressBar -Title "Wait for Few Seconds" 
                $getsmx = Get-User $SharedMailboxAlias 
                if ($getsmx) 
                { 
                    $Error.clear() 
                    Set-User -Notes $Owner -Identity $getsmx.SamAccountName 
                    if ($Error) 
                    { 
                        Write-Host "Error Updating notes for Shared mailbox" -ForegroundColor yellow 
                        $mcoll.Notes = "Error" 
                        $Error.clear() 
                    } 
                    else 
                    { 
                        Write-Host "Updating notes for $SharedMailboxAlias" -ForegroundColor Green 
                        $mcoll.Notes = "Success" 
                    } 
                    $dn = $getsmx.DistinguishedName 
                    $dm = $null 
                    $dm = dsmod user $dn -desc $description 2>&1 
                    if ($dm -like "*dsmod succeeded*") 
                    { 
                        Write-Host "Updating Description for $SharedMailboxAlias" -ForegroundColor Green 
                        $mcoll.Description = "Updated" 
                    } 
                    else 
                    { 
                        Write-Host "Updating Description for $SharedMailboxAlias - Failed" -ForegroundColor yellow 
                        $mcoll.Description = "Failed" 
                    } 
                    $Error.clear() 
                    Set-Mailbox -CustomAttribute10 "NONE" -Identity $getsmx.SamAccountName 
                    if ($Error) 
                    { 
                        Write-Host "Error Updating CustomAttribute10 for $SharedMailboxAlias" -ForegroundColor yellow 
                        $mcoll.CustomAttribute10 = "Error" 
                        $Error.clear() 
                    } 
                    else 
                    { 
                        Write-Host "Updating CustomAttribute10 for $SharedMailboxAlias" -ForegroundColor Green 
                        $mcoll.CustomAttribute10 = "Success" 
                    } 
                    ##########Create Groups and update members###################### 
                    $fgpname = "CN=$FGroup,$GroupsOU" 
                    $dm = $null 
                    $dm = dsadd group $fgpname 2>&1 
                    if ($dm -like "*dsadd succeeded*") 
                    { 
                        Write-Host "Group $fgpname Created" -ForegroundColor Green 
                        $mcoll.FullAccessGroup = "Created" 
                        ProgressBar -Title "Creating $fgpname" 
                        ProgressBar -Title "Creating $fgpname" 
                        $dm = $null 
                        $dm = dsmod group $fgpname -desc "Full Access on :-  $SharedMailboxName" 2>&1 
                        if ($dm -like "*dsmod succeeded*") 
                        { 
                            $mcoll.FullaccesGrpDesc = "Updated Description" 
                        } 
                        else 
                        { 
                            $mcoll.FullaccesGrpDesc = "Failed Description" 
                            $dm 
                        } 
                        #########Add members############# 
                        $userdn = @() 
                        foreach ($Usr in $Users) 
                        { 
                            $Us = Get-User $Usr 
                            $userdn +$Us.distinguishedName 
                        } 
                        if ($error) 
                        { 
                            $mcoll.FullAccessGroupInvalidmembers = "Error" 
                        } 
                        else 
                        { 
                            $mcoll.FullAccessGroupInvalidmembers = "No" 
                        } 
                        $Error.clear() 
                        $dm = $null 
                        $dm = dsmod group $fgpname -addmbr $userdn 2>&1 
                        if ($dm -like "*dsmod succeeded*") 
                        { 
                            $mcoll.FullAccessGroupmem = "Members Added" 
                        } 
                        else 
                        { 
                            $mcoll.FullAccessGroupmem = "Failed Members Addition" 
                            $dm 
                        } 
                        ################Add Permissions to mailbox######## 
                        $Error.clear() 
                        ADD-MailboxPermission -identity $getsmx.SamAccountName -User $fgpname -AccessRights FullAccess -AutoMapping $false 
                        if ($Error) 
                        { 
                            Write-Host "Error Updating FullaccessPermission for $SharedMailboxAlias" -ForegroundColor yellow 
                            $mcoll.FullaccessPermission = "Error" 
                            $Error.clear() 
                        } 
                        else 
                        { 
                            Write-Host "Updating FullaccessPermission for $SharedMailboxAlias" -ForegroundColor Green 
                            $mcoll.FullaccessPermission = "Success" 
                        } 
                    } 
                    else 
                    { 
                        Write-Host "Group $fgpname Creation - Failed" -ForegroundColor yellow 
                        $mcoll.FullAccessGroup = "CreationFailed" 
                        $mcoll.FullaccesGrpDesc = "CreationFailed" 
                        $mcoll.FullAccessGroupmem = "CreationFailed" 
                        $mcoll.FullaccessPermission = "CreationFailed" 
                        $dm 
                    } 
                    ############################################ 
                    $sgpname = "CN=$SGroup,$GroupsOU" 
                    $dm = $null 
                    $dm = dsadd group $sgpname 2>&1 
                    if ($dm -like "*dsadd succeeded*") 
                    { 
                        Write-Host "Group $sgpname Created" -ForegroundColor Green 
                        $mcoll.SendASAccessGroup = "Created" 
                        ProgressBar -Title "Creating $sgpname" 
                        ProgressBar -Title "Creating $sgpname" 
                        $dm = $null 
                        $dm = dsmod group $sgpname -desc "Send Access on :-  $SharedMailboxName" 2>&1 
                        if ($dm -like "*dsmod succeeded*") 
                        { 
                            $mcoll.SendAsAccessGrpDesc = "Updated Description" 
                        } 
                        else 
                        { 
                            $mcoll.SendAsAccessGrpDesc = "Failed Description" 
                            $dm 
                        } 
                        #########Add members############# 
                        $userdn = @() 
                        foreach ($Usr in $Users) 
                        { 
                            $Us = Get-User $Usr 
                            $userdn +$Us.distinguishedName 
                        } 
                        if ($error) 
                        { 
                            $mcoll.SendASAccessGroupInvalidmembers = "Error" 
                        } 
                        else 
                        { 
                            $mcoll.SendASAccessGroupInvalidmembers = "No" 
                        } 
                        $Error.clear() 
                        $dm = $null 
                        $dm = dsmod group $sgpname -addmbr $userdn 2>&1 
                        if ($dm -like "*dsmod succeeded*") 
                        { 
                            $mcoll.SendASAccessGroupMem = "Members Added" 
                        } 
                        else 
                        { 
                            $mcoll.SendASAccessGroupMem = "Failed Members Addition" 
                            $dm 
                        } 
                        #########Nest the group to Full access group##### 
                        $dm = $null 
                        $dm = dsmod group $fgpname -addmbr $sgpname 2>&1 
                        if ($dm -like "*dsmod succeeded*") 
                        { 
                            $mcoll.Nesting = "Nested" 
                        } 
                        else 
                        { 
                            $mcoll.Nesting = "Nesting Failed" 
                            $dm 
                        } 
                        ################Add Permissions to mailbox######## 
                        $Error.clear() 
                        $mbx = Get-Mailbox -id $getsmx.SamAccountName 
                        $mbx | Add-ADPermission -User $sgpname -Extendedrights "Send As" 
                        if ($Error) 
                        { 
                            Write-Host "Error Updating SendasPermission for $SharedMailboxAlias" -ForegroundColor yellow 
                            $mcoll.SendasPermission = "Error" 
                            $Error.clear() 
                        } 
                        else 
                        { 
                            Write-Host "Updating SendasPermission for $SharedMailboxAlias" -ForegroundColor Green 
                            $mcoll.SendasPermission = "Success" 
                        } 
                    } 
                    else 
                    { 
                        Write-Host "Group $sgpname Creation - Failed" -ForegroundColor yellow 
                        $mcoll.SendASAccessGroup = "CreationFailed" 
                        $mcoll.SendAsAccessGrpDesc = "CreationFailed" 
                        $mcoll.SendASAccessGroupMem = "CreationFailed" 
                        $mcoll.SendasPermission = "CreationFailed" 
                        $mcoll.Nesting = "CreationFailed" 
                        $dm 
                    }     
                     
                } 
                else 
                { 
                    Write-Host "not able to find $SharedMailboxAlias" -ForegroundColor Yellow 
                    $mcoll.Notes = "Mailbox not found" 
                    $mcoll.Description = "Mailbox not found" 
                    $mcoll.CustomAttribute10 = "Mailbox not found" 
                    $mcoll.FullAccessGroup = "Mailbox not found" 
                    $mcoll.FullaccesGrpDesc = "Mailbox not found" 
                    $mcoll.SendASAccessGroup = "Mailbox not found" 
                    $mcoll.SendAsAccessGrpDesc = "Mailbox not found" 
                    $mcoll.FullAccessGroupmem = "Mailbox not found" 
                    $mcoll.SendASAccessGroupMem = "Mailbox not found" 
                    $mcoll.SendasPermission = "Mailbox not found" 
                    $mcoll.FullaccessPermission = "Mailbox not found" 
                     
                } 
            } 
        } 
    } 
    $collection +$mcoll 
} 
if ($collection) 
{ 
    $collection | Export-Csv $report1 -NoTypeInformation 
    Send-Email -From $from -To $email1 -subject "Shared Mailbox Creation" -attachment $report1 -smtpserver $smtpserver 
} 
##################Recycle logs#################### 
Get-ChildItem -Path $path1 | Where-Object { 
    $_.CreationTime -lt $limit 
} | Remove-Item -recurse -Force 
 
Get-ChildItem -Path $path2 | Where-Object { 
    $_.CreationTime -lt $limit 
} | Remove-Item -recurse -Force 
 
get-date 
Stop-Transcript 
 
##################################################################
Thanks for Reading
 Sukhija Vikas
 http://SysCloudPro.com

Auto Reply multiple Users

$
0
0

Sharing a script that I created recently while working on a project where the requirement was to set auto reply for hundereds of users.

We need to notify their future address & also want that sender should know that old address is no longer monitored.

This can be achieved by creating a CSV file with just two columns:

PreviousEmail,FutureEmail

Download & extract the solution from below link(update .ps1)

https://gallery.technet.microsoft.com/scriptcenter/Auto-Reply-multiple-Users-840c2a35

Update Start & End date for OOO reply

$start = “1/3/2017”

$end = “1/3/2018”

Update the message that should be sent:

$ooomessage = @”

Please contact me at my new email address, $femail. Also note my $pemail account is no longer monitored.

“@

Now Just open the Exchange management shell , change directory to script & run the script as

OOO.ps1 .\merger.csv

Note: Script requires Exchnage managemnt Shell & was tested with 2010.

 

<#     
    .NOTES 
    =========================================================================== 
     Created on:       3/29/2017 1:55 PM 
     Created by:       sukhijv 
     Organization:      
     Filename:         OOO.ps1 
    =========================================================================== 
    .DESCRIPTION 
        Setup ooo for Users from CSV File by reading old address & New address 
#> 
########################Functions ################################### 
function Write-Log 
{ 
    [CmdletBinding()] 
    param 
    ( 
        [Parameter(Mandatory = $true)] 
        [array]$Name, 
        [Parameter(Mandatory = $true)] 
        [string]$Ext, 
        [Parameter(Mandatory = $true)] 
        [string]$folder 
    ) 
     
    $log = @() 
    $date1 = get-date -format d 
    $date1 = $date1.ToString().Replace("/""-") 
    $time = get-date -format t 
     
    $time = $time.ToString().Replace(":""-") 
    $time = $time.ToString().Replace(" """) 
     
    foreach ($n in $name) 
    { 
         
        $log += (Get-Location).Path + "\" + $folder + "\" + $n + "_" + $date1 + "_" + $time + "_.$Ext" 
    } 
    return $log 
} 
$log = Write-Log -Name "log1""log2" -Ext log -folder Logs 
Start-Transcript -Path $log[0] 
##########################Import CSv & ADD OOO######################## 
$start = "1/3/2017" 
$end = "1/3/2018" 
$data = Import-Csv $args 
foreach ($i in $data) 
{ 
    $pemail = $i.previousEmail 
    $pemail = $pemail.trim() 
    $femail = $i.futureemail 
    $femail = $femail.trim() 
    $ooomessage = @" 
Please contact me at my new email address, $femail. Also note my $pemail account is no longer monitored. 
"@ 
    Write-Host $ooomessage -ForegroundColor Green 
    if (get-mailbox $pemail -ea silentlycontinue) 
    { 
        Try 
        { 
            Set-MailboxAutoReplyConfiguration -identity $pemail -AutoReplyState Scheduled -StartTime $start -endtime $end -InternalMessage $ooomessage –ExternalMessage $ooomessage -ExternalAudience:All 
            Write-Host "Processing...................... $pemail" -ForegroundColor Green 
        } 
        catch 
        { 
            Write-Host "exception occured Processing $pemail" -ForegroundColor Yellow 
            $_.Exception.Message 
        } 
    } 
    else 
    { 
        Write-Host "$pemail mailbox not found" -ForegroundColor RED 
    } 
} 
Stop-Transcript 
######################################################################
Thanks for reading
Sukhija Vikas

 



Export PST for multiple users from Particular Folder

$
0
0

Sharing this script that can be used in case of mergers/seprations where you need to export data from multiple users mailboxes.

It reads the input from CSV file — email & networkid(samaccount name), run against exchange 2010 & export the users data from particular folder (transfer) to the share you have set as well name the pst based on network ids.

After downloading the script zip from below link, Please update below values according to your requirement.

https://gallery.technet.microsoft.com/scriptcenter/Export-PST-for-multiple-663ccae7

$exportfolder = “transfer”

$location = “\\Server\e$\Merger\PST”

To run the script just open exchange Shell, cd to the script directory.

Execute as –> .\MergerExportPst.ps1 .\merger.csv

What script is doing is importing the data from csv , forming the name of pst in $path variable

    $pemail = $i.Previousemail 
    $pemail = $pemail.trim() 
    $networkid = $i.Networkid 
    $networkid = $networkid.trim() 
    $path = $location + "\" + $networkid + ".pst" 

Executing the  NewMailboxExportRequest to export the data from a particular folder.(catching any exceptions using Try/Catch)

New-MailboxExportRequest -Mailbox $pemail -IncludeFolders $exportfolder/* -filepath $path -ExcludeDumpster   

 

PowerShell
<#     
    .NOTES 
    =========================================================================== 
     Created on:       3/31/2017 9:04 AM 
     Created by:       sukhijv 
     Organization:      
     Filename:         MergerExportPst.ps1 
    =========================================================================== 
    .DESCRIPTION 
        This script will export the PST files for list of suers. 
        Folder with name transfer would be extracted 
#> 
######################Functions######################## 
Function Write-Log 
{ 
    [CmdletBinding()] 
    param 
    ( 
        [Parameter(Mandatory = $true)] 
        [array]$Name, 
        [Parameter(Mandatory = $true)] 
        [string]$Ext, 
        [Parameter(Mandatory = $true)] 
        [string]$folder 
    ) 
     
    $log = @() 
    $date1 = get-date -format d 
    $date1 = $date1.ToString().Replace("/""-") 
    $time = get-date -format t 
     
    $time = $time.ToString().Replace(":""-") 
    $time = $time.ToString().Replace(" """) 
     
    foreach ($n in $name) 
    { 
         
        $log += (Get-Location).Path + "\" + $folder + "\" + $n + "_" + $date1 + "_" + $time + "_.$Ext" 
    } 
    return $log 
} 
$log = Write-Log -Name "log1""log2" -Ext log -folder Logs 
Start-Transcript -Path $log[0] 
##########################Import CSv & START EXPORT################ 
$exportfolder = "transfer" 
$location = "\\Server\e$\Merger\PST" 
$data = Import-Csv $args 
foreach ($i in $data) 
{ 
    $pemail = $i.Previousemail 
    $pemail = $pemail.trim() 
    $networkid = $i.Networkid 
    $networkid = $networkid.trim() 
    $path = $location + "\" + $networkid + ".pst" 
    try 
    { 
        Write-Host "Processing...........$pemail................$networkid" -ForegroundColor Green 
        New-MailboxExportRequest -Mailbox $pemail -IncludeFolders $exportfolder/* -filepath $path -ExcludeDumpster     
    } 
    catch 
    { 
        Write-Host "Exception has occured processing $pemail....$networkid" -ForegroundColor Yellow 
        $_.Exception.Message 
    } 
} 
Stop-Transcript 
######################################################################

 

Thanks for reading

Sukhija Vikas

http://SysCloudPro.com


Use EVPM to disable multiple archives

$
0
0

Sharing a method that can be used when you are doing office 365 migrations & you want to disable /ZAP multiple archives.

Disabling the archives using GUI method is cumbersome & can take a lot of time.

We are running the EVPM command manually but you can schedule it as well.

For running the EVPM script command you need the following:

  • ini file that has multiple legacy DNs
  • Exchange mailbox server Name
  • Enterprise vault directory server
  • Enterprise Vault Site name
  • System Mailbox

For Disabling Archives below are the INI contents :


; DirectoryComputerName, add the simple name of the EV server where you will run this script.
; SiteName is the name of the site as it appears in the VAC.

[Directory]
DirectoryComputerName = EVServer1
SiteName = EVSITE

; Use the Distinguished Name of the mailbox to be zapped. You can get this by running the archiving task in report mode for that mailbox and viewing the resulting report.

[Mailbox]
DistinguishedName=/o=Labtest/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=User1
DistinguishedName=/o=Labtest/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=User2

[Folder]
Name = MailboxRoot
Enabled = False


For Zap below are the INI contents:


; DirectoryComputerName, add the simple name of the EV server where you will run this script.
; SiteName is the name of the site as it appears in the VAC.

[Directory]
DirectoryComputerName = EVServer1
SiteName = EVSITE

; Use the Distinguished Name of the mailbox to be zapped. You can get this by running the archiving task in report mode for that mailbox and viewing the resulting report.

[Mailbox]
DistinguishedName=/o=Labtest/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=User1
DistinguishedName=/o=Labtest/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=User2

[Folder]
Name = MailboxRoot
Zap = TRUE


After saving the ini file you can run the below commands on EV server from command prompt.

EVPM cmd resides inside the EnterpriseVault installation path(change to that directory inside command prompt)

\Program Files (x86)\Enterprise Vault

EVPM.EXE -e “Exchange Mailbox server ” -m “EV system Mailbox” -f C:\EVPM\EV_Disabled.ini

EVPM.EXE -e “Exchange Mailbox server ” -m “EV system mailbox” -f C:\EVPM\EV_ZAP.ini

You wll also need EV system mailbox that you have used in the archive task(See below)

You now have all the information & can do ZAP or disable for multiple user mailboxes.

Disable will disable user account in EV so that no further operations can be performed by the user,

ZAP will remove the Enterprisevault properties from user mailbox.

Note: We have used this process with version 9 & think that this will work with other versions as well.

Thanks for reading

Sukhija Vikas

http://SysCloudPro.com

 


Bulk Room Mailboxes Creation

$
0
0

Sharing a Script that you can use in your environment to streamline rooms creation process.

What script does is take the input from CSV file & than do below:

  • Create Exchange account
  • Modify AD account
  • Create a Universal Distribution List Group(s) for Restricted Conference Rooms
  • Apply Calendar Permissions
  • Apply auto accept settings

Here is the process that needs to be followed up.(enviornment specific, modify as per your enviornment)

Copy the Example Restricted or Unrestricted Room file based on the request, Paste it under ROOT of the script folder

Restricted Rooms: Not open to All, restricted to certain groups

  • Open the Excel file Named confroomauto-Res.xlsx update the attributes

Name (Mandatory Attribute): SIte ConRoom 1-2-3 (VC) (Restricted)  — “<Site> ConRm <building number>- <floor number>-<room name>”  –(VC) –Video conference Room

SamaccountName (Mandatory Attribute): conSiteconrm123 — Full name with no spaces or special characters, “Con” in front of the name stands for Confrence room account

OU(Mandatory Attribute): Labtest.com/Exchange/Conroom –Select from Active Directory

Office: LCD  

               Title: Capacity 12 

               Company: Video Conference 

Telephone: 651-333-1234 (x21234) —  Be sure to include the extension in parenthesis 

Restricted(Mandatory Attribute): Yes 

ResOU:  Labtest.com/Exchange/DistributionLists –Select from Active DirectoryIf Restricted is Yes than this field is mandatory 

OwnerGroup: GroupCon Site ConRm 1-2-3 Owner  “GroupCon <Site> ConRm <building number>- <floor number>-<room name> Owner” If Restricted is Yes than this field is mandatory 

AuthorGroup: GroupCon Site ConRm 1-2-3 Author “GroupCon <Site> ConRm <building number>- <floor number>-<room name> Author” If Restricted is Yes than this field is mandatory

PrimaryOwnerGrp: user1owner of the groups that will be created– Networkids

SecondaryOwnerGrp: User2,user3, — Backup owner of the groups that will be created , note coma after each id – Networkids  

Notes(Mandatory Attribute):

AVAILABLE EQUIPMENT/CAPACITY
Scheduling Contact: Steve Jobs
Capacity 10
LCD
Video Conference
Telephone 651-333-1234 (x21234)
Owner: Bill Gates

Unrestricted Rooms: Open to All, Anyone can Book

  • Open the Excel file Named confroomauto-UNRes.xlsx update the attributes

Name (Mandatory Attribute):SIte ConRoom 1-2-3 (VC) or SIte ConRoom 1-2-3 — “<Site> ConRm <building number>- <floor number>-<room name>”  –(VC) –Video conference Room

SamaccountName (Mandatory Attribute):  conSiteconrm123 — Full name with no spaces or special characters, “Con” in front of the name stands for Confrence room account

OU(Mandatory Attribute): Labtest.com/Exchange/Conroom –Select from Active Directory

Office: LCD  

               Title: Capacity 12 

               Company: Video Conference 

Telephone: 651-123-1234 (x21234) — Be sure to include the extension in parenthesis 

Restricted(Mandatory Attribute): No 

ResOU: NA 

OwnerGroup: NA 

AuthorGroup: NA

PrimaryOwnerGrp: NA

SecondaryOwnerGrp: NA  

Notes(Mandatory Attribute):

AVAILABLE EQUIPMENT/CAPACITY
Scheduling Contact: Steve Jobs
Capacity 10
LCD
Video Conference
Telephone 651-123-1234 (x21234)
Owner: Bill Gates

Now save the Excel File as CSV & run the batch file /enter the csv file. (download the solution zip from below link)

https://gallery.technet.microsoft.com/scriptcenter/Bulk-Room-Mailboxes-340a8426

Script will create restricted or unrestricted room based on the input.

For unresticted room two groups will be created that will have author/owner permissions on the room calendar and these are only allowed to book the room.

This restriction is controlled by using room settings such as bookinPolicy.

if you will check the Resource In-Policy request tab of restricted room after creation in exchange console , you will find those groups listed.


Changes inside the script:

$email1 = “Reporting@labtest.com”

$from = “ConRmMailboxCreation@labtest.com”

$smtpserver = “smtp.labtest.com”

———————–

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://ExchangeServer.labtest.com/PowerShell/ -Authentication Kerberos

———————–

$UserPrincipalName = $samaccountname + “@” + “labtest.com”

Here is the code:

PowerShell
########################################################################### 
#        Author: Vikas Sukhija 
#        Date: 12/11/2015 
#        Modified: 12/14/2015 
#           Upadted: Included Groups & owners as well 
#        Reviewer: 
#        Description: Create Room mailbox Accounts for Confrence Rooms 
############################################################################ 
########################### Add Exchange Shell############################## 
param ( 
    $csv$error.clear() 
$csv = Read-Host "Please enter csv file" 
 
$email1 = "Reporting@labtest.com" 
$from = "ConRmMailboxCreation@labtest.com" 
$smtpserver = "smtp.labtest.com" 
 
################Email Function##################### 
 
function Send-Email 
{ 
    [CmdletBinding()] 
    param 
    ( 
        $From, 
        [array]$To, 
        [array]$bcc, 
        [array]$cc, 
        $body, 
        $subject, 
        $attachment, 
        $smtpserver 
    ) 
    $message = new-object System.Net.Mail.MailMessage 
    $message.From = $from 
    if ($To -ne $null) 
    { 
        $To | ForEach-Object{ 
            $to1 = $_ 
            $to1 
            $message.To.Add($to1) 
        } 
    } 
    if ($cc -ne $null) 
    { 
        $cc | ForEach-Object{ 
            $cc1 = $_ 
            $cc1 
            $message.CC.Add($cc1) 
        } 
    } 
    if ($bcc -ne $null) 
    { 
        $bcc | ForEach-Object{ 
            $bcc1 = $_ 
            $bcc1 
            $message.bcc.Add($bcc1) 
        } 
    } 
    $message.IsBodyHtml = $True 
    if ($subject -ne $null) 
    { 
        $message.Subject = $Subject 
    } 
    if ($attachment -ne $null) 
    { 
        $attach = new-object Net.Mail.Attachment($attachment) 
        $message.Attachments.Add($attach) 
    } 
    if ($body -ne $null) 
    { 
        $message.body = $body 
    } 
    $smtp = new-object Net.Mail.SmtpClient($smtpserver) 
    $smtp.Send($message) 
} 
################################################### 
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://ExchangeServer.labtest.com/PowerShell/ -Authentication Kerberos 
import-pssession $session 
 
if ($Error) 
{ 
    Write-Host "CSV Parameter incorrect ---Script will exit" -ForegroundColor Yellow 
    For ($i = 1; $i -le "10"$i++) { sleep 1; Write-Progress -Activity "Exiting Script" -status "$i" -percentComplete ($i /10 * 100) } 
    Stop-transcript 
    Send-Email -From $from -To $email1 -subject "Confrence Room Creation - CSV Parameter incorrect" -smtpserver $smtpserver 
    exit 
} 
 
 
###########################Define Variables/Logs############################ 
 
$date = get-date -format d 
# replace \ by - 
$time = get-date -format t 
$month = get-date 
$month1 = $month.month 
$year1 = $month.year 
 
 
$date = $date.ToString().Replace("/""-") 
 
$time = $time.ToString().Replace(":""-"$time = $time.ToString().Replace(" """) 
 
$logs = (Get-Location).Path + "\Logs" + "\" + "RoomScript" + $date + "_" + $time + "_.txt" 
$log1 = (Get-Location).Path + "\Logs" + "\" + "RoomScript_Summary" + $date + "_" + $time + "_.txt" 
 
Start-Transcript -Path $logs 
 
 
$data = import-csv $csv 
if ($Error) 
{ 
    Write-Host "CSV Import Error ---Script will exit" -ForegroundColor Yellow 
    For ($i = 1; $i -le "10"$i++) { sleep 1; Write-Progress -Activity "Exiting Script" -status "$i" -percentComplete ($i /10 * 100) } 
    Stop-transcript 
    Send-Email -From $from -To $email1 -subject "Confrence Room Creation - CSV Import Error" -smtpserver $smtpserver 
    exit 
} 
 
foreach ($i in $data) 
{ 
     
    $name = $i.name 
    $name = $name.trim() # mandatory 
    if ($name -like $null) 
    { 
        Write-host "Name is empty... Script will exit" -foregroundcolor yellow 
        For ($i = 1; $i -le "10"$i++) { sleep 1; Write-Progress -Activity "Exiting Script" -status "$i" -percentComplete ($i /10 * 100) } 
        Send-Email -From $from -To $email1 -subject "Confrence Room Creation Logs" -smtpserver $smtpserver -attachment $logs 
        exit 
    } 
     
    $samaccountname = $i.samaccountname 
    $samaccountname = $samaccountname.trim() #mandatory 
    if ($samaccountname -like $null) 
    { 
        Write-host "samaccountName is empty... Script will exit" -foregroundcolor yellow 
        For ($i = 1; $i -le "10"$i++) { sleep 1; Write-Progress -Activity "Exiting Script" -status "$i" -percentComplete ($i /10 * 100) } 
        Stop-transcript 
        Send-Email -From $from -To $email1 -subject "Confrence Room Creation Logs" -smtpserver $smtpserver -attachment $logs 
        exit 
    } 
     
    $OU = $i.OU 
    $OU = $OU.trim() #mandatory 
    if ($OU -like $null) 
    { 
        Write-host "OU is empty... Script will exit" -foregroundcolor yellow 
        For ($i = 1; $i -le "10"$i++) { sleep 1; Write-Progress -Activity "Exiting Script" -status "$i" -percentComplete ($i /10 * 100) } 
        Stop-transcript 
        Send-Email -From $from -To $email1 -subject "Confrence Room Creation Logs" -smtpserver $smtpserver -attachment $logs 
        exit 
    } 
     
    $Office = $i.office 
    $Office = $office.trim() 
     
    $Title = $i.title 
    $Title = $Title.trim() 
     
    $Company = $i.company 
    $Company = $Company.trim() 
     
    $Telephone = $i.Telephone 
    $Telephone = $Telephone.trim() 
     
    $Restricted = $i.Restricted 
    $Restricted = $Restricted.trim() #mandatory 
    if ($Restricted -like $null) 
    { 
        Write-host "Restricted field is empty... Script will exit" -foregroundcolor yellow 
        For ($i = 1; $i -le "10"$i++) { sleep 1; Write-Progress -Activity "Exiting Script" -status "$i" -percentComplete ($i /10 * 100) } 
        Stop-transcript 
        Send-Email -From $from -To $email1 -subject "Confrence Room Creation Logs" -smtpserver $smtpserver -attachment $logs 
        exit 
    } 
    $resou = $i.resou 
    $resou = $resou.trim() 
     
    $OwnerGroup = $i.OwnerGroup 
    $OwnerGroup = $OwnerGroup.trim() 
     
    $AuthorGroup = $i.AuthorGroup 
    $AuthorGroup = $AuthorGroup.trim() 
     
    if (($Restricted -like "Yes"-and (($OwnerGroup -like $null-or ($OwnerGroup -like $null-or ($resou -like $null))) 
    { 
        Write-host "Either both or one of the restrction group is empty... Script will exit" -foregroundcolor yellow 
        For ($i = 1; $i -le "10"$i++) { sleep 1; Write-Progress -Activity "Exiting Script" -status "$i" -percentComplete ($i /10 * 100) } 
        Stop-transcript 
        Send-Email -From $from -To $email1 -subject "Confrence Room Creation Logs" -smtpserver $smtpserver -attachment $logs 
        exit 
    } 
     
    $managedby = $i.PrimaryOwnerGrp 
    $managedby = $managedby.trim() 
     
    $bkpowner = $i.SecondaryOwnerGrp 
    $user1 = $bkpowner.split(",") 
    $count1 = $user1.count 
    $user = $user1[0 .. ($count1 - 2)] 
    $count = $user.count 
     
    if (($Restricted -like "Yes"-and (($managedby -like $null-or ($bkpowner -like $null))) 
    { 
        Write-host "Either both or one of the managed by filed is empty... Script will exit" -foregroundcolor yellow 
        For ($i = 1; $i -le "10"$i++) { sleep 1; Write-Progress -Activity "Exiting Script" -status "$i" -percentComplete ($i /10 * 100) } 
        Stop-transcript 
        Send-Email -From $from -To $email1 -subject "Confrence Room Creation Logs" -smtpserver $smtpserver -attachment $logs 
        exit 
    } 
     
    if ($Restricted -like "Yes") 
    { 
        ## All Owners for DL including backups 
        $AllOwner = @() 
        $AllOwner +$managedby 
        $AllOwner +$user 
        $AllOwner = $AllOwner | Select -Unique 
    } 
     
    $Notes = $i.Notes 
     
    $UserPrincipalName = $samaccountname + "@" + "labtest.com" 
     
    if ($error) 
    { 
        Write-host "CSV Load error... Script will exit" -foregroundcolor yellow 
        For ($i = 1; $i -le "10"$i++) { sleep 1; Write-Progress -Activity "Exiting Script" -status "$i" -percentComplete ($i /10 * 100) } 
        Stop-transcript 
        Send-Email -From $from -To $email1 -subject "Confrence Room Creation Logs" -smtpserver $smtpserver -attachment $logs 
        exit 
    } 
     
    ############################Start Room mailbox account########################### 
     
    write-host "Creating Room mailbox Account..........." -foregroundcolor green 
     
    $gmmbx1 = get-mailbox $name -ea silentlycontinue 
    $gmmbx2 = get-mailbox $samaccountname -ea silentlycontinue 
    if ($gmmbx1 -or $gmmbx2) 
    { 
        Write-Host "Mailbox Already exists,script will exit....." -ForegroundColor Yellow 
        For ($i = 1; $i -le "10"$i++) { sleep 1; Write-Progress -Activity "Exiting Script" -status "$i" -percentComplete ($i /10 * 100) } 
        Stop-transcript 
        Send-Email -From $from -To $email1 -subject "Confrence Room Creation Logs" -smtpserver $smtpserver -attachment $logs 
        exit 
    } 
     
    $Error.Clear() 
     
    New-Mailbox -Name $name -OrganizationalUnit $ou -DisplayName $name -samaccountname $samaccountname -UserPrincipalName $UserPrincipalName -Room 
     
    if ($error) 
    { 
        Write-host "Mailbox Creation error... Script will exit" -foregroundcolor yellow 
        For ($i = 1; $i -le "10"$i++) { sleep 1; Write-Progress -Activity "Exiting Script" -status "$i" -percentComplete ($i /10 * 100) } 
        Stop-transcript 
        $DATE1 = GET-DATE 
        Add-Content $log1 "$DATE1 - Mailbox $name Creation error" 
        Send-Email -From $from -To $email1 -subject "Confrence Room Creation Logs" -smtpserver $smtpserver -attachment $log1 
        exit 
    } 
     
    For ($i = 1; $i -le "20"$i++) { sleep 1; Write-Progress -Activity "Creating Room Mailbox" -status "$i" -percentComplete ($i /20 * 100) } 
     
    write-host "Room mailbox $name Account Created..........." -foregroundcolor green 
    $DATE1 = GET-DATE 
    Add-Content $log1 "$DATE1 - Mailbox $name Created" 
     
    while (!(get-mailbox $samaccountname -ea silentlycontinue)) 
    { 
        For ($i = 1; $i -le "10"$i++) { sleep 1; Write-Progress -Activity "Creating Room Mailbox $name" -status "$i" -percentComplete ($i /10 * 100) } 
    } 
     
    $getrmbx = get-mailbox $samaccountname -ea silentlycontinue 
    $Error.clear() 
    #######################Update Attributes on the Mailbox################## 
     
    if ($getrmbx) 
    { 
         
        set-User -identity $samaccountname -office $office -Company $company -Title $title -phone $Telephone -notes $notes 
        set-mailbox -id $samaccountname -CustomAttribute1 "NONE" -CustomAttribute12 "CONF" 
         
        if ($error) 
        { 
            write-host "Setting Room mailbox $samaccountname Attributes encountered error ..........." -foregroundcolor yellow 
            $DATE1 = GET-DATE 
            Add-Content $log1 "$DATE1 - Error - Setting Attributes"} 
        else 
        { 
            write-host "Room mailbox $samaccountname Attributes has been set..........." -foregroundcolor green 
            $DATE1 = GET-DATE 
            Add-Content $log1 "$DATE1 - Success - Setting Attributes"} 
         
    } 
 
    $error.clear() 
     
    ########################Create Owner /Author Groups##################### 
     
    if ($Restricted -like "Yes") 
    { 
         
        New-DistributionGroup -Name $OwnerGroup -Type "Security" -OrganizationalUnit $resou -Managedby $AllOwner -MemberDepartRestriction closed 
        #Provide permissions to owner on Group 
        For ($i = 1; $i -le "20"$i++) { sleep 1; Write-Progress -Activity "Creating $OwnerGroup" -status "$i" -percentComplete ($i /20 * 100) } 
        if ($error) 
        { 
            Write-host "group $OwnerGroup Creation error..." -foregroundcolor yellow 
            $DATE1 = GET-DATE 
            Add-Content $log1 "$DATE1 - Error - $OwnerGroup Creation" 
        } 
        else 
        { 
            $DATE1 = GET-DATE 
            Add-Content $log1 "$DATE1 - Success - $OwnerGroup Creation" 
            while (!(get-distributiongroup $OwnerGroup -ea "silentlycontinue")) 
            { 
                For ($i = 1; $i -le "20"$i++) { sleep 1; Write-Progress -Activity "Waiting for $OwnerGroup Appear " -status "$i" -percentComplete ($i /20 * 100) } 
            } 
        } 
        $Error.clear() 
        New-DistributionGroup -Name $AuthorGroup -Type "Security" -OrganizationalUnit $resou -Managedby $AllOwner -MemberDepartRestriction closed 
        #Provide permissions to owner on Group 
        For ($i = 1; $i -le "20"$i++) { sleep 1; Write-Progress -Activity "Creating $AuthorGroup" -status "$i" -percentComplete ($i /20 * 100) } 
        if ($error) 
        { 
            Write-host "group $AuthorGroup Creation error..." -foregroundcolor yellow 
            $DATE1 = GET-DATE 
            Add-Content $log1 "$DATE1 - Error - $AuthorGroup Creation" 
        } 
        else 
        { 
            $DATE1 = GET-DATE 
            Add-Content $log1 "$DATE1 - Success - $AuthorGroup Creation" 
            while (!(get-distributiongroup $AuthorGroup -ea "silentlycontinue")) 
            { 
                For ($i = 1; $i -le "20"$i++) { sleep 1; Write-Progress -Activity "Waiting for $OwnerGroup Appear " -status "$i" -percentComplete ($i /20 * 100) } 
            } 
        } 
        #################Update the Custom attributes for the group############# 
         
        $getowngp = get-distributiongroup $OwnerGroup -ea "silentlycontinue" 
        $getauthgp = get-distributiongroup $AuthorGroup -ea "silentlycontinue" 
         
        $Error.clear() 
        if ($getowngp) 
        { 
            set-distributiongroup $OwnerGroup -CustomAttribute1 "NONE" -CustomAttribute12 "CONF" 
            Add-ADPermission -identity $OwnerGroup -User $managedby -AccessRights writeproperty -Properties "Member" 
            if ($error) 
            { 
                write-host "Setting Group $OwnerGroup Attributes encountered error ..........." -foregroundcolor yellow 
                $DATE1 = GET-DATE 
                Add-Content $log1 "$DATE1 - Error - $OwnerGroup Attributes"} 
            else 
            { 
                write-host "Group $OwnerGroup Attributes Attributes has been set..........." -foregroundcolor green 
                $DATE1 = GET-DATE 
                Add-Content $log1 "$DATE1 - Success - $OwnerGroup Attributes"} 
        } 
         
         
        if ($getauthgp) 
        { 
            set-distributiongroup $AuthorGroup -CustomAttribute1 "NONE" -CustomAttribute12 "CONF" 
            Add-ADPermission -identity $AuthorGroup -User $managedby -AccessRights writeproperty -Properties "Member" 
            if ($error) 
            { 
                write-host "Setting Group $AuthorGroup Attributes encountered error ..........." -foregroundcolor yellow 
                $DATE1 = GET-DATE 
                Add-Content $log1 "$DATE1 - Error - $AuthorGroup Attributes"} 
            else 
            { 
                write-host "Group $AuthorGroup Attributes Attributes has been set..........." -foregroundcolor green 
                $DATE1 = GET-DATE 
                Add-Content $log1 "$DATE1 - Success - $AuthorGroup Attributes"} 
        } 
         
    } 
    else 
    { 
        Write-host "As Restricted is not equal to Yes for $samaccountname....so Group creation is ignored" -foregroundcolor blue 
        $DATE1 = GET-DATE 
        Add-Content $log1 "$DATE1 - SKIP - Restricted"} 
     
    $error.clear() 
     
    ###################ADD permission for Unrestricted Rooms#################### 
     
    if ($Restricted -like "No") 
    { 
         
        Set-MailboxFolderPermission -identity ($getrmbx.alias + ':\calendar'-user "Default" -AccessRights "Reviewer" 
        For ($i = 1; $i -le "10"$i++) { sleep 1; Write-Progress -Activity "Adding Reviewer Perm on $samacountname " -status "$i" -percentComplete ($i /10 * 100) } 
         
        if ($error) 
        { 
            write-host "Setting unrestricted for $samaccountname default permission encountered error ..........." -foregroundcolor yellow 
            $DATE1 = GET-DATE 
            Add-Content $log1 "$DATE1 - Error - Setting Default Reviewer"} 
        else 
        { 
            write-host "Unrestricted Room Deafult Reviewer has been set for .......$samaccountname" -foregroundcolor green 
            $DATE1 = GET-DATE 
            Add-Content $log1 "$DATE1 - Success - Setting Default Reviewer"} 
    } 
    $error.clear() 
     
    ###################ADD permission for Restricted Rooms####################     
     
    if ($Restricted -like "Yes") 
    { 
         
        Set-MailboxFolderPermission -identity ($getrmbx.alias + ':\calendar'-user "Default" -AccessRights "None" 
         
        For ($i = 1; $i -le "10"$i++) { sleep 1; Write-Progress -Activity "Adding Default Perm to None on $samacountname " -status "$i" -percentComplete ($i /10 * 100) } 
         
        ADD-mailboxfolderpermission -identity ($getrmbx.alias + ':\calendar'-user "$ownergroup" -AccessRights "Owner" 
         
        For ($i = 1; $i -le "10"$i++) { sleep 1; Write-Progress -Activity "Adding Owner Perm to $ownergroup on $samacountname " -status "$i" -percentComplete ($i /10 * 100) } 
         
        ADD-mailboxfolderpermission -identity ($getrmbx.alias + ':\calendar'-user "$Authorgroup" -AccessRights "Author" 
         
        For ($i = 1; $i -le "10"$i++) { sleep 1; Write-Progress -Activity "Adding Author Perm to $Authorgroup on $samacountname " -status "$i" -percentComplete ($i /10 * 100) } 
         
        if ($error) 
        { 
            write-host "Setting restricted permission for $samaccountname encountered error ..........." -foregroundcolor yellow 
            $DATE1 = GET-DATE 
            Add-Content $log1 "$DATE1 - Error - Setting Restricted Permissions"} 
        else 
        { 
            write-host "Restrcited Permissions has been set for........... $samaccountname" -foregroundcolor green 
            $DATE1 = GET-DATE 
            Add-Content $log1 "$DATE1 - Success - Setting Restricted Permissions"} 
    } 
     
    $error.clear() 
     
    #########################Setting Auto accept############################## 
     
    $AUTOMATE_PROCESSING = "AutoAccept" 
    $ADD_ADDITIONAL_RESPONSE = $false 
    $ADDITIONAL_RESPONSE = $false 
    $ADD_NEW_REQUEST_TENTATIVELY = $false 
    $REMOVE_OLD_MEETING_MSG = $true 
    $DELETE_SUBJECT = $false 
    $DELETE_Organizer = $false 
    $RESTRICT_ALL_BOOK = $false 
    $TentativePendingApproval = $true 
     
    if ($Restricted -like "No") 
    { 
        set-calendarprocessing -id $samaccountname ` 
                               -AutomateProcessing: $AUTOMATE_PROCESSING        ` 
                               -enableresponsedetails: $false                ` 
                               -AddAdditionalResponse: $ADD_ADDITIONAL_RESPONSE    ` 
                               -AdditionalResponse: $ADDITIONAL_RESPONSE        ` 
                               -AddNewRequestsTentatively: $ADD_NEW_REQUEST_TENTATIVELY    ` 
                               -RemoveOldMeetingMessages: $REMOVE_OLD_MEETING_MSG        ` 
                               -DeleteSubject: $DELETE_SUBJECT        ` 
                               -TentativePendingApproval:$TentativePendingApproval 
        set-MailboxCalendarConfiguration -id $samaccountname -RemindersEnabled:$false 
        For ($i = 1; $i -le "5"$i++) { sleep 1; Write-Progress -Activity "Setting Auto accept properties" -status "$i" -percentComplete ($i /* 100) } 
        if ($error) 
        { 
            write-host "Unrestricted Room $samaccountname : Setting Auto accept & other properties encountered error ..........." -foregroundcolor yellow 
            $DATE1 = GET-DATE 
            Add-Content $log1 "$DATE1 - Error - Setting AutoAccept Properties"} 
        else 
        { 
            write-host "Unrestricted Room $samaccountname : Auto accept & other properties has been set..........." -foregroundcolor green 
            $DATE1 = GET-DATE 
            Add-Content $log1 "$DATE1 - Success - Setting AutoAccept Properties"} 
    } 
     
    $error.clear() 
     
    if ($Restricted -like "Yes") 
    { 
        $restrictlist = @() 
        $restrictlist = $ownergroup$Authorgroup 
        set-calendarprocessing -id $samaccountname ` 
                               -AutomateProcessing: $AUTOMATE_PROCESSING        ` 
                               -enableresponsedetails: $false                    ` 
                               -AddAdditionalResponse: $ADD_ADDITIONAL_RESPONSE    ` 
                               -AdditionalResponse: $ADDITIONAL_RESPONSE        ` 
                               -AddNewRequestsTentatively: $ADD_NEW_REQUEST_TENTATIVELY    ` 
                               -RemoveOldMeetingMessages: $REMOVE_OLD_MEETING_MSG        ` 
                               -DeleteSubject: $DELETE_SUBJECT            ` 
                               -AllBookInPolicy: $RESTRICT_ALL_BOOK        ` 
                               -BookInPolicy: $restrictlist     ` 
                               -TentativePendingApproval:$TentativePendingApproval 
        set-MailboxCalendarConfiguration -id $samaccountname -RemindersEnabled:$false 
        For ($i = 1; $i -le "5"$i++) { sleep 1; Write-Progress -Activity "Setting Auto accept properties" -status "$i" -percentComplete ($i /* 100) } 
        if ($error) 
        { 
            write-host "Restricted Room $samaccountname : Setting Auto accept & other properties encountered rror ..........." -foregroundcolor yellow 
            $DATE1 = GET-DATE 
            Add-Content $log1 "$DATE1 - Error - Setting AutoAccept Restricted Properties"} 
        else 
        { 
            write-host "Restricted Room $samaccountname : Auto accept & other properties has been set..........." -foregroundcolor green 
            $DATE1 = GET-DATE 
            Add-Content $log1 "$DATE1 - Success - Setting AutoAccept Restricted Properties"} 
    } 
     
    $error.clear() 
     
    #################################Setting for Video Conference Rooms######################### 
     
    if ($name -match ".*(VC).*") 
    { 
        set-calendarprocessing -id $samaccountname -AddOrganizerToSubject $DELETE_Organizer 
        For ($i = 1; $i -le "5"$i++) { sleep 1; Write-Progress -Activity "Setting VC Room properties" -status "$i" -percentComplete ($i /* 100) } 
        if ($error) 
        { 
            write-host "VC Room $samaccountname : Setting Auto accept & other properties encountered error ..........." -foregroundcolor yellow 
            $DATE1 = GET-DATE 
            Add-Content $log1 "$DATE1 - Error - Setting VC Properties"} 
        else 
        { 
            write-host "VCRestricted Room $samaccountname : Auto accept & other properties has been set..........." -foregroundcolor green 
            $DATE1 = GET-DATE 
            Add-Content $log1 "$DATE1 - Success - Setting VC Properties"} 
    } 
    ############################################################################################ 
     
} 
Stop-transcript 
 
$body = Get-Content $log1 
Send-Email -From $from -To $email1 -subject "Confrence Room Creation Logs" -smtpserver $smtpserver -attachment $log1 -body $body 
 
 
Exit

Thanks for Reading

Sukhija Vikas

http://SycCloudpro.com


Exchange Remote Hosted Archives

$
0
0

For one of our customers we are using a process to migrate the PST from EntepriseVault to archives on Exchange online.

The process that we are following till now is :

  • Migrate the Exchange mailbox to EOL.
  • Enable the Remote Archive
  • Upload the PST via Azure.

This process is working great for us but customer still wants if we can improve that Archives are delivered along with the mailbox or before.

We know this is possible but we haven’t tested yet how it works with outlook 2010, so for testing we will be enabling the

Remote Hosted Archive for one of the On-premise Users & wait for AAD Synchronization to happen, we will check if user is able to use the archive.

Here is the Powershell command to enable the Remote Archive for Exchange 2010 user:

Check the target delivery domain first

Get-RemoteDomain | Where {$_.TargetDeliveryDomain -eq $true}

Now use below command to enable Archive:

Enable-Mailbox “MailboxName” -RemoteArchive -ArchiveDomain “TargetDeliveryDomain”

You can enable it using GUI as well, Launch Exchange Management Console

Select user –> right click –> Enable Archive

Select Create a remote hosted archive –> browse to select the target delivery domain & press Ok.

Now you can see the archive underneath the mailbox after synchronization of AAD Sync.

Next step is to upload the PST to Azure, so create a mapping file & upload it.

After the import is completed, you can see all the pst items are present in the archive.

This way we can migrate the archives before even moving the mailboxes to the cloud & archives are still accessible by users for

whom mailboxes are still OnPremise so its kind of seamless for the users.

Hope you will be able to use the same process if you are also in a situation where you want archives to be migrated sooner.

(before mailbox moves & without impacting access to old archive data)

Thanks for reading

Sukhija Vikas

http://SysCloudPro.com

 


Exchange Online and Automapping

$
0
0

You have seen that exchange 2010 has introduced the feature called auto-mapping where mailboxes

get auto mapped to outlook when full mailbox permissions are granted.

We have seen issues with this feature & that’s why in the past I have written the post on

how to disable the auto-mapping for all mailboxes in the environment.

https://syscloudpro.com/2015/05/04/disable-auto-mapping-of-exchange-mailboxes/

Things have come a long way since than but some administrators are still not comfortable with this feature.

This feature is also part of Exchange online but needs to be disabled differently than what we have done on On-premise.

Exchange On-premise Uses Autodiscover & also “msExchDelegateListLink” attribute for Automapping , In the above blog post ,

We have fetched all mailboxes in the environment & set the “msExchDelegateListLink” attribute to null  where applicable via Powershell script.

This can also be accomplished by using below powershell command as well by removing the permissions first & than adding the permissions

by setting -automapping parameter as false.

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

Add-MailboxPermission -Identity Mailboxname  -User Username -AccessRight FullAccess  -Automapping $false

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

In Exchange online environment where you are maintaining Hybrid , attribute msExchDelegateListLink doesn’t gets updated.

So how you can mass disable this without removing/re-adding permissions ??????????????????

This is possible as Microsoft has provided a good powershell way to accomplish it 🙂

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

Remove-MailboxPermission mailboxname -ClearAutoMapping

————————————————————————————————————————————————-

You can fetch all mailboxes & schedule this command to remove it from all users.(you can just

filter it on shared mailboxes as generally those are ones used for mapping)

I will also check if there is other way to do it where we can detect which all mailboxes are using this feature & just act on those ones,

till than stay tuned 🙂

Thanks for Reading

Sukhija Vikas

http://SysCloudPro.com


Extract Permission Dump Exchange Onpremise

$
0
0

Sharing a quickly written powershell solution to extract the permissions dump from Exchange onpremise enviornment.

This dump will than be used by project management team to create migration sets for Exchange online migration.

Following is done by the script.

  • Extract Full access permissions
  • Extract Send as permissions
  • Extract delegates information using pubdelegates attribute of Active Directory.
  • Report on mailbox type
  • Extracts employee id.
  • extracts primary smtp address
  • Shows the progress of the script after execution.
  • format the information in CSV columns that can be delimited further.
  • exclude service accounts & known accounts from full as/send as permission.

Script uses exchange mangement & quest AD shell.

Download & extract the script from below link.

https://gallery.technet.microsoft.com/scriptcenter/Extract-Permission-Dump-31809149

 

Config folder has a file name excludeaccounts.txt where you can define the accounts that you want to exclude from the permission dump.

Logs folder will contain transcript log which you can activate by removing hash inside the script.

Report folder contains the output report (permission dump) after script execution is completed.

In this script there is nothing to update except the employeeid part that can may or may not be applicable to your environment.

I have taken example of extensionattribute10 which is used by one of the company to store employeeid.

Just open exchange shell & execute the script.

Report will be like:

<#     
    .NOTES 
    =========================================================================== 
     Created on:       7/27/2017 8:55 AM 
     Created by:       Vikas Sukhija(http://SysCloudPro.com) 
     Organization:      
     Filename:         ExtractPermissionsMBX.ps1 
    =========================================================================== 
    .DESCRIPTION 
        This script will extract send ad, full access & delegate dump from 
                Exchange enviornment, this can be handy in creating groups for EOL Migration. 
#> 
######################Add 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 
} 
 
################################ADD Funstions################## 
function Write-Log 
{ 
    [CmdletBinding()] 
    param 
    ( 
        [Parameter(Mandatory = $true)] 
        [array]$Name, 
        [Parameter(Mandatory = $true)] 
        [string]$Ext, 
        [Parameter(Mandatory = $true)] 
        [string]$folder 
    ) 
     
    $log = @() 
    $date1 = get-date -format d 
    $date1 = $date1.ToString().Replace("/""-") 
    $time = get-date -format t 
     
    $time = $time.ToString().Replace(":""-") 
    $time = $time.ToString().Replace(" """) 
     
    foreach ($n in $name) 
    { 
         
        $log += (Get-Location).Path + "\" + $folder + "\" + $n + "_" + $date1 + "_" + $time + "_.$Ext" 
    } 
    return $log 
} 
#########################Add logs/variables####################### 
$excludeacc = (Get-Content .\config\excludeaccounts.txt) 
$log = Write-Log -Name extractperm -folder logs -Ext log 
$report = Write-Log -Name extractpermissions -folder report -Ext csv 
$collection = @() 
$count = 0 
 
#Start-Transcript -Path $log 
Write-Host "Fetching all mailboxes" -ForegroundColor Magenta 
$allmbx = get-mailbox -resultsize unlimited 
$countAll = $allmbx.count 
Write-Host "fetched all mailboxes .....count $countAll" -ForegroundColor Green 
 
$allmbx | ForEach-Object { 
    $pub=@() 
    $count = $count + 1 
    $mcoll = "" | select Alias, Samaccountname, PrimarySMTPAddress, Employeeid,MBXType,fullaccess, sendasaccess, delegate 
    $alias = $_.alias 
    $sam = $_.samaccountname 
    $email = $_.primarysmtpaddress 
    $mbxtype = $_.recipienttypedetails 
    Write-Host "Processing........$sam..........$count of $countAll" -ForegroundColor Green 
    $qaduser = get-qaduser -samaccountname $sam -IncludedProperties publicdelegates,extensionattribute10 
    $empid = $qaduser.extensionattribute10 
    $pubdelegates = $qaduser.publicdelegates 
    if($pubdelegates){ 
    $pubdelegates | ForEach-Object{ 
            $delegate = (get-qaduser $_).Samaccountname 
            $pub +$delegate 
        } 
    } 
    $fullaccessp = Get-MailboxPermission -Identity $sam | where{ $_.AccessRights -like "*fullaccess*" } | select -ExpandProperty user 
    $senasp = get-mailbox $sam | get-ADPermission | where { $_.ExtendedRights -like "*Send-As*" } | select -ExpandProperty user 
    $full = compare $fullaccessp $excludeacc | where{ $_.SideIndicator -eq '<='| select -ExpandProperty InputObject 
    $send = compare $senasp $excludeacc | where{ $_.SideIndicator -eq '<=' } | select -ExpandProperty InputObject 
    $mcoll.Alias = $alias 
    $mcoll.Samaccountname = $sam 
    $mcoll.PrimarySMTPAddress = $email 
    $mcoll.Employeeid = $empid 
    $mcoll.MBXtype = $mbxtype 
    $mcoll.delegate = $pub 
    $mcoll.fullaccess = $full 
    $mcoll.sendasaccess = $send 
     
    $collection +$mcoll 
} 
 
$collection | select Alias, Samaccountname, PrimarySMTPAddress,Employeeid,MBXType, @{ Name = "fullaccess"; Expression = { $_.fullaccess } }, @{ Name = "sendasaccess"; Expression = { $_.sendasaccess} }, @{ Name = "delegate"; Expression = { $_.delegate} } |Export-Csv $report -NoTypeInformation 
#Stop-Transcript

 

Thanks for reading & downloading

Sukhija Vikas

http://SysCloudPro.com


Viewing all 214 articles
Browse latest View live