21 May 2014

New-exchangecertificate for Exchange EDGE 2010

Do this after office hours or in a service window, because the risk exists that mail flow may come to a halt because the edgesync subscription certificate don't match anymore. I found out the hard way.

Generate a new certificate request:

$data = New-ExchangeCertificate -GenerateRequest -SubjectName "cn=mx03.domain.com" -domainname mx03.domain.com, sr-XXXXX.domain.lan, sr-XXXXX -friendlyname mx03.domain.com -PrivateKeyExportable $true
Set-Content -Path "c:\Temp\mailcert.req" -Value $Data

Import the request into the PKI website http://servername/certsrv

Request a new Certificate

Submit a certificate request by using a base-64-encoded CMC or PKCS #10 file, or submit a renewal request by using a base-64-encoded PKCS #7 file

Enter the request code and press Submit

On the PKI environment Issue the requested certificate and export the new certificate.

On the EDGE server copy the certificate to a folder.

To import the certificate in Powershell:

Import-ExchangeCertificate -FileData ([Byte[]]$(Get-Content -Path c:\certificates\ExportedCert.cer -Encoding byte -ReadCount 0))

Check the thumbprint to use in the next commandlet:

Get-exchangecertificate | fl

Use the thumbprint in the following line:

Enable-ExchangeCertificate -Thumbprint 5113ae0233a72XXXXXXXXXXXXXXXX8675333d010e -Services SMTP

Then recreate the EdgeSync Subcription

new-edgesyncsubcription -filepath "C:\temp\filename.xml"

Export the XML file to your CAS server and create a new Edgesync subscription.

The problem right now is we do not refresh the certificate used by ADAM when issue a new subscription, so if you have created a new certificate, we keep presenting the old one. Ok, so here's what you need to do to get ADAM to present the new one:
1. On the Hub, Remove the Subscription
2. On the Edge, Remove the cert used by ADAM to establish secure
connections. You can do this by following the following steps:
  • a. Open up an empty mmc console (Run -> mmc)
  • b. Select File -> Add / Remove Snap-in
  • c. Hit Add
  • d. Select "Certificates" from the List of Snap-Ins available, and
  • hit Add.
  • e. Select "Service Account" on the "Certificates Snap-In" page,
  • click next.
  • f. Select "Local Computer" on the "Select Computer" page, click
  • next.
  • g. Select "Microsoft Exchange ADAM" from the list of services,
  • click Finish.
  • h. Close the "Add Snap-in" dialog.
  • i. Navigate to "Certifcates – Service" ->
  • "ADAM_MSExchange\Personal" -> Certificates
  • j. You should see a single certificate here. Remove it.
3. On the Edge, Unsubscribe, then create a new subscription file
(you should see a new certificate show up at this point on the ADAM cert container from the step above) by calling new-edgesubscription
New-EdgeSubscription -FileName "Path to file".xml
4. Re-start the "Microsoft Exchange ADAM" service.
5.Export the file to the Hub server.
6.On the Hub server import the new subscription.
7.Create a new Edge subscription in the EMC

Then you have to wait a few minutes.

To check if synchronization works run;


14 May 2014

Sync Folders and files with Powershell and send notification email

I needed a way to sync some files and folders to another disc, as Allwaysync only permits less than 40.000 items per sync.
I came across a nice script from here.

But it did not exactly do what i needed it to do so adjustments were made.
I didnt need it to check the destination against the source, so got rid of that,
and made a way for it to email me the results as it had
finished comparing and syncing.

The script looks like this now:

function Get-FileMD5 {
    $mode = [System.IO.FileMode]("open")
    $access = [System.IO.FileAccess]("Read")
    $md5 = New-Object System.Security.Cryptography.MD5CryptoServiceProvider
    $fs = New-Object System.IO.FileStream($file,$mode,$access)
    $Hash = $md5.ComputeHash($fs)
    [string]$Hash = $Hash
    Return $Hash
# Source from http://bsonposh.com/archives/231

$logfile = "C:\temp\foldersync.log"

function Copy-LatestFile{
     $File1Date = get-Item $File1 | foreach-Object{$_.LastWriteTimeUTC}
     $File2Date = get-Item $File2 | foreach-Object{$_.LastWriteTimeUTC}
     if($File1Date -gt $File2Date)
         write-output "$File1 is Newer… Copying…" | out-file $logfile -Append
         if($whatif){Copy-Item -path $File1 -dest $File2 -force -whatif}
         else{Copy-Item -path $File1 -dest $File2 -force}
         write-output "$File2 is Newer… Copying…" | out-file $logfile -Append
         if($whatif){Copy-Item -path $File2 -dest $File1 -force -whatif}
         else{Copy-Item -path $File2 -dest $File1 -force}
     write-output | out-file $logfile

if(!(test-Path $Destination))
     New-Item $Destination -type Directory -force | out-Null

# Getting Files/Folders from Source and Destination
$SrcEntries = Get-ChildItem $Source -Recurse -Force
$DesEntries = Get-ChildItem $Destination -Recurse -Force

# Parsing the folders and Files from Collections
$Srcfolders = $SrcEntries | Where-Object{$_.PSIsContainer}
$SrcFiles = $SrcEntries | Where-Object{!$_.PSIsContainer}
$Desfolders = $DesEntries | Where-Object{$_.PSIsContainer}
$DesFiles = $DesEntries | Where-Object{!$_.PSIsContainer}

# Checking for Folders that are in Source, but not in Destination
foreach($folder in $Srcfolders)
     $SrcFolderPath = $source -replace "\\","\\" -replace "\:","\:"
     $DesFolder = $folder.Fullname -replace $SrcFolderPath,$Destination
     if($DesFolder -ne ""){
         if(!(test-path $DesFolder))
             write-output "Folder $DesFolder Missing. Creating it!" | out-file $logfile -Append
             new-Item $DesFolder -type Directory | out-Null

# Checking for Files that are in the Source, but not in Destination
foreach($entry in $SrcFiles)
     $SrcFullname = $entry.fullname
     $SrcName = $entry.Name
     $SrcFilePath = $Source -replace "\\","\\" -replace "\:","\:"
     $DesFile = $SrcFullname -replace $SrcFilePath,$Destination
     if(test-Path $Desfile)
         $SrcMD5 = Get-FileMD5 $SrcFullname
         $DesMD5 = Get-FileMD5 $DesFile
         If($srcMD5 -ne $desMD5)
             write-output "The Files MD5′s are Different… Checking Write Dates" | out-file $logfile -Append
             write-output $SrcMD5 | out-file $logfile
             write-output $DesMD5 | out-file $logfile
             Copy-LatestFile $SrcFullname $DesFile
         write-output "$Desfile Missing… Copying from $SrcFullname" | out-file $logfile -Append
         copy-Item -path $SrcFullName -dest $DesFile -force

$smtpto = "user@domain.com"
$smtpfrom = "FolderSync@domain.com"
$messagesubject = "FolderSync results $finishtime"
$smtpServer = "smtp.domain.com"

out-file $Logfile -Append

$finishTime = get-date -format "dd-MM-yy HH-mm"
"Backup script finished at $finishTime" | out-file $logFile -Append -Force

$message = New-Object System.Net.Mail.MailMessage $smtpfrom, $smtpto
$message.Subject = $messageSubject
$message.IsBodyHTML = $false
$finished = get-content $LogFile
$message.Body = ( $Finished | out-string )
$message.Body = $Finished
write-host 'Sending email'
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
Write-Host "Email sent"

remove-item $Logfile

After this you can schedule it in task manager:

powershell -command "& 'E:\path to script\scriptname.ps1 X:\source Y:\destination' "

Sending email with powershell fails, 5.7.1 Client not authenticated

The error powershell throws at you:

Exception calling “Send” with “1″ argument(s): “The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.7.1 Client was not authenticated”

When using the following:
#Send email message
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)

Needs another line and becomes this:

#Send email message
$smtp = New-Object Net.Mail.SmtpClient($smtpServer)
$smtp.UseDefaultCredentials = $true

Email delivers correctly.