0 votes

Hi!

Is there a way to have ADAxess move mailboxes to a new Exchange server/store if the user becomes Skype for Business enabled ?

The logic would be something that if the mailbox is on Exchange server X and Sfb Enabled (or member of group that contains SFB enabled users) then migrate their mailbox to a (load balanced) list of two other Exchange servers.

Prefereably sequentially so that it doesnt try to move all current mailboxes that already are SFB enabled but not moved, but does it one by one ....

/Kaj

by (650 points)

1 Answer

0 votes
by (270k points)
selected by
Best answer

Hello Kaj,

There is no possibility to trigger a Business Rule on enabling a user for Skype for Business (Lync). Thus, there is no possibility to move the mailbox of a user right after enabling them for Skype for Business (Lync).

As a workaround, we recommend using a Scheduled Task. It will check all the conditions you mentioned and move the mailbox if required. You can set task to be executed once a day, for example, or more often. If this solution meets your needs, we will provide you with detailed instructions.

0

A scheduled task will work, the main thing is that it runs once every day and moves any SFB enabled accounts that sit on the 'wrong' Exchange server to one of the New Exchange servers (four stores totally spread over two servers) - and perhaps throttling so that it doesnt run more than one user at a time to prevent exchange logs from filling up the logvolumes between backups.

0

Hello Kaj,

Thank you for specifying. To create the Scheduled Task:

  1. Launch Adaxes Administration Console.

  2. Right-click your Adaxes service node, navigate to New and click Scheduled Task.

  3. On step 3 of the Create Scheduled Task wizard, select User Object type and click Next.

  4. Click Add Action and select Move the Exchange mailbox.

  5. Specify action parameters and click OK.

  6. Double click Always and select If PowerShell script returns true.

  7. Paste the following script into the Script field.

     $mailboxStore = "MailboxStorage" # TODO: modify me
     $groupDN = "CN=Sales Agents,CN=Users,DC=domain,DC=com" # TODO: modify me
    
     if ($Context.TargetObject.RecipientType -ne "ADM_EXCHANGERECIPIENTTYPE_MAILBOXENABLED")
     {
         return
     }
    
     # Get GUIDs of the groups the user is a member of
     $Context.ConditionIsMet = $False
     $targetGroupGuids = New-Object "System.Collections.Generic.HashSet[Guid]"
     try
     {
         $Context.TargetObject.GetEx("adm-MemberOfGuid") | %%{[void]$targetGroupGuids.Add([Guid]$_)}
     }
     catch
     {
         return # The user is not a member of any groups. Return False
     }
     $group = $Context.BindToObjectByDN($groupDN)
     $groupGuid = [Guid]$group.Get("ObjectGuid")
     $mailboxParams = $Context.TargetObject.GetMailParameters()
    
     $Context.ConditionIsMet = $Context.TargetObject.IsLyncEnabled -and (($mailboxParams.StorageDatabase -eq $mailboxStore) -or $targetGroupGuids.Contains($groupGuid))
    
  8. Enter a short description and click OK.

  9. Click Next and finish creating the Scheduled Task.

0

Thanks, just so that I understand the script.

$mailboxStore = source Exchange store to move from?

$groupDN = Group members it should operate on?

A side note - Is there a way to repopolute (empty & refill) the Group based on Skype for Business membership? We have such script to populate already outside of AdAxess but that one only adds users, never removes manually added or users that been decommisioned from Sfb.

/Kaj

0

Hello Kaj,

$mailboxStore = source Exchange store to move from?

Yes.

$groupDN = Group members it should operate on?

No, you mentioned that a mailbox should be moved if a user is enabled for Skype for Business and the mailbox is stored in a specific MailboxStore or if a user is enabled for Skype for Business and is member of a specific group. The $groupDN variable specifies the distinguished name of this group.

A side note - Is there a way to repopolute (empty & refill) the Group based on Skype for Business membership? We have such script to populate already outside of AdAxess but that one only adds users, never removes manually added or users that been decommisioned from Sfb.

Could you provide us with as much detail on the desired scenario as possible?

0

I basically run this script now, the first line is added today .... Would like to get it into ADAxess instead so all automatic stuff is in one place.

Remove-ADGroupMember "XXXX" -Members (Get-ADGroupMember "XXXX")  -Confirm:$false
Foreach ($User in get-csuser -filter {Enabled -ne $Null})
{Add-ADGroupMember -Identity "SFB" -Members $User.SamAccountName}

Can AdAxess access the get-csuser calls from within its engine or does the above need to be rewritten somehow?

0

No, you mentioned that a mailbox should be moved if a user is enabled for Skype for Business and the mailbox is stored in a specific MailboxStore or if a user is enabled for Skype for Business and is member of a specific group. The $groupDN variable specifies the distinguished name of this group.

Perhaps a misunderstanding / I'm that misreading the statement. The mailboxes that needs to be moved are located on Exchange server Y and (members of the group XXXX or Skype enabled). My suggestion with group or SFB enabled was two different approaches to the same problem, clearly checking the SFB enablement directly is a cleaner way to go than to take the round trip through the group membership that can be wrong due to manual editing.

I'm guessing the last line of code can be changed to the below to only act on one store and lync enablement.

$Context.ConditionIsMet = $Context.TargetObject.IsLyncEnabled -and (($mailboxParams.StorageDatabase -eq $mailboxStore)

But I also now realize that we are talking about STORE, not Server - where Server would be more right since the user can be on any of four stores on one Exchange 2010 server.

Also, we would like to limit the number of moves for each pass of the scheduled task and run the scheduled task once every night. This so that we move users slowly to new exchange environment but that its still automated during the migration.

Remove-ADGroupMember "XXXX" -Members (Get-ADGroupMember "XXXX")  -Confirm:$false
Foreach ($User in get-csuser -filter {Enabled -ne $Null})
{Add-ADGroupMember -Identity "SFB" -Members $User.SamAccountName}

To comment on my other post in this thread - I guess that its a nicer approach to check if the user is isLyncEnabled and ifso insert the user to the XXXX group. Question is how to remove users that no longer is SFB enabled for some reason or another and how the above code can be adapted and inserted into your script to both move the Exchange store and update the SFB members group.

/Kaj

0

Hello Kaj,

Allow us to clarify to avoid any further misunderstandings. Do we understand correctly that you need the following:

  1. A Scheduled Task that will move mailboxes of users enabled for Skype for Business to another Server if they are stored on Server X. Each time the Scheduled Task is executed only a specified number of mailboxes must be moved.
  2. A Scheduled Task that will add all users enabled for Skype for Business to a group and remove all users that are not enabled for Skype for Business from the group.
0

Correct - although the destination server is more like Destination serverS - its two different servers with two different stores each, so the target is four different stores whichever has least number of mailboxes (preferably by GB, but understand that you count # of mailboxes which is OK).

Thanks for your excellent support.

/Kaj

0

Hello Kaj,

The solution will include 2 Scheduled Tasks. The first task will move mailboxes of users enabled for Skype for Business (Lync), the second task will add/remove users to a group depending on whether they are enabled for Skype for Business (Lync).

i. Creating the Scheduled Task to move mailboxes.

  1. Launch Adaxes Administration Console.

  2. Right-click your Adaxes service node, navigate to New and click Scheduled Task.

  3. On step 3 of the Create Scheduled Task wizard, select Domain-DNS Object type and click Next.

  4. Click Add Action.

  5. Select Run a program or Powershell script.

  6. Paste the script below into the Script field.

     $sourceExcahngeServer = "SourceMailboxServer1" # TODO: modify me
     $targetExcahngeServers = @("TargetMailboxServer1", "TargetMailboxServer1") # TODO: modify me
    
     # Mailbox move settings
     $mailboxMoveLimit = 10 # TODO: modify me
     $moveWithArchive = $True # TODO: modify me
     $badItemLimit = 0 # TODO: modify me
     $largeItemLimit = 0 # TODO: modify me
    
     function SearchObjects($path, $filter, $properties, $searchInAllDomans, $sizeLimit)
     {
         $searcher = $Context.BindToObject($path)
         $searcher.SearchFilter = $filter
         $searcher.SearchScope = "ADS_SCOPE_SUBTREE"
         $searcher.PageSize = 500
         $searcher.ReferralChasing = "ADS_CHASE_REFERRALS_NEVER"
         $searcher.SetPropertiesToLoad($properties)
         if ($searchInAllDomans)
         {
             $searcher.VirtualRoot = $True
         }
         if ($sizeLimit -ne $NULL)
         {
             $searcher.SizeLimit = $sizeLimit
         }
    
         try
         {
             $searchResultIterator = $searcher.ExecuteSearch()
             $searchResults = $searchResultIterator.FetchAll()
    
             return ,$searchResults
         }
         finally
         {
             # Release resources
             if ($searchResultIterator){ $searchResultIterator.Dispose() }
         }
     }
    
     # Get all databases from source exchange server
     $sourceServerSearchResults = SearchObjects "Adaxes://RootDSE" "(&(objectClass=msExchExchangeServer)(name=$sourceExcahngeServer))" @("distinguishedName") $True $NULL
     if ($sourceServerSearchResults.Length -eq 0)
     {
         $Context.LogMessage("Exchange server '$sourceExcahngeServer' not found.", "Warning")
         return
     }
     $sourceServerDN = $sourceServerSearchResults[0].Properties["distinguishedName"].Value
     $domainName = $Context.GetObjectDomain($sourceServerDN)
     $sourceDBSearchResults = SearchObjects "Adaxes://$domainName/RootDSE" "(&(objectClass=msExchPrivateMDB)(msExchOwningServer=$sourceServerDN))" @() $False $NULL
     if ($sourceDBSearchResults.Length -eq 0)
     {
         $Context.LogMessage("No mailbox databases found for server '$sourceExcahngeServer'.", "Warning")
         return
     }
    
     # Search users enabled for Skype for Business (Lync)
     $filter = New-Object "System.Text.Stringbuilder"
     [void]$filter.Append("(&(sAMAccountType=805306368)(msRTCSIP-UserEnabled=TRUE)(msExchRecipientTypeDetails=1)(|")
     foreach ($searchResult in $sourceDBSearchResults)
     {
         [void]$filter.Append([Softerra.Adaxes.Ldap.FilterBuilder]::Create("homeMDB", $searchResult.Properties["distinguishedName"].Value))
     }
     [void]$filter.Append("))")
     $usersSearchResults = SearchObjects "Adaxes://$domainName/RootDSE" $filter.ToString() @() $False $mailboxMoveLimit
     if ($usersSearchResults.Length -eq 0)
     {
         $Context.LogMessage("No users enabled for Skype for Business (Lync) found.", "Information")
         return
     }
    
     # Search target exchange servers
     $targetServerSearchResults = @()
     foreach ($server in $targetExcahngeServers)
     {
         $searchResults = SearchObjects "Adaxes://RootDSE" "(&(objectClass=msExchExchangeServer)(name=$server))" @("distinguishedName") $True $NULL
         $targetServerSearchResults += $searchResults
     }
     if ($targetServerSearchResults.Length -eq 0)
     {
         $Context.LogMessage("Target exchange servers not found.", "Warning")
         return
     }
    
     # Build filter for searching target mailbox databases
     $targetDBSearchFilter = New-Object "System.Text.StringBuilder"
     [void]$targetDBSearchFilter.Append("(&(objectClass=msExchPrivateMDB)(|")
     foreach ($searchResult in $targetServerSearchResults)
     {
         $dn = $searchResult.Properties["distinguishedName"].Value
         [void]$targetDBSearchFilter.Append("(msExchOwningServer=$dn)")
     }
     [void]$targetDBSearchFilter.Append("))")
    
     # Search target mailbox databases
     $targetDBSearchResults = SearchObjects "Adaxes://RootDSE" $targetDBSearchFilter.ToString() @("homeMDBBL", "distinguishedName") $True $NULL
     if ($targetDBSearchResults.Length -eq 0)
     {
         $Context.LogMessage("Target mailbox databases not found.", "Warning")
         return
     }
     $targetDBInfos = @{}
     foreach ($searchResult in $targetDBSearchResults)
     {
         $dn = $searchResult.Properties["distinguishedName"].Value
         $homeMDBBL = $searchResult.Properties["homeMDBBL"].Values
         $targetDBInfos.Add($dn, $homeMDBBL.Count)
     }
    
     # Move user mailboxes
     foreach ($searchResult in $usersSearchResults)
     {
         # Get mailbox DB with the least number of mailboxes
         $dbInfo = $targetDBInfos.GetEnumerator() | Sort Value -Descending | Select -Last 1
         $targetDBInfos[$dbInfo.Key] += 1
    
         # Bind to user
         $user = $Context.BindToObject($searchResult.AdsPath)
    
         # Create Move request
         $archiveDatabaseDN = $NULL
         $targetDatabaseDN = $dbInfo.Key.ToString()
         if ($moveWithArchive)
         {
             $archiveDatabaseDN = $dbInfo.Key.ToString()
         }
         $user.CreateMoveMailboxRequest("Adaxes://$targetDatabaseDN", $archiveDatabaseDN, $badItemLimit, $largeItemLimit)
     }

    In the script:

    • $sourceExcahngeServer – Specifies the name of the Exchange server from which mailboxes are moved.
    • $targetExcahngeServers - Specifies names of the Exchange servers to which mailboxes are moved.
      To obtain the name of an Exchange server, sign in to the server and execute the following command:
      (Get-ExchangeServer).Name
    • $mailboxMoveLimit - Specifies the number of mailboxes to move.
    • $moveWithArchive - Specifies whether mailbox archives must be moved.
    • $badItemLimit - Specifies the number of bad items to skip if the request encounters corruption in the mailbox. Use 0 to not skip bad items. The valid input range for this parameter is from 0 through 2147483647.
    • $largeItemLimit - Specifies the number of large items to skip if the request encounters such items in the mailbox. Use 0 to not skip any large items.
  7. Enter a short description and click OK.

  8. Finish creating the Scheduled Task

ii. Creating the Scheduled Task to add/remove users from a Group.

  1. Launch Adaxes Administration Console.

  2. Right-click your Adaxes service node, navigate to New and click Scheduled Task.

  3. On step 3 of the Create Scheduled Task wizard, select User Object type and click Next.

  4. Click Add Action.

  5. Select Add the User to a group and click Select Group.

  6. Select the group to which users enabled for Skype for Business (Lync) must be added and click OK twice.

  7. Double-click Always and select If Powershell script returns true.

  8. Paste the script below into the Script field.

     $Context.ConditionIsMet = $Context.TargetObject.IsLyncEnabled
  9. Enter a short description and click OK.

  10. Right-click the action you have created and click Add Condition.

  11. Select If is a member of <Group>.

  12. Select is not and click Select Group.

  13. Select the same group you have selected on step 6 and click OK twice.

  14. Click Add action to a new set.

  15. Select Remove the User from a group and click Select Group.

  16. Select the same group you have selected on step 6 and click OK twice.

  17. Double-click Always and select If Powershell script returns true.

  18. Paste the script below into the Script field.

     $Context.ConditionIsMet = (-not($Context.TargetObject.IsLyncEnabled))
  19. Enter a short description and click OK.

  20. Right-click the action you have created and click Add Condition.

  21. Select If is a member of <Group> and click Select Group.

  22. Select the same group you have selected on step 6 and click OK twice.

  23. Finish creating the Scheduled Task.

You should have something like the following:

Related questions

0 votes
1 answer

Currently getting this error when enabling a user for Skype for Business: No cmdlets have been authorized for use by the RBAC role that the user belongs ... minimum required permissions that the Adaxes account needs to manage Skype for Business functionality?

asked Dec 16, 2021 by thedoo (60 points)
0 votes
1 answer

"Connecting to remote server &lt;&lt;FQDN Servername&gt;&gt; failed with the following error message : The server certificate on the destination computer (&lt;&lt;FQDN servername: ... ? This may help to diagnose the issue with schannel on the skype server.

asked Mar 5, 2020 by mark.it.admin (2.3k points)
0 votes
1 answer

One of the features I noticed being called out in the 2019 update was the ability to control some Skype for Business attributes for a user. Looking at users in my environment ... can be used to manage online users, what admin roles are required on Office 365?

asked Aug 12, 2019 by blaiseb (120 points)
0 votes
1 answer

We have the Skype for business Basic working correctly in Adaxes. However we need add to the server and grant specific options (screen sharing). We ... " -PolicyName MyPersistentChatPolicy # Assign a Persistent Chat Policy Remove-PSSession -Session $session

asked Jan 2, 2017 by willy-wally (3.2k points)
0 votes
1 answer

Hi Team I need some assitance with creating a report to pull from exchange online all user mailboxes that have automatic replies enabled. I have been attempting to use ... Where-Object { $_.AutoReplyState -ne "Disabled" } | Select Identity, StartTime, EndTime

asked Aug 25, 2021 by Richard_NRL (90 points)
3,326 questions
3,025 answers
7,724 comments
544,675 users