Use Exchange EWS/Powershell to Copy Outlook Quick Copy AKA Quick Step Settings

Wow , possible my biggest EWS Powershell script, Big thanks go to Glen for the missing piece of the jigsaw. The project started as a way to copy Quick Copy settings between users when needed.

Outlook doesn’t provide much functionality to do this itself, you can use the famous redemtion.dll for this task  http://www.dimastr.com/redemption/rdoquicksteps.htm , but I’m more of a server side guy than a client side, Our Outlook Enviroment has too many macros already!

I knew how to get more Inbox items , but have never dived into the “Associated Contents Table”. Using the free MFCMAPI.exe tool , I explored the mailbox to find the folder I need as well as the table and after hours or tinkering and borrowing code we are good!

You will need to go through and change the values in %

This is the download script , I will paste the SOAP upload script in another post

$mailbox = Get-Mailbox %mailbox%
$mailAddress = $mailbox.PrimarySmtpAddress.ToString();
 
[Reflection.Assembly]::LoadFile("C:\Program Files (x86)\Microsoft\Exchange\Web Services\2.1\Microsoft.Exchange.WebServices.dll") | Out-Null
$s = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP1)
$s.AutodiscoverUrl($mailAddress);
 
#needed for XML Soap
$cred = New-Object System.Net.NetworkCredential("%username%","%password%")
 
$windowsIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$sidbind = "LDAP://<SID=" + $windowsIdentity.user.Value.ToString() + ">"
$aceuser = [ADSI]$sidbind
$s.Credentials = $cred
 
$MailboxRootid = new-object  Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$mailAddress)
$MailboxRoot = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,$MailboxRootid)
 
# Get Folder ID from Path
Function GetFolder()
{
	# Return a reference to a folder specified by path
 
	$RootFolder, $FolderPath = $args[0];
 
	$Folder = $RootFolder;
	if ($FolderPath -ne '\')
	{
		$PathElements = $FolderPath -split '\\';
		For ($i=0; $i -lt $PathElements.Count; $i++)
		{
			if ($PathElements[$i])
			{
				$View = New-Object  Microsoft.Exchange.WebServices.Data.FolderView(2,0);
				$View.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep;
				$View.PropertySet = [Microsoft.Exchange.WebServices.Data.BasePropertySet]::IdOnly;
 
				$SearchFilter = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName, $PathElements[$i]);
 
				$FolderResults = $Folder.FindFolders($SearchFilter, $View);
				if ($FolderResults.TotalCount -ne 1)
				{
					# We have either none or more than one folder returned... Either way, we can't continue
					$Folder = $null;
					Write-Host "Failed to find " $PathElements[$i];
					Write-Host "Requested folder path: " $FolderPath;
					break;
				}
 
				$Folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s, $FolderResults.Folders[0].Id)
			}
		}
	}
 
	$Folder;
}
#choose the folder name you want to download the Configuration items from
$folderobject = GetFolder($MailboxRoot, "\Quick Step Settings\");
$sfSearchFilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.ItemSchema]::ItemClass, "IPM.Microsoft.CustomAction")
$Itemview = new-object Microsoft.Exchange.WebServices.Data.ItemView(20)
$ItemView.PropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
$ItemView.Traversal = [Microsoft.Exchange.Webservices.Data.ItemTraversal]::Associated
#$folderid = new-object  Microsoft.Exchange.WebServices.Data.Folderid([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Root,$mailAddress)
$folderid = $folderobject.Id
$InboxFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,$folderid)
$pspropset = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.ItemSchema]::MimeContent)
$mails  = $inboxFolder.finditems($sfSearchFilter,$Itemview)
 
#loop to go through all the items in the folder
$count=0
foreach($Item in $mails.Items)
{ 
 
#gets the id for the SOAP XML Request
$itemid = $mails.Items[$count].Id.Uniqueid
 
$expRequest = @"
<?xml version="1.0" encoding="utf-8" ?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:xsd="http://www.w3.org/2001/XMLSchema"
      xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
      xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
      xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages">
  <soap:Header>
    <t:RequestServerVersion Version="Exchange2010_SP1" />
  </soap:Header>
  <soap:Body>
    <m:ExportItems>
      <m:ItemIds>
        <t:ItemId Id="$itemid"/>
      </m:ItemIds>
    </m:ExportItems>
  </soap:Body>
</soap:Envelope>
"@
$mbMailboxFolderURI = New-Object System.Uri($s.url)
$wrWebRequest = [System.Net.WebRequest]::Create($mbMailboxFolderURI)
$wrWebRequest.KeepAlive = $false;
$wrWebRequest.Headers.Set("Pragma", "no-cache");
$wrWebRequest.Headers.Set("Translate", "f");
$wrWebRequest.Headers.Set("Depth", "0");
$wrWebRequest.ContentType = "text/xml";
$wrWebRequest.ContentLength = $expRequest.Length;
$wrWebRequest.Timeout = 60000;
$wrWebRequest.Method = "POST";
$wrWebRequest.Credentials = $cred
$bqByteQuery = [System.Text.Encoding]::ASCII.GetBytes($expRequest);
$wrWebRequest.ContentLength = $bqByteQuery.Length;
$rsRequestStream = $wrWebRequest.GetRequestStream();
$rsRequestStream.Write($bqByteQuery, 0, $bqByteQuery.Length);
$rsRequestStream.Close();
$wrWebResponse = $wrWebRequest.GetResponse();
$rsResponseStream = $wrWebResponse.GetResponseStream()
$sr = new-object System.IO.StreamReader($rsResponseStream);
$rdResponseDocument = New-Object System.Xml.XmlDocument
$rdResponseDocument.LoadXml($sr.ReadToEnd());
$Datanodes = @($rdResponseDocument.getElementsByTagName("m:Data"))
$Datanodes
if ($Datanodes.length -ne 0){
	$Data = [System.Convert]::FromBase64String($Datanodes[0].'#text')
#file location
	$fsFileStream = new-object system.io.filestream C:\%folder%\quickcopy$count, ([io.filemode]::create), ([io.fileaccess]::write), ([io.fileshare]::none)
	$fsFileStream.Write($Data, 0, $Data.Length);
    $fsFileStream.Close();
}
$count= $count+1 
 
	}

 

VN:F [1.9.22_1171]
Rating: 1.0/10 (2 votes cast)
VN:F [1.9.22_1171]
Rating: -2 (from 2 votes)
Use Exchange EWS/Powershell to Copy Outlook Quick Copy AKA Quick Step Settings, 1.0 out of 10 based on 2 ratings

Tags: Associated Contents Table, binary, Download, EWS, file, IPF.Configuration, IPM.Microsoft.CustomAction, powershell, Quick Copy, Quick Step Settings, SOAP, UserConfigurationProperties

Trackback from your site.