EWS Powershell: Set HomePageURL
I'm so close its frustrating
Building a powershell app to add a folder to a mailbox and set it with a homepage. I can create the folder and my code below sets the PR_FOLDER_WEBVIEWINFO property, but its not setting the correct value. If looking at MFCMapi the value I'm setting appears
under "Value (alternative text)" rather than "Value"....
Here's the code, the $Encoded URL value is valid as if I input this directly into MFCMapi then the 'homepage' appears...
$EncodedURL = "020000000100000001000000000000000000000000000000000000000000000000000000000000002000000068007400740070003A002F002F00620069006E0067002E0063006F006D000000"
$bqByteArray = [System.Text.Encoding]::ASCII.GetBytes($EncodedURL)
$PR_FOLDER_WEBVIEWINFO = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(14047,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Binary)
$NewFolder.SetExtendedProperty($PR_FOLDER_WEBVIEWINFO,$bqByteArray)
$NewFolder.update()
It's almost as if my $EncodedURL should be the byte array, but if I try to use
$NewFolder.SetExtendedProperty($PR_FOLDER_WEBVIEWINFO,$EncodedURL) it just fails.... A little guidance please
Hmm, Get errors with your code. Here's something I've put together. Very similar and wished I had seen yours a bit earlier. Would have made the task easier. Working on adding Get-Mailbox for all mailbox users.
Open to suggestions.
# Script is designed to create a new folder in Outlook and add a homepage URL
# Tested using Exchange Server 2007SP1/2010SP1
# Works for a single user only. Future designs to apply to Get-Mailbox users.
# This file should be named with a *.ps1 extension to run. If need be, rename the file.
# It is assumed this file and the associated dll are located in C:\Temp\, else
# Update the $LogFile and $dllpath accordingly
# User Settings
$newFolderName = "Google"
$CustomURL = "http://google.co.nz"
$MailboxName = "[email protected]"
$MailboxPwd = "pwd"
$Domain = "" #Not Used yet
$MbAdmin = "" #Not Used yet
$MbAdminPwd = "" #Not Used yet
$dllpath = "c:\temp\Microsoft.Exchange.WebServices.dll"
[string]$LogFile = "C:\Temp\Log.txt" # Path of the Log File
Import-Module $dllpath
[string]$info = "White" # Color for informational messages
[string]$warning = "Yellow" # Color for warning messages
[string]$error = "Red" # Color for error messages
#Setup the service for the appropriate version of Exchange
#$Service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1)
$Service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP1)
#$Service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2)
#$Service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2013)
#Set login credentials
#$Service.Credentials = New-Object System.Net.NetworkCredential($MailboxName,$MailboxPwd,$Domain)
$Service.Credentials = New-Object Microsoft.Exchange.WebServices.Data.WebCredentials($MailboxName,$MailboxPwd)
#Use hardcoded CAS Server URL or use Autodiscover
#$service.Url= new-object Uri(http://CAS-Server/EWS/Exchange.asmx)
$Service.AutodiscoverUrl($MailboxName,{$true})
Write-host "EWS URL set to :" $Service.Url -foregroundcolor $info
#Connect to users MsgFolderRoot and search for $newFolderName
$RootFolderID = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$MailboxName)
$RootFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($Service,$RootFolderID)
$FolderView = New-Object Microsoft.Exchange.WebServices.Data.FolderView(1) #Custom value. Enable the following line for +10
#$FolderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep
$SfSearchFilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName,$newFolderName)
$findFolderResults = $service.FindFolders($RootFolderID,$SfSearchFilter,$FolderView)
# If $newFolderName found, say so.
if ($findFolderResults.TotalCount -ne 0){
Write-host "Folder already exists for" $MailboxName -foregroundcolor $info
#Delete the folder ? ?
#$newFolderName.delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::SoftDelete) #DeletedItems
#$newFolderName.delete([Microsoft.Exchange.WebServices.Data.DeleteMode]::HardDelete)
# DON'T CHANGE BELOW THIS LINE
# If $newFolderName not found create it and set homepage URL
if ($findFolderResults.TotalCount -eq 0){
Write-host $MailboxName ": Folder not found... Creating" -foregroundcolor $warning >> $Logfile
# Create the folder
$NewFolder = new-object Microsoft.Exchange.WebServices.Data.Folder($service)
$NewFolder.DisplayName = $newFolderName
$NewFolder.Save($RootFolderID)
# Do the real work!
# Generate HEX of URL
$CharArray = $CustomURL.ToCharArray();
$homepagebytes = $null
Foreach ($Char in $CharArray) {$homepagebytes = $homepagebytes + [System.String]::Format("{0:X}", [System.Convert]::ToUInt32($Char))+"00"}
# String together the value for PR_FOLDER_WEBVIEWINFO
$dwversion = "02"
$dwType = "00000001"
$dwFlags = "00000001"
$dwUnused = "00000000000000000000000000000000000000000000000000000000"
$cbDataSizePadding = "000000"
$cbDataSize = (($homepagebytes.length / 2)+2).ToString($x)
$cbDataSizePadding2 = "000000"
$homepagebytesPadding = "0000"
$HexURL = $dwversion + $dwType + $dwFlags + $dwUnused + $cbDataSizePadding + $cbDataSize + $cbDataSizePadding2 + $homepagebytes + $homepagebytesPadding
# $HexURL = "020000000100000001000000000000000000000000000000000000000000000000000000000000002000000068007400740070003A002F002F00620069006E0067002E0063006F006D000000"
# Convert $HexURL to a Bytearray then Base64
$bytes2 = @($HexURL -split '([a-f0-9]{2})' | foreach-object { if ($_) {[System.Convert]::ToByte($_,16)}})
$Base64URL = [System.Convert]::ToBase64String($bytes2);
# $Base64URL = "AgAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAABoAHQAdABwADoALwAvAGIAaQBuAGcALgBjAG8AbQAAAA=="
# read/write the URL into $PR_FOLDER_WEBVIEWINFO
$bytes = [System.Convert]::FromBase64String($Base64URL);
$PR_FOLDER_WEBVIEWINFO = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(14047,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Binary)
$NewFolder.SetExtendedProperty($PR_FOLDER_WEBVIEWINFO,$bytes)
#Save
$NewFolder.update()
Write-host "Created for" $MailboxName -foregroundcolor $info >> $Logfile
Write-host "Finished" -foregroundcolor $info
# Credits to the following in no particular order:
# Plus many many more. Thanks to you all.
Similar Messages
-
Powershell: Set Access Based Enumeration on share in Failover Cluster
Hi guys,
I'm facing the following problem. Below you see my script to create a shared folder. (My folder share is visible in failover cluster manager, underneath clustergroup TESTSTO01.)
Now I need to enable Access Based Enumeration on this share. Has anyone a clue how to do that in powershell? (Version 2).
I also need to make sure that the files and programs are not available offline.
Thanks in advance!
$SHARE_READ = 1179817 # 100100000000010101001
$SHARE_CHANGE = 1245631 # 100110000000100010110
$SHARE_FULL = 2032127 # 111110000000111111111
$SHARE_NONE = 1 # 000000000000000000001
$ACETYPE_ACCESS_ALLOWED = 0
$ACETYPE_ACCESS_DENIED = 1
$ACETYPE_SYSTEM_AUDIT = 2
$ACEFLAG_INHERIT_ACE = 2
$ACEFLAG_NO_PROPAGATE_INHERIT_ACE = 4
$ACEFLAG_INHERIT_ONLY_ACE = 8
$ACEFLAG_INHERITED_ACE = 16
$ACEFLAG_VALID_INHERIT_FLAGS = 31
$ACEFLAG_SUCCESSFUL_ACCESS = 64
$ACEFLAG_FAILED_ACCESS = 128
# New Trustee
function New-Trustee($Domain, $User)
$Trustee = ([WMIClass]"\\TESTSTO01\root\cimv2:Win32_Trustee").CreateInstance()
$Trustee.Domain = $Domain
$Trustee.Name = $User
if ($User -eq "Administrators")
{$Trustee.SID = @(1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0,32,2,0,0)}
else
{$Trustee.SID = @(1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0)}
return $Trustee
# New ACE
function New-ACE($Domain, $User, $Access, $Type, $Flags)
$ACE = ([WMIClass]"\\TESTSTO01\root\cimv2:Win32_ACE").CreateInstance()
$ACE.AccessMask = $Access
$ACE.AceFlags = $Flags
$ACE.AceType = $Type
$ACE.Trustee = New-Trustee $Domain $User
return $ACE
# Get SD
function Get-SD
$sd = ([WMIClass]"\\TESTSTO01\root\cimv2:Win32_SecurityDescriptor").CreateInstance()
$ACE1 = New-ACE -Domain $null -User "Everyone" -Access $SHARE_CHANGE -Type $ACETYPE_ACCESS_ALLOWED -Flags $ACEFLAG_INHERIT_ACE
$ACE2 = New-ACE -Domain $null -User "Administrators" -Access $SHARE_FULL -Type $ACETYPE_ACCESS_ALLOWED -Flags $ACEFLAG_INHERIT_ACE
[System.Management.ManagementObject[]] $DACL = $ACE1, $ACE2
$sd.DACL =$DACL
return $sd
# Create-Share
function Create-Share($ShareName, $Path, $Comment,$Access)
$checkShare = (Get-WmiObject Win32_Share -Filter "Name='$ShareName'")
if ($checkShare -ne $null) {
# "Share exists and will now be deteted!!!"
get-WmiObject Win32_Share -Filter "Name='$ShareName'" | foreach-object { $_.Delete() }
$wmishare = [WMIClass] "\\TESTSTO01\ROOT\CIMV2:Win32_Share"
$Access = Get-SD
$R = $wmishare.Create($Path,$Sharename,0,$null,$Comment,"", $Access)
if ($R.ReturnValue -ne 0) {
Write-Error "Error while creating share: " + $R.ReturnValue
exit
# Write-Host "Share has been created."
# Create first share with permissons **********************************
$ShareName = "$Company$"
$Path = "$Driveletter" + ":\$Company"
$Comment = ""
$Domain = $Null
Create-Share $ShareName $Path $Comment $AccessUnable to find type [CmdletBinding(SupportsShouldProcess=$TRUE)]: make sure tha
t the assembly containing this type is loaded.
At C:\Script Nathalie\Everyware2.ps1:294 char:45
+ [CmdletBinding(SupportsShouldProcess=$TRUE)] <<<<
+ CategoryInfo : InvalidOperation: (CmdletBinding(S...dProcess=$T
RUE):String) [], RuntimeException
+ FullyQualifiedErrorId : TypeNotFound
The term 'param' is not recognized as the name of a cmdlet, function, script fi
le, or operable program. Check the spelling of the name, or if a path was inclu
ded, verify that the path is correct and try again.
At C:\Script Nathalie\Everyware2.ps1:295 char:6
+ param <<<< (
+ CategoryInfo : ObjectNotFound: (param:String) [], CommandNotFou
ndException
+ FullyQualifiedErrorId : CommandNotFoundException
The term 'begin' is not recognized as the name of a cmdlet, function, script fi
le, or operable program. Check the spelling of the name, or if a path was inclu
ded, verify that the path is correct and try again.
At C:\Script Nathalie\Everyware2.ps1:304 char:6
+ begin <<<< {
+ CategoryInfo : ObjectNotFound: (begin:String) [], CommandNotFou
ndException
+ FullyQualifiedErrorId : CommandNotFoundException
Get-Process : Cannot evaluate parameter 'Name' because its argument is specifie
d as a script block and there is no input. A script block cannot be evaluated w
ithout input.
At C:\Script Nathalie\Everyware2.ps1:331 char:8
+ process <<<< {
+ CategoryInfo : MetadataError: (:) [Get-Process], ParameterBindi
ngException
+ FullyQualifiedErrorId : ScriptBlockArgumentNoInput,Microsoft.PowerShell.
Commands.GetProcessCommand
The term 'end' is not recognized as the name of a cmdlet, function, script file
, or operable program. Check the spelling of the name, or if a path was include
d, verify that the path is correct and try again.
At C:\Script Nathalie\Everyware2.ps1:345 char:4
+ end <<<< {
+ CategoryInfo : ObjectNotFound: (end:String) [], CommandNotFound
Exception
+ FullyQualifiedErrorId : CommandNotFoundException
The term 'set-shareABE' is not recognized as the name of a cmdlet, function, sc
ript file, or operable program. Check the spelling of the name, or if a path wa
s included, verify that the path is correct and try again.
At C:\Script Nathalie\Everyware2.ps1:348 char:13
+ set-shareABE <<<< TESTSTO01 $Company$ -Enable
+ CategoryInfo : ObjectNotFound: (set-shareABE:String) [], Comman
dNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException -
Get items in all Outlook folders using EWS (PowerShell)
Hi All,
I'm trying to figure out how to search all items in Outlook mailbox using EWS. I have a script that currently search "Sent Items" only. See script below. I just need to modify it to search all folders instead. Any help is appreciated. Thank you
$Report = @()
#Provide text files for all users in the legal department
$Law = cat law.txt
#Set Date to 1 Year Ago
$Date = (Get-Date).AddYears(-1)
#Logon to Exchange Web Service with default credentials
Add-Type -Path "C:\Program Files\Microsoft\Exchange\Web Services\1.2\Microsoft.Exchange.WebServices.dll"
$sid = [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value
$user = [ADSI]"LDAP://<SID=$sid>"
$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService -ArgumentList ([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2)
$service.AutodiscoverUrl($user.Properties.mail)
Write-Progress -Activity "Preparing" -Status "Retrieving mailbox list" -PercentComplete 0
#Get Mailboxes for all users in the text file
$Mailboxes = $law | Get-User | Select WindowsEmailAddress, Company
$Count = $Mailboxes.Count
#Go through each users found and process accordingly
ForEach ($Mailbox in $Mailboxes){
$DisplayName = $Mailbox.DisplayName
$i = $i + 1
$pct = $i/$Count * 100
Write-Progress -Activity "Collecting mailbox details" -Status "Processing mailbox $i of $Count - $DisplayName" -PercentComplete $pct
Try {
$Ok = $true
$Mailbox = (Get-Mailbox $mailbox.WindowsEmailAddress -ErrorAction Stop ).PrimarySMTPAddress}
catch [System.Exception]{
$Ok = $false
if ($Ok){
#Set EWS up to impersonationate user
$ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId -ArgumentList ([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress),$Mailbox
$service.ImpersonatedUserId = $ImpersonatedUserId
#Open user folder and bind SentItems folder to the EWS service.
$folderid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::SentItems,$Mailbox)
$SentFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)
#Specify Search Filters: Specify Date and Message Class Type
$Sfir = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsGreaterThanOrEqualTo([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::DateTimeSent, $Date)
$Sfir2 = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::ItemClass, "IPM.Note")
#Add search filters together to form one search
$sfCollection = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollection([Microsoft.Exchange.WebServices.Data.LogicalOperator]::AND);
$sfCollection.Add($Sfir)
$sfCollection.Add($Sfir2)
#Create PropertySet to make it possible to retreive all properties of email content
$psPropset = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
$SentItemsview = new-object Microsoft.Exchange.WebServices.Data.ItemView(1000)
$fiItems = $null
#Loop through all all items in 1000 page increment until all items are processed
Do {
#Find Items based on folder Id, search filter and page view
$fiItems = $Service.FindItems($SentFolder.Id,$sfCollection,$SentItemsView)
#Create PropertySet to make it possible to retreive all properties of email content
[Void]$service.LoadPropertiesForItems($fiItems,$psPropset)
#Loop through each email item and retrieve recipients info.
ForEach ($item in $fiItems)
$AllAttendees = $item.ToRecipients | Select -Expand Address
$AllAttendees += $item.CCRecipients | Select -Expand Address
$AllAttendees += $item.BCCRecipients | Select -Expand Address
$sender = $item.From.Address
$subject = $item.Subject
$TimeSent = $item.DateTimeSent
Write-Host "$Sender --- mailbox --- $TimeSent"
for ($index = 0; $index -lt $AllAttendees.count; $index++) {
Write-Progress -Activity "Looping" -Status "Going through all recipients list" -PercentComplete 0
$Attendees = $AllAttendees[$index]
#Filter invalid users, external users and users in Legal department
If ($Attendees -like "*domain.com"){
If ($Law -notcontains $Attendees){
$a = Get-User $Attendees -filter {Company -ne $null} -ErrorAction SilentlyContinue
if ($a){
$Obj = New-Object -TypeName PSObject
$Obj | Add-Member -MemberType NoteProperty -Name Subject -Value $subject
$Obj | Add-Member -MemberType NoteProperty -Name Sender -Value $sender
$Obj | Add-Member -MemberType NoteProperty -Name Sent -Value $TimeSent
$Obj | Add-Member -MemberType NoteProperty -Name Recipients -Value $Attendees
$Report += $Obj
$SentItemsView.Offset += $fiItems.Items.Count
While ($fiItems.MoreAvailable -eq $true)
#Export report to CSV
$Report | Export-Csv "C:\Users\user\Dropbox\Script\LawData.csv" -NoTypeInformation -Encoding UTF8
TundeIt seems the answer is here:
http://gsexdev.blogspot.com/2011/08/using-allitems-search-folder-from.html.
I'll go through it and let you if successfully.
Thanks
Tunde
Tunde -
Powershell Setting Share Folder Permissions
I have a script that create a shared folder and I am trying to set permissions. Here is what I have so far:
$serverName = "myfileserver"
$folderName = "d:\Personal"
$shareName = $newSAM+"$"
$fullName = "\\$serverName\"+$folderName.Replace(":", "$")+"\$newSAM"
# Creating the Directory
$finalResult = New-Item $fullName -type directory
$trustee = ([wmiclass]"Win32_trustee").psbase.CreateInstance()
$trustee.Domain = "domain.com"
$trustee.Name = $newSAM
$ace = ([wmiclass]"Win32_ACE").psbase.CreateInstance()
$ace.AccessMask = 2032127
$ace.AceFlags = 3
$ace.AceType = 0
$ace.Trustee = $trustee
$trustee2 = ([wmiclass]"Win32_trustee").psbase.CreateInstance()
$trustee2.Domain = "domain.com"
$trustee2.Name = "administrator"
$ace2 = ([wmiclass]"Win32_ACE").psbase.CreateInstance()
$ace2.AccessMask = 2032127
$ace2.AceFlags = 3
$ace2.AceType = 0
$ace2.Trustee = $trustee2
$trustee3 = ([wmiclass]"Win32_trustee").psbase.CreateInstance()
$trustee3.Domain = $serverName
$trustee3.Name = "administrator"
$ace3 = ([wmiclass]"Win32_ACE").psbase.CreateInstance()
$ace3.AccessMask = 2032127
$ace3.AceFlags = 3
$ace3.AceType = 0
$ace3.Trustee = $trustee3
$sd = ([wmiclass]"Win32_SecurityDescriptor").psbase.CreateInstance()
$sd.ControlFlags = 4
$sd.DACL = $ace, $ace2, $ace3
$sd.group = $trustee3
$sd.owner = $trustee3
# Creating the Folder Share
$finalResult = Invoke-WmiMethod -Class win32_share -name Create -ArgumentList @($sd,"",4294967295,$shareName,"","$folderName\$newSAM",0) -computername $serverName
The folder is created correctly but I am getting this error when setting permissions:
Exception setting "DACL": "Unable to cast object of type 'System.Management.Automation.PSObject' to type 'System.Manage
ment.ManagementBaseObject'."I am testing it against a remote 2003 R2 SP2 server...
I have upgraded to Powershell v3 in my frustation (although I would rather have worked with the default like our helpdesk folks who will be running this - now we have to install this on all their machines)... Anyway...
I do not get any more errors when I run it, but it still does not add and share permissions... All it had is 'Everyone' as the sole group in the Permissions area...
Here again is the code I ran:
$serverName = "myServer"
$folderName = "d:\Users"
$shareName = $newSAM+"$"
$fullName = "\\$serverName\"+$folderName.Replace(":", "$")+"\$newSAM"
# Creating the Directory
$finalResult = New-Item $fullName -type directory
# AccessMasks:
# 2032127 = Full Control
# 1245631 = Change
# 1179817 = Read
$trustee = ([wmiclass]"Win32_trustee").psbase.CreateInstance()
$trustee.Domain = "domain"
$trustee.Name = "administrator"
$ace = ([wmiclass]"Win32_ACE").psbase.CreateInstance()
$ace.AccessMask = 2032127
$ace.AceFlags = 3
$ace.AceType = 0
$ace.Trustee = $trustee
$trustee2 = ([wmiclass]"Win32_trustee").psbase.CreateInstance()
$trustee2.Domain = "BUILTIN" #Or domain name
$trustee2.Name = "Administrators"
$ace2 = ([wmiclass]"Win32_ACE").psbase.CreateInstance()
$ace2.AccessMask = 2032127
$ace2.AceFlags = 3
$ace2.AceType = 0
$ace2.Trustee = $trustee2
$trustee3 = ([wmiclass]"Win32_trustee").psbase.CreateInstance()
$trustee3.Domain = "domain"
$trustee3.Name = $newSAM
$ace3 = ([wmiclass]"Win32_ACE").psbase.CreateInstance()
$ace3.AccessMask = 2032127
$ace3.AceFlags = 3
$ace3.AceType = 0
$ace3.Trustee = $trustee3
$sd = ([wmiclass]"Win32_SecurityDescriptor").psbase.CreateInstance()
$sd.ControlFlags = 4
$sd.DACL = [System.Management.ManagementBaseObject[]] ($ace, $ace3)
$sd.group = $trustee2
$sd.owner = $trustee2
# Creating the Folder Share
$finalResult = Invoke-WmiMethod -Class win32_share -name Create -ArgumentList @($sd, "", 4294967295, $shareName, "", "$folderName\$newSAM", 0) -computername $serverName -EnableAllPrivileges
I will change this manually so that I perform this on my laptop and report what results I get.... -
When I run the Set-AzureSqlDatabase command to update the SQL Edition, using the
-Edition parameter, and try to change it back to the previously configured edition, I receive a message saying:
Set-AzureSqlDatabase : A service objective assignment on server 'cvhgaeh2v0' and database 'Trevor01DB' is already in progress. Please wait until the service objective assignment state for the database is marked as 'Completed'.
Can someone please help me understand what this means? What exactly is a
service objective assignment?
I am using Windows PowerShell 5.0 September Preview on Windows
8.1 Professional with Update, and the Azure PowerShell module version
0.8.8.
Cheers,
Trevor Sullivan
Microsoft MVP: PowerShell
If this post was helpful, please click the little "Vote as Helpful" button :)
Trevor Sullivan
Trevor Sullivan's Tech Room
Twitter ProfileHi,
You can Specify the service tier, the performance level, and the maximum size for the database by using Set-AzureSqlDatabase –ServiceObjective.
More information :
http://msdn.microsoft.com/en-us/library/azure/dn369872.aspx
-ServiceObjective<ServiceObjective>
If specified, an object representing the new service objective for this database.
http://msdn.microsoft.com/library/azure/dn546732.aspx
Regards,
Mekh. -
Send email (c#) using ews and set custom display name (from)
How to connect to exchange service via exchange web services send a mail and the display name is custom ?
With this code, just connect to exchange server (ews) and send a mail.
How to change my code ?
private void t() {
const string subjectBody = "test email ";
const string username = "username";
const string password = "password";
const string domain = "domain";
const string ewsURL = "http://exchangesrv/ews/exchange.asmx";
unews.ExchangeServiceBinding esb = new unews.ExchangeServiceBinding();
esb.Credentials = new System.Net.NetworkCredential( username, password, domain );
esb.Url = ewsURL;
unews.CreateItemType newItem = new unews.CreateItemType();
newItem.MessageDisposition = unews.MessageDispositionType.SendAndSaveCopy;
newItem.MessageDispositionSpecified = true;
unews.MessageType msg = new unews.MessageType();
msg.Subject = subjectBody;
msg.Body = new unews.BodyType();
msg.Body.BodyType1 = unews.BodyTypeType.Text;
msg.Body.Value = subjectBody;
msg.ToRecipients = new unews.EmailAddressType[1];
msg.ToRecipients[0] = new unews.EmailAddressType();
msg.ToRecipients[0].EmailAddress = "[email protected]";
newItem.Items = new unews.NonEmptyArrayOfAllItemsType();
newItem.Items.Items = new unews.ItemType[1];
newItem.Items.Items[0] = msg;
try {
unews.CreateItemResponseType createItemResponse = esb.CreateItem( newItem );
if (createItemResponse.ResponseMessages.Items[0].ResponseClass == unews.ResponseClassType.Error) {
throw new Exception( createItemResponse.ResponseMessages.Items[0].MessageText );
else {
Console.WriteLine( "Item was created" );
catch (Exception ex) {
Console.WriteLine( ex.ToString() );
With this code, can connect to a exchange server (smtp) and send a mail, with a custom display name.
System.Net.Mail.SmtpClient smtpc = new System.Net.Mail.SmtpClient( "exchangesrv" );
System.Net.Mail.MailMessage mm = new System.Net.Mail.MailMessage( "CustomDisplayName <[email protected]>", "[email protected]", "test email", "test email" );
smtpc.Credentials = new System.Net.NetworkCredential( "username", "password", "domain" );
smtpc.Send( mm );That won't work the way you want it in EWS, like when you send via Outlook or OWA when you send a messages via EWS it's submitted via the Exchange store so the Sender Address will be resolved back to the default Reply address for whatever account your trying
to send as. If you need some sort of custom display name I would suggest you stick to SMTP or possible create a Transport Agent that would rewrite the address before its sent externally.
Cheers
Glen -
Create appointment using EWS and set BusyType with XML
Hi guys,
I have Exchange 2010 and am trying to create a calendar appointment using EWS with XML. Everything works fine, but the "BusyType" option doesn't work. I want the appointment to show in the calendar as "Free", but instead it
shows as "Busy". Here is what I have for the XML:
<?xml version="1.0" encoding="utf-16"?>
<CreateItemType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" SendMeetingInvitations="SendToNone">
<SavedItemFolderId xmlns="http://schemas.microsoft.com/exchange/services/2006/messages">
<DistinguishedFolderId Id="calendar" xmlns="http://schemas.microsoft.com/exchange/services/2006/types">
<Mailbox>
<EmailAddress>{ItemProperty:OTManager_x0020_Display_x0020_Name}</EmailAddress>
<MailboxType>Mailbox</MailboxType>
</Mailbox>
</DistinguishedFolderId>
</SavedItemFolderId>
<Items xmlns="http://schemas.microsoft.com/exchange/services/2006/messages">
<CalendarItem xmlns="http://schemas.microsoft.com/exchange/services/2006/types">
<ItemClass>IPM.Appointment</ItemClass>
<Subject>Other Leave for {Common:InitiatorsDisplayName}</Subject>
<Body BodyType="Text">Leave request</Body>
<Location>
</Location>
<Importance>Normal</Importance>
<Start>{ItemProperty:OTFrom}</Start>
<End>{ItemProperty:OTTo}</End>
<BusyType>Free</BusyType>
</CalendarItem>
</Items>
</CreateItemType>
I've also tried using "LegacyFreeBusyStatus" which also didn't work. Can someone tell me how to modify my XML so that the appointment shows as "Free"? The actual XML was generated using a workflow tool called "Nintex
Workflow 2010", and I simply added the BusyType option to it. I'm not sure if that makes a difference or not. Thanks in advance!BusyType is not an element of the CalendarItem type it belongs to the CalendarEvent type which is part of the GetUserAvailability operation. There is a full list of CalendarItem elements on
http://msdn.microsoft.com/en-us/library/office/aa564765(v=exchg.150).aspx (note the order of the elements is critical). You should be using the LegacyFreeBusyStatus eg the following works okay for me
<m:Items>
<t:CalendarItem>
<t:Subject>tta</t:Subject>
<t:Start>2014-02-04T12:53:33.970+11:00</t:Start>
<t:End>2014-02-04T13:53:33.972+11:00</t:End>
<t:LegacyFreeBusyStatus>Free</t:LegacyFreeBusyStatus>
</t:CalendarItem>
</m:Items>
Cheers
Glen -
Apologies if this is something obvious but I'm trying to get the full folder path from an EWS Powershell script. I call the PR_Folder_Path extended property but it always returns: {MapiType: String Tag: 26293 }
The code is:
Function SearchFolder( $FolderId )
# Bind to the folder and show which one we are processing
$folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$FolderId)
$PR_Folder_Path = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(26293, [Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String)
# Search the folder for any matching items
$pageSize = 500 # We will get details for up to 500 items at a time
$offset = 0
$moreItems = $true
# Perform the search and display the results
while ($moreItems)
$searchFilter = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.ItemSchema]::ItemClass, $MessageClass)
$view = New-Object Microsoft.Exchange.WebServices.Data.ItemView($pageSize, $offset, [Microsoft.Exchange.WebServices.Data.OffsetBasePoint]::Beginning)
$view.PropertySet = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::IdOnly, [Microsoft.Exchange.WebServices.Data.ItemSchema]::ItemClass, [Microsoft.Exchange.WebServices.Data.ItemSchema]::Subject, [Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeCreated)
$view.Traversal = [Microsoft.Exchange.WebServices.Data.ItemTraversal]::Shallow
$results = $service.FindItems( $FolderId, $searchFilter, $view )
$lastRow = $ws.cells.Range("A1048576").End($xlup).row
$lastRow++
Write-Host $pr_folder_path " - " $folder.displayname " - " $folder.folderclass " - " $folder.totalcount " - " $results.totalcount " - " $folder.unreadcount
$cells.item($lastrow,1)=$folder.displayname
$cells.item($lastrow,2)=$folder.folderclass
$cells.item($lastrow,3)=$folder.totalcount
$cells.item($lastrow,4)=$results.totalcount
$cells.item($lastrow,5)=$folder.unreadcount
$moreItems = $results.MoreAvailable
$offset += $pageSize
# Now search subfolders
$view = New-Object Microsoft.Exchange.WebServices.Data.FolderView(500)
ForEach ($subFolder in $folder.FindFolders($view)) {
SearchFolder $subFolder.Id
Note: some of the code comes from the following script -
http://blogs.msdn.com/b/emeamsgdev/archive/2013/06/25/powershell-search-mailbox-for-items-of-a-particular-message-class-itemclass.aspxHi,
for performing your task you need to declare the property before and requests it when you bind to the folder.
Sample code is in C#, up to you to convert it in powershell...
var folder = Microsoft.Exchange.WebServices.Data.Folder.Bind(service, folderId, new PropertySet(BasePropertySet.FirstClassProperties, PR_Folder_Path));
string folderPath;
folder.TryGetProperty(PR_Folder_Path, out folderPath);
Regards,
Désiré GOVIN Refresh IT Solutions -
Calling powershell script from a batch file
Hello All,
I have a batch script that calls a powershell script. Before calling the script I set the execution policy to unrestricted, but when it gets to the line that calls the batch script i still get the confirmation in the command window: "Do you want to
perform this operation" I then have to press Y for the PS script to run and then my batch script finishes.
Does anyone know the setting I need to change in order to suppress the confirmation?
Note: this is Windows 8, see code below
set THIS_DIR=%~dp0
powershell Set-ExecutionPolicy unrestricted
powershell %THIS_DIR%MyScript.ps1 "param1"I may sound like a jerk but you really want to look at PowerShell.exe /?
PowerShell[.exe] [-PSConsoleFile <file> | -Version <version>]
[-NoLogo] [-NoExit] [-Sta] [-Mta] [-NoProfile] [-NonInteractive]
[-InputFormat {Text | XML}] [-OutputFormat {Text | XML}]
[-WindowStyle <style>] [-EncodedCommand <Base64EncodedCommand>]
[-File <filePath> <args>] [-ExecutionPolicy <ExecutionPolicy>]
[-Command { - | <script-block> [-args <arg-array>]
| <string> [<CommandParameters>] } ]
PowerShell[.exe] -Help | -? | /?
-PSConsoleFile
Loads the specified Windows PowerShell console file. To create a console
file, use Export-Console in Windows PowerShell.
-Version
Starts the specified version of Windows PowerShell.
Enter a version number with the parameter, such as "-version 2.0".
-NoLogo
Hides the copyright banner at startup.
-NoExit
Does not exit after running startup commands.
-Sta
Starts the shell using a single-threaded apartment.
Single-threaded apartment (STA) is the default.
-Mta
Start the shell using a multithreaded apartment.
-NoProfile
Does not load the Windows PowerShell profile.
-NonInteractive
Does not present an interactive prompt to the user.
-InputFormat
Describes the format of data sent to Windows PowerShell. Valid values are
"Text" (text strings) or "XML" (serialized CLIXML format).
-OutputFormat
Determines how output from Windows PowerShell is formatted. Valid values
are "Text" (text strings) or "XML" (serialized CLIXML format).
-WindowStyle
Sets the window style to Normal, Minimized, Maximized or Hidden.
-EncodedCommand
Accepts a base-64-encoded string version of a command. Use this parameter
to submit commands to Windows PowerShell that require complex quotation
marks or curly braces.
-File
Runs the specified script in the local scope ("dot-sourced"), so that the
functions and variables that the script creates are available in the
current session. Enter the script file path and any parameters.
File must be the last parameter in the command, because all characters
typed after the File parameter name are interpreted
as the script file path followed by the script parameters.
-ExecutionPolicy
Sets the default execution policy for the current session and saves it
in the $env:PSExecutionPolicyPreference environment variable.
This parameter does not change the Windows PowerShell execution policy
that is set in the registry.
-Command
Executes the specified commands (and any parameters) as though they were
typed at the Windows PowerShell command prompt, and then exits, unless
NoExit is specified. The value of Command can be "-", a string. or a
script block.
If the value of Command is "-", the command text is read from standard
input.
If the value of Command is a script block, the script block must be enclosed
in braces ({}). You can specify a script block only when running PowerShell.exe
in Windows PowerShell. The results of the script block are returned to the
parent shell as deserialized XML objects, not live objects.
If the value of Command is a string, Command must be the last parameter
in the command , because any characters typed after the command are
interpreted as the command arguments.
To write a string that runs a Windows PowerShell command, use the format:
"& {<command>}"
where the quotation marks indicate a string and the invoke operator (&)
causes the command to be executed.
-Help, -?, /?
Shows this message. If you are typing a PowerShell.exe command in Windows
PowerShell, prepend the command parameters with a hyphen (-), not a forward
slash (/). You can use either a hyphen or forward slash in Cmd.exe.
Hope that helps! Jason -
Can't set internal SMTP servers, breaking anti-spam
Hi, in our on-premise Exchange there is a PowerShell setting,
Set-TransportConfig -InternalSMTPServers , which is used to inform Forefront Protection for Exchange ("FPE") of any non-Exchange SMTP servers that might be handling messages before they arrive at Exchange. This setting is necessary to ensure
that the anti-spam functionality of FPE can properly look back through the message header and determine which internet host actually delivered the message, and determine if that host is on a blacklist, or whatnot.
In Exchange Online Protection, though, it seems that there is no argument under Set-TransportConfig to establish such settings. I *can* see the setting under Get-TransportConfig, but I can't set it.
This is a problem for us because we route mail internally first via on-premise, non-Exchange mail gateways before the messages are routed to Exchange Online. Exchange online always believes that our internal mail gateways are the originating server, when
in fact, it's one hop back. The result is that Exchange Online's anti-spam functionality is not working correctly.
How can I address this issue? I can't really re-route my MX record directly to the cloud yet.Hi Jouni, thanks for your response.
Turns out that the Citrix Access Gateway wasn't set up until yesterday evening and by then I had stopped trying for the day. It is now set up and external access is available.
Further to this, my colleague forgot to inform me of the change of I.P. address of the Exchange server. This meant that Webmail requests were pointing to an I.P. address that didn't exist.
I have reconfigured the firewall this morning and external access for Webmail is also working correctly. -
Using EWS to cancel a meeting in a room mailbox.
This seems like a common occurance at any company but there really doesn't seem to be a solution for it. In Exchange people can reserve a conference room by inviting it to a meeting and with the proper setup the room mailbox will accept the meeting
if the time slot is free. The problem comes in when the organizer of the meeting leaves the company. I'm working on a project using Exchange Web Services to clean out our room mailboxes of meetings which were scheduled by people who are no longer
at the company. The only way I know how is through web services and through an account that has been given the impersonation right (which I am using).
The problem I'm having is that through web services there is a method on an appointment item called CancelMeeting which would do just this except I'm getting the below error:
Exception calling "CancelMeeting" with "0" argument(s): "User must be an organizer for CancelCalendarItem action."
I'm looking for any suggestions as I've been looking out over the Internet for quite a bit now and not really coming up with anything of use. Below is the code I'm using (cleaned up to remove company information). Any thoughts or input that could
be helpful would be much appreciated.
#Address of object to connect to
$roomAddress = '[email protected]'
#Path to the EWS DLL
$dllpath = "C:\Program Files\Microsoft\Exchange\Web Services\1.2\Microsoft.Exchange.WebServices.dll"
#Load the EWS DLL
[void][Reflection.Assembly]::LoadFile($dllpath)
#Create a service object that supports Exchange 2010 SP1
$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP1)
#Store the passed in credential
#$service.Credentials = $credential
#Web services url
$uri=[system.URI] "https://ExhcangeServer.Contoso.com/EWS/Exchange.asmx"
$service.Url = $uri
#The impersonation details.
$ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId
$ImpersonatedUserId.IdType = 'smtpaddress'
$ImpersonatedUserId.Id = $roomAddress
$service.ImpersonatedUserId = $ImpersonatedUserId
#Build a folder ID object
$folderid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar,$roomAddress)
#Bind to the mailbox and folder.
$CalendarFolder = [Microsoft.Exchange.WebServices.Data.CalendarFolder]::Bind($service,$folderid)
#Get up to 2000 entries from the folder and find any that are appointments from today and the next 5 days.
$startDAte = get-date
$endDate = (get-date).AddDays(+5)
$cvCalendarview = new-object Microsoft.Exchange.WebServices.Data.CalendarView($StartDate,$EndDate,2000)
$frCalendarResult = $CalendarFolder.FindAppointments($cvCalendarview)
#Build a view
$psPropset = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
$psPropset.RequestedBodyType = [Microsoft.Exchange.WebServices.Data.BodyType]::Text
#Cancel the first meeting found (there is one here)
$frCalendarResult.Items[0].CancelMeeting()Oh, ouch. In that case, I might also try asking in the Exchange development forum. They're a bit more versed in EWS than I am.
http://social.technet.microsoft.com/Forums/en-US/exchangesvrdevelopmentlegacy/threads
I do have a script that uses EWS to set a delegate on a specific calendar (it was written for standard users, not sure how it'll handle room mailboxes. Perhaps delegate rights will be enough to send out cancellation notices. I can clean it up and post it
(after I get out of this afternoon meeting) if you think it might help. -
Disabling Minimal Download Strategy from PowerShell but still shows feature as "Activated".
I have an interesting issue with the Minimal Download Strategy feature in SharePoint 2013. I have a script in place which will disable this feature on all sites in all site collections on our Farm. The script has been working fine and we schedule it to run
daily at 8PM so that any new sites that get created will have this feature shut off, in case the person who created it forgot to disable it.
As of recently, I've noticed while the script appears to be working fine, we are seeing that new sites are still showing the feature as activated in the "Manage Site Features" page. If I re-run the script, it shows that the feature is disabled
and won't do anything. The script basically steps through all sites of all site collections in our default web application and if the MDS feature is enabled it disables it. Simple enough.
So why am I now seeing sites that show the feature is Activated even though it is disabled? I've checked this by noting the URL that the site uses and it does not load pages from the "_layouts/15/" location.
The reason we have to turn this feature off on all sites is because we allow external users to access our SharePoint through a secure proxy. With this feature enabled, we have constant problems with pages not loading properly or generating javascript errors.
Anyone have any insight into this?Here is the script we are using. As I mentioned, it works fine. It disables the the "Minimal Download Strategy", however when you go to the site settings it shows the feature is activated.
# This PowerShell script will check all sites of each site collection in
# the default Web Application to see if the MDS (Minimal Download Strategy)
# feature is enabled and if so it will turn it off.
# This script should be scheduled to run once a day to ensure this feature
# is always disabled.
# Register SharePoint Snap-In
$ver = $host | select version
if ($ver.Version.Major -gt 1) {$Host.Runspace.ThreadOptions = "ReuseThread"}
Add-PsSnapin Microsoft.SharePoint.PowerShell
Set-location $home
Write-Host "Script Running at "(Get-Date);
$Default_WebApp = "http://vmsp2k13app.phs.org"
# Get all Site Collections in the default Web Application
$SPSites = Get-SPSite -WebApplication $Default_WebApp
#Cycle through each Site Collection and its Webs (sub-sites)
ForEach($Site in $SPSites){
Write-Host "";
Write-Host "Checking Site-Collection: " $Site.Url;
ForEach($Web in $Site.AllWebs)
Write-Host "";
Write-HOst " Checking Sub-Site: " $Web;
If($Web.EnableMinimalDownload -eq 1)
Write-Host " Minimal Download Strategy is Enabled for this site!";
Write-Host " Disabling....";
$Web.EnableMinimalDownload = 0;
$Web.Update();
Else
Write-Host "";
$Web.Dispose();
$Site.Dispose(); -
How to create a context menu using powershell
Hi
i would like to create a context menu for powershell but i am getting an error after powershell menu is created
"This file does not have a program associated to it. i am using this script . I am trying to create a powershell shortcut on folders."
also once it gets created i would like to open powershell as admin always
New-PSDrive -Name HKCR -PSProvider Registry -Root HKEY_CLASSES_ROOT
Test-Path HKCR:\Directory\shell\Powershell
New-Item -Path HKCR:\Directory\shell -Name Powershell
Set-Item -Path HKCR:\Directory\shell\Powershell -Value "Open Powershell Here"
New-Item -Path HKCR:\Directory\shell\Powershell\key -Value "C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe -NoExit -Command ""Set-Location -LiteralPath '%L'"""You need to put forth the effort to ask a good, clear, and meaningful question.
As it stands, you seem to have a record of asking nearly unintelligible questions that take a great amount of effort for others to guess what you are asking. This is bad because it wastes everyone's time.
Read these for some good information on how to ask good questions:
Posting guidelines
Handy tips for posting to this forum
How to ask questions in a technical forum
Rubber duck problem solving
How to write a bad forum post
-- Bill Stewart [Bill_Stewart] -
PowerShell code not working import XML to SharePoint list
All hi, I don't understand why doesn't work? XML file from here -
http://www.cbr.ru/scripts/XML_daily.asp?date_req=23/01/2015
if(!(Get-PSSnapin Microsoft.SharePoint.Powershell -ErrorAction:SilentlyContinue))
Add-PSSnapin Microsoft.SharePoint.Powershell
#Set these two variables accordingly
$WebURL = “http://sharepoint/Test”
$ListName = "Test"
$XMLFilePath = "C:\Test\XML\XML_daily_asp.xml"
#Get the Web
$web = Get-SPWeb $WebURL
#Get the List
$ProjectList = $web.Lists[$ListName]
#import xml file
$ProjectXmlFile = Get-Content $XMLFilePath
foreach ($XMLProject in $ProjectXmlFile)
$NewProject = $ProjectList.Items.Add()
$NewProject["Title"] = $XMLProject.Value
$NewProject["NumCode"] = $XMLProject.NumCode
$NewProject["CharCode"] = $XMLProject.CharCode
$NewProject["Nominal"] = $XMLProject.Nominal
$NewProject["Name"] = $XMLProject.Name
$NewProject["Value"] = $XMLProject.Value
$NewProject.Update()
Write-Host "Has been Added to External Projects list!"I understood, my error was that it is necessary to add (.ValCurs.Valute) to $ProjectXmlFile.ValCurs.Valute, and also surely to specify an ID (i.e. Valute ID)
This' working code:
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
$WebURL = "http://sharepoint/Test"
$ListName = "Test"
$XMLFilePath = "C:\Test\XML_daily_asp.xml"
$web = Get-SPWeb $WebURL
#Get the List
$ProjectList = $web.Lists[$ListName]
#import xml file
[xml]$ProjectXmlFile = Get-Content $XMLFilePath
foreach ($XMLProject in $ProjectXmlFile.ValCurs.Valute)
$NewProject = $ProjectList.Items.Add()
$NewProject["Title"] = $XMLProject.id
$NewProject["NumCode"] = $XMLProject.NumCode
#Set the People Picker Field
$NewProject["CharCode"] = $XMLProject.CharCode
$NewProject["Nominal"] = $XMLProject.Nominal
$NewProject["Name"] = $XMLProject.Name
$NewProject["Value"] = $XMLProject.Value
$NewProject.Update()
Write-Host "Project $($XMLProject.id) has been Added to External Projects list!" -
Hi,
I have been tasked with decommissioning our single Multi Role Server (CAS/HT/MB) and assigning the roles to 2 new servers. 1 server will be dedicated to CAS and the other new server will be dedicated to HT & MB roles.
I think I'm OK with the moving of HT and MB roles from our current server to the new HT/MB server by following "Ed Crowley's Method for Moving Exchange Servers", my focus is on the migration of the CAS role from the current to the new server as
this one has the potential to kill our mail flow if I don't move the role correctly.
The actual introduction of the new CAS server is fairly straight forward but the moving of the certificate is where I need some clarification.
Our current multi role server has a 3rd Party Certificate with the following information:
Subject: OWA.DOMAIN.COM.AU
SANs: internalservername.domain.local
autodiscover.domain.com.au
The issue here is the SAN entry "internalservername.domain.local" which will need to be removed in order for the certificate to be used on the new CAS server, firstly because the CAS server has a different name and secondly the internal FQDN will
no longer be allowed to be used from 2015 onwards. So I will need to revoke this certificate and issue a new certificate with our vendor who is Thawte.
This presents me with an opportunity to simplify our certificate and make changes to the URLs using a new certificate name, so I have proposed the following:
New Certificate:
Subject: mail.domain.com.au
SANs: autodiscover.domain.com.au
OWA.DOMAIN.COM.AU
I would then configure the URLs using PowerShell:
Set-ClientAccessServer -Identity NEWCASNAME-AutodiscoverServiceInternalUrl https://mail.domain.com.au/autodiscover/autodiscover.xml
Set-WebServicesVirtualDirectory -Identity " NEWCASNAME\EWS (Default Web Site)" -InternalUrl https://mail.domain.com.au/ews/exchange.asmx
Set-OABVirtualDirectory -Identity " NEWCASNAME\oab (Default Web Site)" -InternalUrl https://mail.domain.com.au/oab
Set-OWAVirtualDirectory -Identity " NEWCASNAME\owa (Default Web Site)" -InternalUrl https://mail.domain.com.au/owa
I would also then set up split DNS on our internal DNS server creating a new zone called "mail.domain.com.au" and add an host A record with the internal IP address of the new CAS server.
Now I know I haven't asked a question yet and the only real question I have is to ask if this line of thinking and my theory is correct.
Have I missed anything or is there anything I should be wary of that has the potential to blow up in my face?
Thanks guys, I really appreciate any insights and input you have on this.Hi Ed,
Thanks for your reply, it all makes perfect sense I guess I was being optimistic by shutting down the old server and then resubscribing the edge and testing with mailboxes on the new mailbox server.
I will make sure to move all of the mailboxes over before removing the old server via "Add/Remove Programs". Will I have to move the arbitration mailboxes on the old server across to the new mailbox server? Will having the arbitration mailboxes
on the old server stop me from completely removing exchange?
Also, the InternalURL & ExternalURL properties are as follows:
Autodiscover:
New CAS - InternalURL: https://svwwmxcas01.pharmacare.local/Autodiscover/Autodiscover.xml
Old CAS - InternalURL: https://svwwmx001.pharmacare.local/autodiscover/autodiscover.xml
WebServices:
New CAS - InternalURL: https://svwwmxcas01.pharmacare.local/EWS/Exchange.asmx
New CAS - ExternalURL: https://owa.pharmacare.com.au/EWS/Exchange.asmx
Old CAS - InternalURL: https://svwwmx001.pharmacare.local/ews/exchange.asmx
Old CAS - ExternalURL: https://owa.pharmacare.com.au/EWS/Exchange.asmx
OAB:
New CAS - InternalURL: http://svwwmxcas01.pharmacare.local/OAB
New CAS - ExternalURL: https://owa.pharmacare.com.au/OAB
Old CAS - InternalURL: https://svwwmx001.pharmacare.local/oab
Old CAS - ExternalURL: https://owa.pharmacare.com.au/OAB
OWA:
New CAS - InternalURL: https://svwwmxcas01.pharmacare.local/owa
New CAS - ExternalURL: https://owa.pharmacare.com.au/
Old CAS - InternalURL: https://svwwmx001.pharmacare.local/owa
Old CAS - ExternalURL: https://owa.pharmacare.com.au/
ECP:
New CAS - InternalURL: https://svwwmxcas01.pharmacare.local/ecp
New CAS - ExternalURL: https://owa.pharmacare.com.au/ecp
Old CAS - InternalURL: https://svwwmx001.pharmacare.local/ecp
Old CAS - ExternalURL: https://owa.pharmacare.com.au/ecp
Our Public Certificate has the following details:
Name: OWA.PHARMACARE.COM.AU
SAN/s: autodiscover.pharmacare.com.au, svwwmx001.pharmacare.local
From your previous communications you mentioned that this certificate would not need to change, it could be exported from the old server and imported to the new which I have done. With the InternalURL & ExternalURL information that you see here can you
please confirm that your original recommendation of keeping our public certificate and importing it into the new CAS is correct? Will we forever get the certificate warning on all of our Outlook clients when we cut over from the old to the new until we get
a new certificate with the SAN of "svwwmx001.pharmacare.local" removed?
Also, I am toying with the idea of implementing a CAS Array as I thought that implementing the CAS Array would resolve some of the issues I was having on Saturday. I have followed the steps from this website, http://exchangeserverpro.com/how-to-install-an-exchange-server-2010-client-access-server-array/,
and I have got all the way to the step of creating the CAS array in the Exchange Powershell but I have not completed this step for fear of breaking connectivity to all of my Outlook Clients. By following all of the preceeding steps I have created a Windows
NLB with dedicated NICs on both the old CAS and the new CAS servers (with separate IP addresses on each NIC and a new internal IP address for the dedicated CAS array) and given it the name of "casarray.pharmacare.local" as per the instructions on
the website, the questions I have on adding the CAS array are:
1. Do you recommend adding the CAS array using this configuration?
2. Will this break Outlook connectivity alltogether?
3. Will I have to generate a new Public Certificate with an external FQDN of "casarray.pharmacare.com.au" pointing back to a public IP or is it not required?
4. If this configuration is correct, and I add the CAS Array as configured, when the time comes to remove the old server is it just as simple as removing the NLB member in the array and everything works smoothly?
So, with all of the information at hand my steps for complete and successful migration would be as follows:
1. Move all mailboxes from old server to new server;
2. Move arbitration mailboxes if required;
3. Implement CAS Array and ensure that all Outlook clients connect successfully;
4. Remove old server;
5. Shut down old server;
6. Re-subscribe Edge from new Hub Transport server;
7. Test internal & external comms;
We also have internal DNS entries that would need changing:
1. We have split DNS with a FLZ of "owa.pharmacare.com.au" that has a Host A record going to the old server, this would need changing from "svwwmx001.pharmacare.local" to "svwwmxcas01.pharmacare.local";
2. The _autodiscover entry that sits under _TCP currently has the IP address of the old server, this would need to be changed to the IP address of the new CAS;
3. The CNAME that sits in our FLZ for "pharmacare.local" would need to be changed from "svwwmx001.pharmacare.local" to "svwwmxcas01.pharmacare.local".
4. Or rather than using the FQDN of the server where applicable in the DNS changes would I be using the FQDN of the CAS Array instead? Please confirm.
Would you agree that the migration path and DNS change plan is correct?
Sorry for the long post, I just need to make sure that everything goes right and I don't have egg on my face. I appreciate your help and input.
Thanks again.
Regards,
Jamie
Maybe you are looking for
-
Hello. I'm an Illustrator novice, as you will be able to tell from my question. I'm somewhat familiar with the gradient mesh tool as well as the raster effects that Illustrator CS3 offers, but I can't figure out how to use them to do what I have to d
-
Acrobat 9.3 standard and IE8 printing freezes
I can't believe this is still an issue...its been a known problem since end of last year at least (IE 8 came out in Mar 09?). It freezes my computer such that I have to POWER OFF!!!! I am NOT looking forward to the first time this happens with a user
-
Hi all, reports version : 6i I am trying to run a receipt based report , passing a range of receipt number in parameter form i need to get the report of the given range of receipt number I give the first receipt number('RV00001/2008') in the list in
-
Payment Terms-Manual due date Input-Which field?
Dear Gurus, I can observe an option at the payment terms of "no default" which means that payment due date has to be entered manually.Is there some field in the order or billing document where the due date can be entered manually.Kindly hep,thank you
-
Material price not appearing in SC
Hi Experts, we have a strange problem in our system.we are having classic scenario(SRM 5) when i select a material from Internal goods/services , system will not show us the Std price maintained in material master. Inforecord is also maintained for t