Tag Archives: Exchange

Connecting to Powershell Endpoints Exchange/Lync

I will write a short post about connecting to Powershell endpoints of Exchange and Lync. Basically you can always use PSRemoting to connect and make use of modules. However some CMDlets will simply not work when importing the snapin or module. So connecting to an endpoint is much more efficient. To connect to Microsoft Exchange use the following commands:

$PSOptions = New-PSSessionOption -SkipCACheck -SkipRevocationCheck -SkipCNCheck
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ExchangeServer.Domain.TLD/powershell -SessionOption $PSOptions
Import-PSSession $Session 

To connect to Lync use the following commands:

$Session = New-PSSession  -ConnectionUri https://LyncServer.Domain.TLD/ocspowershell -Authentication NegotiateWithImplicitCredential
Import-PSSession $Session

You can connect from any domain computer. Of course if your loged on with an account that does not have to appropriate permission you’ll have to connect using the  -credentials parameter.

 

Resolving script for autocomplete

A servicedesk employee came to me with a problem with the autocomplete functionality in Outlook 2010. So I looked around for a bit to find some code. I came across a script that does the job. I added functionality so that it would work for the servicedesk. For the script to work, the user will need to have enough permissions to add permissions to any mailbox. The script is semi-automatic. So user interaction is needed.

Outlook 2003 used to have NK2 files which are corrupt from time to time. Then Microsoft replaced that functionality into a .dat with exact the same issues. Clearly in Outlook 2010 this problem still exists. The key difference is that Outlook 2010 and Outlook 2013 in combination with Exchange 2010 or later has a functionality called suggested contacts. This works similar to the autocomplete function only better. Contacts added to the suggested contacts will be in the autocomplete list. Imagine that by generating a list of all unique recipients in the sent item you’ll have a list that is satisfactory for the user.

Furthermore this functionality works regardless of the user profile. So in our case if a user uses Outlook Web App that user will also have that same functionality. There is a catch. This does not work as intended in combination with Res Workspace Manager and Zero-profiling. To get this right you can use another script.

This script gives write the LegacyDN as output on screen. This is needed for situaties where you have GAL segregation. Then it opens the control panel for e-mail on that server. Of course Outlook needs to be installed on the system. That you need to permit the script to use Outlook. You’ll get the warning as seen below:

Screen Shot 2015-04-16 at 13.55.28

Again if you use RES Workspace Manager with Zero-Profiling use another script.

#Import Modules,Snapins and functions
ipmo ActiveDirectory
Add-PSSnapin Microsoft.Exchange.Management.Powershell.E2010
Function AddTo-SuggestedContactsIfNotAlreadyAdded ($name, $email)
{

    if(($name -eq "") -or ($email -eq "") -or ($name -eq $null) -or ($email -eq $null)){
        return;
    }

    $name = $name.Replace("'", "").Replace("""", "")


    $contactAlreadyAdded = $false

    foreach ($elem in $global:alreadyAddedEmails) {
        if(($elem.ToLower() -match $email.ToLower())){
            $contactAlreadyAdded = $true
            Write-Host  ($global:counter)"/"($totalItems)  "SKIPPED " $name.PadRight(25," ") "-" $email
            return;
        }
    }

    if(!$contactAlreadyAdded )    {
        $newcontact = $contacts.Items.Add()
        $newcontact.FullName = $name
        $newcontact.Email1Address = $email
        $newcontact.Save()
        $global:alreadyAddedEmails += $email
        Write-Host ($global:counter)"/"($totalItems)  "ADDED   " $name.PadRight(25," ") "-" $email
    }
}

#Set Variables
$Admin = [Environment]::UserName
$choice2 = "y"
$Admindomain = $env:userdomain

#Set loop function
while ($choice2 -match  "y"){

#Request Username from interactive User
Write-Host "Voer de gebruikersnaam van de gebruiker in: " -NoNewline -F Cyan 
$Username = read-host 

#Test if user exist
$Testresult = $Null
$Testresult = Get-ADUser $Username -Properties *
While ($Testresult -eq $Null){
write-host "De opgegeven Username bestaat niet of is foutief ingevoerd. Toets de username in in het format zoals bijvoorbeeld OTHSBE02" -b Black -f Red
$Username = Read-Host "Voer de gebruikersnaam van de gebruiker in:" -NoNewline -F Cyan 
$Testresult = Get-ADUser $Username -Properties *}

Get-ADUser -Identity $Testresult.samaccountname -Properties legacyExchangeDN  | Select legacyExchangeDN

#Addmailbox permission to the admin user with retry
Add-MailboxPermission -Identity $Testresult.samaccountname -AccessRights "FullAccess" -User ("$AdminDomain"+"\"+"$Admin")
$Testresult2 = $null
$Testresult2 = Get-MailboxPermission -Identity $Testresult.samaccountname | ? {$_.User -match ("$AdminDomain"+"\\"+"$Admin")}
While ($Testresult2 -eq $Null){
write-host "De rechten op de mailbox zijn niet goed gezet. Het wordt nogmaals geprobeerd" -b Black -f Red
Add-MailboxPermission -Identity $Testresult.samaccountname -AccessRights "FullAccess" -User ("$AdminDomain"+"\"+"$Admin")
$Testresult2 = Get-MailboxPermission -Identity $Testresult.samaccountname | ? {$_.User -match ("$AdminDomain"+"\\"+"$Admin")}}


#Opens Mail control panel
C:\Windows\SysWOW64\control.exe mlcfg32.cpl

#Confirm that the admin have changed to Exchange profile accordingly.
$choice = $Null
 while ($choice -notmatch "[y|n]"){
     $choice = read-host "Heb je het Outlook profiel aangepast? (Y/N)"
      }


$outlook = new-object -com outlook.application
$olFolders = "Microsoft.Office.Interop.Outlook.OlDefaultFolders" -as [type]
$namespace = $outlook.GetNameSpace("MAPI")
$sentItems = $namespace.getDefaultFolder($olFolders::olFolderSentMail)
$alreadyAddedEmails = @() #Empty Array
$counter = 0;
$totalItems = $sentItems.items.count;

Write-Host "Scanning through" $totalItems "emails in SentItems"

$contacts = $outlook.Session.GetDefaultFolder($olFolders::olFolderSuggestedContacts)



# Loop through all emails in SentItems
$sentItems.Items | % {

    #Loop through each recipient
    $_.Recipients | %{
        AddTo-SuggestedContactsIfNotAlreadyAdded $_.Name  $_.Address
    }
    $global:counter = $global:counter + 1
}

$outlook.Quit()

#Addmailbox permission to the admin user with retry
Remove-MailboxPermission -Identity $Testresult.samaccountname -AccessRights "FullAccess" -User ("$AdminDomain"+"\"+"$Admin")
$Testresult2 = Get-MailboxPermission -Identity $Testresult.samaccountname | ? {$_.User -match ("$AdminDomain"+"\\"+"$Admin")}
While ($Testresult2 -ne $Null){
write-host "De rechten op de mailbox zijn niet goed gezet. Het wordt nogmaals geprobeerd" -b Black -f Red
Remove-MailboxPermission -Identity $Testresult.samaccountname -AccessRights "FullAccess" -User ("$AdminDomain"+"\"+"$Admin")
$Testresult2 = Get-MailboxPermission -Identity $Testresult.samaccountname | ? {$_.User -match ("$AdminDomain"+"\\"+"$Admin")}}


#Present user with the choice to do another user.
$choice2 = read-host "Wilt u dit voor nog een user uitvoeren? (Y/N)"
}

 

autodiscover DNS zones aanmaken

Om een autodiscover record aan te maken middels een command kunnen de volgende commando’s uitgevoerd worden.  recordnaam moet vervangen wordt voor het subdomein en domein voor het domeinnaam in kwestie. Daarnaast moet er eerst een primary zone aangemaakt worden of een record in een publieke DNS server.

dnscmd . /zoneadd _recordnaam._tcp.domein.nl. /dsprimary
dnscmd . /recordadd _recordnaam._tcp.domein.nl. @ SRV 10 1 443 recordnaam.domein.nl.

Outlook 2010 kan dan een foutmelding geven zoals is beschreven in Microsoft KB2480582
. Maak hiervoor een REG_SZ sleutel aan binnen het gebruikersregister met bijvoorbeeld RES Workspace Manager met in de KB beschreven waardes.

Recipients of senders filteren op basis van wildcards

Soms moet je weten hoeveel er wordt gestuurd naar *@hotmail.com of *@outlook.com. Dit kan op de volgende manier

Get-MessageTrackingLog -ResultSize Unlimited -Start "9/1/2013" -End "9/12/2013" | where{$_.recipients -like "*@live.nl"} | select-object Timestamp,SourceContext,Source,EventId,MessageSubject,Sender,{$_.Recipients} >

Of voor ontvangen e-mail:

Get-MessageTrackingLog -ResultSize Unlimited -Start "5/1/2011" -End "5/12/2011" | where{$_.sender -like "*@example.com"} | select-object Timestamp,SourceContext,Source,EventId,MessageSubject,Sender,{$_.Recipients} | export-csv C:ExchangeLogResults.txt

Exchange SAN Certificaat aanvragen

Een Exchange certificaat aanvragen op basis van SAN (Subject Alternative Name) is een vrij eenvoudig. Hieronder een voorbeeld:

New-ExchangeCertificate -FriendlyName 'webmail.test.nl' -GenerateRequest -PrivateKeyExportable $true -KeySize '2048' -SubjectName 'C=NL,S="Zuid-Holland",L="Rotterdam",O="Bedrijfsnaam uit de KvK",OU="IT",CN=webmail.test.nl' -DomainName 'webmail.test.nl','autodiscover.test.nl','smtp.test.nl','autodiscover.test2.nl','webmail.test2.nl','outlookanywhere.test.nl','clusternaam.test.nl' -Server 'server waarop de aanvraag gedaan wordt'

Exchange HUB servers

Wanneer er een e-mail wordt verzonden in een Microsoft Exchange 2010 organisatie gaat het transport proces als volgt:

Exchange kijkt binnen de Active Directory Site waar het mailtje wordt gesubmit naar een beschikbare HUB Transport server om de e-mail te versturen. De HUB Transport servers accepteren de e-mail als de services draaien. Er wordt niet gekeken naar de mogelijkheid om het mailtje daadwerkelijk te versturen. Als de HUB Transport server een Send connector heeft is dat voldoende. Stel er is geen Send connector toegewezen met als address space * dan kan de HUB server het mailtje niet kwijt. Er is makkelijk in de Exchange console te kijken naar de wachtrij binnen Exchange.

Get-TransportServer | Get-Queue

Er wordt dan een lijst uitgedraaid met de queue’s van alle server binnen de Exchange organisatie. Er is dus ook makkelijk te zien welke server mogelijk een probleem heeft de mail te versturen.

Andere nuttige commando’s zijn:

Overzicht uitdraaien van users op een mailbox server
Get-MailboxDatabase "Mailbox Database Naam" | Get-Mailbox