Alan's sysadmin Blog

Working smarter not harder

Archive for the ‘PowerShell’ Category

PS Script: Auto Generating New Extensions in Lync

Posted by Alan McBurney on August 29, 2014

This a script I’ve been meaning to put together for a while in order to find free extensions within a given extension range in Lync.

Within Lync I assign all enterprise voice users with a phone number and extension.
Some users have a DDI assigned whilst others use the base office number with an extension.

Each office has its own extensions range

100 – 109 HQ response Groups
110 – 299 HQ Users
300 – 399 Branch Office 1
400 – 499 Branch Office 2

Over time and depending on who activates new staff members the extensions tend to get out of sequence, so finding the next available extension within a range can be tedious.

The Get-FreeExtensions.ps1 script makes finding available extensions a lot easier.

The script has 4 parameters:
BaseNumber
ExtensionsRequired
ExtRangeStart
ExtRangeEnd

BaseNumber is the base number to search against without the +, ExtensionsRequired is the number of extensions that are needed within a given range, where ExtRangeStart and ExtRangeEnd define the range.

The script is run as the example below in order to generate 5 free extensions within the range 110 to 299

Get-FreeExtensions.ps1 -BaseNumber 442890454433 -ExtensionsRequired 5 -ExtRangeStart 110 -ExtRangeEnd 299

The script will always find the free extensions in ascending numerical order

<#
  .SYNOPSIS
  Finds free extensions within a given range
 
  .Author
  Alan.McBurney
 
  THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE
  RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
 
  Version 1.0, August 28th, 2014
  Version 1.1, December 16th, 2014
 
    .Description
  This script will find the next available extension(s) within a given extension range.
  The script searches for extensions across:
    Users
    RgsWorkflows
    AnalogDevices
    CommonAreaPhones
    Unified Messaging
    MeetingRooms
  The script will also throw a warning if the number of required extensions are not
  available within the given range.
  
  .PARAMETER -BaseNumber
  This the base number to search for a free extension within
  
  .Parameter -ExtensionsRequired
  This is the number of free extensions that are required
  
  .Parameter -ExtRangeStart
  This is the start of the range to query
  
  .Parameter -ExtRangeEnd
  This is the end of the Range to query
  
  .Example
  Get-FreeExtensions.ps1 -BaseNumber 442890454433 -ExtensionsRequired 5 -ExtRangeStart 100 -ExtRangeEnd 199
#>
param
(
  [parameter(Position=1,Mandatory=$true,ValueFromPipeline=$false,HelpMessage='Base Number without +')][long]$BaseNumber,
  [parameter(Position=2,Mandatory=$true,ValueFromPipeline=$false,HelpMessage='Number of Extensions Required')][int]$ExtensionsRequired,
  [parameter(Position=3,Mandatory=$true,ValueFromPipeline=$false,HelpMessage='Extension Range Start')][int]$ExtRangeStart,
  [parameter(Position=4,Mandatory=$true,ValueFromPipeline=$false,HelpMessage='Extension Range End')][int]$ExtRangeEnd
)
  
#Check to Ensure Lync Module is loaded or can be loaded
Function Get-MyModule
{
  Param([String]$Name)
  if (-not(Get-Module -name $Name))
  {
    if(Get-Module -ListAvailable | Where-Object {$_.Name -eq $Name})
    {
      Import-Module -Name $Name
    }
    else
    {
      Write-Host $Name PowerShell Module Not Available -ForegroundColor Red
    }
  }
}
  
Get-MyModule -Name Lync
  
Function Get-LyncExtensions
{
  $Extensions = @()
  $Extensions += (Get-CsUser).LineURI | Where-Object {$_ -match "$BaseNumber;ext="}
  $Extensions += (Get-CsUser).PrivateNumber | Where-Object {$_ -match "$BaseNumber;ext="}
  $Extensions += (Get-CsRgsWorkflow).LineURI | Where-Object {$_ -match "$BaseNumber;ext="}
  $Extensions += (Get-CsAnalogDevice).LineURI | Where-Object {$_ -match "$BaseNumber;ext="}
  $Extensions += (Get-CsCommonAreaPhone).LineURI | Where-Object {$_ -match "$BaseNumber;ext="}
  $Extensions += (Get-CsExUMContact).LineURI | Where-Object {$_ -match "$BaseNumber;ext="}
  $Extensions += (Get-CsMeetingRoom).LineURI | Where-Object {$_ -match "$BaseNumber;ext="}
  if (($Extensions).Count -gt "0")
    {
      $Extensions -replace "tel:\+$BaseNumber;ext=" | Sort
    }
}

If ((Get-LyncExtensions).Count -eq "0")
{
  Write-Host "Invalid Base Number detected, please ensure the base number is valid" -ForegroundColor Red
}
Else
{   
$UnUsedCount = 0
$ExtRange = ($ExtRangeStart..$ExtRangeEnd)
$FreeExt = @()
$UsedExt = Get-LyncExtensions
$CompareUsed = Compare-Object $UsedExt $ExtRange
   
foreach ($ext in $CompareUsed)
{
  if($ext.sideIndicator -eq "=>") {$FreeExt+=$ext.inputobject;$UnUsedCount++}
}
  
if ($ExtRangeStart -gt $ExtRangeEnd)
{
  Write-Host "Extension End Range must be equal or greater to Extension Start Range" -ForegroundColor Yellow
  } elseif ($ExtensionsRequired -gt $ExtRange.Count) {
    Write-Host "Extensions Required is greater than Specifed Extensions Range. Please ammend the Extension Range End parameter" -ForegroundColor Yellow
  } elseif ($ExtensionsRequired -gt $UnUsedCount) {
    Write-Host "Not enough free extensions within the specified range $ExtRangeStart-$ExtRangeEnd Maximum is $UnUsedCount" -ForegroundColor Yellow
  } else {
    $FreeExt | Select -First $ExtensionsRequired
  }
}

Posted in Lync, Lync 2013, PowerShell | Tagged: , , , , | Leave a Comment »

Script: Checking for Expired Certificates in Exchange

Posted by Alan McBurney on August 27, 2014

I was working with a customer that had unintentionally let their Exchange certificates expire.

This resulted in a bit of a headache for the team as users were now getting certificate warnings and mobility services were down until the certificate was replaced.

I decided to put together a script that will check and warn about expired or soon to expire certificates.
The script gets the certificates which have services bound to them on all Exchange 2010 client access and hub transport servers.
It checks for certificates that have expired or that will expire within the next 60 days and optionally emails the report and creates a schedule task.
An email will only be generated if expired\expiring certificates have been detected


<#
.SYNOPSIS
Detects expired certificates on Exchange 2010 Client Access & Hub Transport servers
 
.Author
Alan.McBurney
 
THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE
RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.
 
Version 1.0, August 27th, 2014
 
.DESCRIPTION
This script will get the certificates which have services bound to them on all Exchange 2010
client access and hub transport servers.
It checks the expiration for any certificates that are due to expire within 60 days and optionally
emails the report and creates a schedule task
An email will only be generated if expired\expiring certificates have been detected
 
.REFERENCES
Parameters, checks and scheduled tasks stolen from Steve Goodman's Exchange Environmental Reports script
 
http://gallery.technet.microsoft.com/exchange/Generate-Exchange-2388e7c9
 
.Notes
To Do list: Enable Autnetication for SMTP
Support for Exchange 2007 & 2013
 
.PARAMETER SendMail
Send Mail after completion. Set to $True to enable. If enabled, -MailFrom, -MailTo, -MailServer are mandatory
 
.PARAMETER MailFrom
Email address to send from. Passed directly to Send-MailMessage as -From
 
.PARAMETER MailTo
Email address to send to. Passed directly to Send-MailMessage as -To
 
.PARAMETER MailServer
SMTP Mail server to attempt to send through. Passed directly to Send-MailMessage as -SmtpServer
 
.PARAMETER ScheduleAs
Attempt to schedule the command just executed weekly. Specify the username here, schtasks (under the hood) will ask for a password later.
 
.EXAMPLE
Get-ExpiringEx2K10Certs
#>
 
param(
[parameter(Position=1,Mandatory=$false,ValueFromPipeline=$false,HelpMessage='Send Mail ($True/$False)')][bool]$SendMail=$false,
[parameter(Position=2,Mandatory=$false,ValueFromPipeline=$false,HelpMessage='Mail From')][string]$MailFrom,
[parameter(Position=3,Mandatory=$false,ValueFromPipeline=$false,HelpMessage='Mail To')]$MailTo,
[parameter(Position=4,Mandatory=$false,ValueFromPipeline=$false,HelpMessage='Mail Server')][string]$MailServer,
[parameter(Position=5,Mandatory=$false,ValueFromPipeline=$false,HelpMessage='Schedule as user')][string]$ScheduleAs
)
 
#Check Powershell Version
if ((Get-Host).Version.Major -eq 1)
{
  throw "Powershell Version 1 not supported";
}
 
#Check Exchange Management Shell, attempt to load
if (!(Get-Command Get-ExchangeServer -ErrorAction SilentlyContinue))
{
  if (Test-Path "C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1")
  {
    .'C:\Program Files\Microsoft\Exchange Server\V14\bin\RemoteExchange.ps1'
    Connect-ExchangeServer -auto
  } elseif (Test-Path "C:\Program Files\Microsoft\Exchange Server\bin\Exchange.ps1") {
    Add-PSSnapIn Microsoft.Exchange.Management.PowerShell.Admin
    .'C:\Program Files\Microsoft\Exchange Server\bin\Exchange.ps1'
    } else {
    throw "Exchange Management Shell cannot be loaded"
  }
}
 
# Check if -SendMail parameter set and if so check -MailFrom, -MailTo and -MailServer are set
if ($SendMail)
{
  if (!$MailFrom -or !$MailTo -or !$MailServer)
  {
    throw "If -SendMail specified, you must also specify -MailFrom, -MailTo and -MailServer"
  }
}
 
$Path=Get-Location
$Dir=$Path.ToString()
$HTMLReport = $Dir + "\ExpiredCerts.html"
$CASServers = Get-ExchangeServer | Where-Object {$_.AdminDisplayVersion -match "Version 14" -and $_.ServerRole -match [regex] 'Hub|Client'}
$Certs = Foreach ($srv in $CASServers) {Get-ExchangeCertificate -Server $srv| Where-Object {$_.NotAfter -le (Get-Date).AddDays(60) -and $_.Services -ne "None"} | Select @{n="Server";e={$srv.name}}, @{n="Expiry Date";e={$_.NotAfter}}, Thumbprint, Services, Issuer, Subject}
$Certs | ConvertTo-Html | Out-File $HTMLReport
 

if ($SendMail)
{
  if ($Certs.count -gt 0)
  { 
    Send-MailMessage -Attachments $HTMLReport -To $MailTo -From $MailFrom -Subject "Warning - Expired Exchange Certificates Detected" -Body "Expired or soon to be expired certificates have been detected on Exchange Servers. Please see attached file for certificates affected" -SmtpServer $MailServer
  }
}
 
if ($ScheduleAs)
{
  if ($SendMail)
  {
    $params+=' -SendMail:$true'
    $params+=" -MailFrom:$MailFrom -MailTo:$MailTo -MailServer:$MailServer"
  }
  $task = "powershell -c \""pushd $dir; $($myinvocation.mycommand.definition) $params\"""
  schtasks /Create /RU $ScheduleAs /RP /SC WEEKLY /ST 22:00 /TN ExpiredCerts /TR $task
}

Posted in Certificates, Exchange 2010, PowerShell, Windows 2008 R2, Windows Server 2012, Windows Servers | Tagged: , , | Leave a Comment »

Script: Fixing Orphaned AdminSDHolder Accounts

Posted by Alan McBurney on August 27, 2014

This is intended as a follow up to Detecting members of Protected Groups within AD

It seems that no matter how many Exchange or Lync projects I do I always come across the issue of orphaned AdminSDHolders.

To overcome the tedium of detecting and fixing orphaned users I decided to put together a script to automate the task.

This script gets all users that are members of protected groups within AD and compares membership with users that have the AD Attribute AdminCount=1 set. If the user has the AdminCount=1 enabled but is not a member of a protected group within AD then the user is considered orphaned, the AdminCount is reset to 0 and inheritable permissions are enabled.

<#
.SYNOPSIS
Detects Orphaned SD Admin users, resets admin count attribute and enables inheritable permissions

.Author
Alan.McBurney

THIS CODE IS MADE AVAILABLE AS IS, WITHOUT WARRANTY OF ANY KIND. THE ENTIRE
RISK OF THE USE OR THE RESULTS FROM THE USE OF THIS CODE REMAINS WITH THE USER.

Version 1.0, July 10th, 2014

.DESCRIPTION
This script gets all users that are members of protected groups within AD and compares
membership with users that have the AD Attribute AdminCount=1 set.
If the user has the AdminCount=1 enabled but is not a member of a protected group then the user
is considered an orphaned admin user and the AdminCount is reset to 0 and inheritable permissions
are reset

.REFERENCES
"http://blogs.technet.com/b/heyscriptingguy/archive/2010/07/11/hey-scripting-guy-weekend-scripter-checking-for-module-dependencies-in-windows-powershell.aspx">http://blogs.technet.com/b/heyscriptingguy/archive/2010/07/11/hey-scripting-guy-weekend-scripter-checking-for-module-dependencies-in-windows-powershell.aspx</a>
"http://blogs.msdn.com/b/muaddib/archive/2013/12/30/how-to-modify-security-inheritance-on-active-directory-objects.aspx">http://blogs.msdn.com/b/muaddib/archive/2013/12/30/how-to-modify-security-inheritance-on-active-directory-objects.aspx</a>

.EXAMPLE
Reset-OrphanSDUsers

.Notes
To Do list: Enable logging
#>

#Check to Ensure Active Directory PowerShell Module is available within the system
Function Get-MyModule
{
Param([string]$name)
if(-not(Get-Module -name $name))
  {
    if(Get-Module -ListAvailable |Where-Object { $_.name -eq $name })
    {
      Import-Module -Name $name
      $True | Out-Null
    }
    else
    {
      Write-Host ActiveDirectory PowerShell Module Not Available -ForegroundColor Red
    }
  } # end if not module
  else
  {
    $True | Out-Null
  }   #module already loaded
} #end function get-MyModule

Get-MyModule -name "ActiveDirectory"

Function Set-Inheritance
{
Param($ObjectPath)
$Acl = Get-ACL -path "AD:\$ObjectPath"
  If ($Acl.AreAccessRulesProtected -eq $True)
  {
    $Acl.SetAccessRuleProtection($False, $True)
    Set-ACL -AclObject $ACL -path "AD:\$ObjectPath"
  }
}

#Get List of Proected Groups
$AdminGrp = Get-ADGroup -LDAPFilter "(adminCount=1)"

#Get List of Admin Users (Past and Present)
$AdminUsers = Get-ADUser -LDAPFilter "(adminCount=1)"

$Admins = ForEach ($Grp in $AdminGrp) {Get-ADGroupMember $Grp | Where-Object {$_.ObjectClass -eq "User"}}

#Create Empty Hash
$PGUSers = @{}
$OrphanUsers = @{}

#Compare $AdminUsers to $Admins and place in appropriate hash table
ForEach ($User in $AdminUsers)
{
If ($Admins -Match $User.Name)
  {
    $PGUsers.Add($User.Name, "Present")
  }
  Else
  {
    $OrphanUsers.Add($User.SamAccountName, "NotPresent")
  }
}

If ($OrphanUsers.Keys.Count.Equals(0))
{
  $True | Out-Null
}
Else
{
  #Clear AdminCount Attribute
  ForEach ($Orphan in $OrphanUsers.Keys)
  {
    $Orphan
    $ADUser = Get-ADUser $Orphan
    Set-ADUser $Orphan -Clear {AdminCount}
    Set-Inheritance $ADUser
  }
}

Posted in Active Directory, Exchange 2010, Exchange 2013, Lync, Lync 2013, PowerShell | Tagged: , | 1 Comment »

Automating PowerShell Connection to Office 365

Posted by Alan McBurney on August 18, 2014

Connecting to Office 365 manually can be a bit of a chore especially if you need to do it on a regular basis, so why not automate the task.

Be sure the following components have been installed on your system before attempting this.

    • Azure Active Directory Module for Windows PowerShell
    • Microsoft Online Services Sign-In Assistant

In order to automate the task, credentials are exported to an XML file.

Get-Credential user@domain.com | Export-Clixml $env:USERPROFILE\Documents\MyO365Creds.xml

The cool thing about exporting the credentials used to connect to 365 using the Export-Clixml command is that the credentials are automatically encrypted within the file using DPAPI and can only by decrypted by the person who originally saved it.

image 

The final piece of the automation process is adding this into your PowerShell profile
First test to see if a profile exists

Test-Path $Profile

Running the above command will return either a True or False value.
True being that the profile exists, false that it doesn’t

If the return value is false then in order to create the profile run the code below

New-Item -Type File -Path $Profile

image

Once the profile exists, to open the Profile type

Notepad $Profile

Finally enter the following into your PowerShell profile. This will run every time you launch PowerShell

Import-Module MSOnline
$Cred = Import-Clixml $env:USERPROFILE\Documents\MyO365Creds.xml
Connect-MsolService -Credential $Cred

If you work with multiple office 365 accounts each one of these credentials can be represented by a variable within your PowerShell profile.

$Cust1Cred = Import-Clixml $env:USERPROFILE\Documents\Cust1O365Creds.xml
$Cust2Cred = Import-Clixml $env:USERPROFILE\Documents\Cust2O365Creds.xml
$Cust3Cred = Import-Clixml $env:USERPROFILE\Documents\Cust3O365Creds.xml

Typically I will omit the final line from the Profile to connect to the service.
Then its really simple to connect to a customers tenancy using

Connect-MSOLService –Credential $Cust1Cred

Posted in Office 365, PowerShell | Tagged: , , | Leave a Comment »

Install Certificate Services on Server 2012 Core

Posted by Alan McBurney on July 24, 2013

I’m finally getting the time to focus more and more on Windows Server 2012.

With Server 2012 I’m running Domain Controllers as server core installations.

My reasoning for running DC’s using core is as follows:

  • No additional software can be installed on the server. Domain Controllers are Domain Controllers are Domain Controllers.
  • With server core installations admins generally don’t log onto the server unless they are comfortable with the command line and Shell and even then they only log on typically when something needs to be changed with the configuration.
  • Surface area is greatly reduced as there are limited binaries installed.
  • Memory is also minimal. My server core installs are running with 512MB RAM
  • Disk requirements are reduced

All of the above in my opinion leads to a more stable system.
On the downside though it takes a bit more work to get things up and running.

Getting Certificate Services up and running on the server core installation was pretty easy.

Once logged onto the server I run PowerShell from the cmd line and then Import-Module ServerManager

image

Next is to add the Active Directory Certificate Services & Certification Authority roles

Add-WindowsFeature AD-Certificate, ADCS-Cert-Authority

A reboot is required after installation.

After the comes has rebooted we can check that the features have been installed by running

Get-WindowsFeature | Where Installed

image

We now need to configure the Certificate Authority. To do this we need a bit of code that Microsoft has handily already provided here

Copy the code into notepad on the server core installation and save to a  location on the disk.
(I RDP to my server core installation and therefore can paste the clipboard contents from my desktop to the server core console.)

Final piece of the configuration is to run the SetupCA.vbs fiile using the following parameters

cscript SetupCA.vbs /IE

image

Once installed I can now manage the CA from any workstation or  server running RSAT.

image

Posted in Certificate Authority, Certificates, PowerShell, Server Core, Windows Server 2012 | Tagged: , , | 1 Comment »

Creating File Shares with PowerShell

Posted by Alan McBurney on July 23, 2013

I’m gradually moving more and more to PowerShell only for server administration.

Today I needed to create a new file share for a Lync 2013 Std Edition installation on Server 2012 and once again I looked to achieve this though the Shell.

As it turns out that this is a very simple task so with no further ado here is the syntax

New-SmbShare –Name LyncShare -Path C:\LyncShare –Description “Lync 2013 File Share” –FullAccess Administrators

Posted in Active Directory, Lync, Lync 2013, PowerShell | Tagged: , | Leave a Comment »

Detecting members of Protected Groups within AD

Posted by Alan McBurney on July 16, 2013

I do a lot Exchange and Lync work and typically post project I get calls from customers that things aren’t working quite as expected.

Some typical issues include insufficient rights to modify users within Lync, ActiveSync not working or send as permissions being stripped out for users within Exchange.

What all these issues have in common is that users affected are members of what’s termed as Protected Groups within AD and security inheritance is being stripped from the user object.

If you need a primer or a deep dive for that matter into Protected Groups see John Policelli’s article here

The following Active Directory PowerShell commands can be used detect which users and groups are affected by Protected Group status.

To get the list of protected users:
     Get-ADUser -LDAPFilter "(admincount=1)" | select name

To get the list of protected groups:
     Get-ADGroup -LDAPFilter "(admincount=1)" | select name

Once the users have been removed from the Protected Groups its just a matter of enabling security inheritance for the user object from within AD and the issues should be resolved. 

Posted in Active Directory, Exchange 2010, Exchange 2013, Lync, PowerShell, Windows 2008 R2, Windows Server 2012 | Tagged: , | 2 Comments »

Unable to Connect to Exchange Management Shell after SP2 installation

Posted by Alan McBurney on September 12, 2012

After patching a number DAG nodes with SP2 I was unable to open the EMC from any of the mailbox servers.

The follow error was displayed

SNAGHTML737be47

To resolve this issue I downloaded the Exchange Management Console Troubleshooter Tool EMTShooter

After running the tool it found an error and displayed the following

image

After reading through the possible solutions I discounted options 2 & 3 as these had already been investigated and the settings were correct.

So with that I settled on option 1.

After examining the GlobalModules of C:\Windows\System32\Inetsrv\config\ApplicationHost.config I could see that the entry for WSMan was indeed missing

image

I added the entry and closed the file

image

Refresh the EMC and viola, good as new.

image

Posted in EMC, Exchange 2010, PowerShell | Tagged: , , , , , | Leave a Comment »

Rebuilding an Exchange DAG

Posted by Alan McBurney on April 10, 2012

Recently I’ve been working with a customer where their DAG has been misbehaving.

The DAG was stretched between 2 AD sites. There were multiple issues with cluster resources in addition to the PAM (Primary Active Manager) not failing over properly

After looking at it for a few hours I decided that the best course of action would be to rebuild the DAG

The following are the steps required in order to remove the DAG and rebuild it

  • Remove All Database Copies from the DAG

Remove-MailboxDatabaseCopy “DBName\ServerToRemove” –Confirm:$False

  • Turn off DataCenter Activation Mode

Set-DatabaseAvailabilityGroup -Identity DAG1 -DatacenterActivationMode Off

  • Remove the MailboxServers from the DAG

Remove-MailboxDatabaseAvailabilityServer DAG1 –MailboxServer ServerToRemove

Be sure to allow time for replication to occur between executing commands

  • Recreate the DAG

New-DatabaseAvailabilityGroup -Name DAG1 –WitnessServer “WitnessServer” -WitnessDirectory D:\DAG1  -DatabaseAvailabilityGroupIpAddresses 192.168.100.100,192.168.101.100

  • Add the servers back into the DAG

Add-DatabaseAvailabilityGroupServer -Identity DAG1 –MailboxServer “SourceMBXServer”
repeat this command for all servers that you wish to add

  • Enable Database Activation Mode

Set-DatabaseAvailabilityGroup -Identity DAG1 -DatacenterActivationMode DAGOnly

  • Finally Add the mailboxdatabase copy server

Add-MailboxDatabaseCopy –Identity DBName -MailboxServer MBXServerToAdd -ActivationPreference 2

  • Finally we can test the Primary Active Manager Failover

Cluster.exe DAG1.DOMAIN.LOCAL Group “Cluster Group” /MoveTo:PassiveServerNode

Posted in Exchange 2010, PowerShell | Tagged: , , , , , , , | Leave a Comment »

Reseed failed DAG database copies

Posted by Alan McBurney on September 16, 2011

I have been working with a customer that has a large number of Exchange databases and wishing to to protect these with a DAG solution.

A multi node DAG had been built for the customer and one of the nodes was being problematic when it came to the initial seeding of the database.
The databases would initially seed fine, however as soon as they finished the DB’s momentarily reported “Healthy” before changing status to “FailedandSuspended”

I tried a number of fixes for this including manually copying log and catalog files, however nothing seemed to work. Then in true Microsoft fashion a reboot of the server resolved the issues and the databases seeded properly. After running an update against a DB it’s status remained “Healthy”

As previously stated the customer had a large number of DB’s that were being replicated so I resorted to the Shell to fix the remainder of the DB’s that were “FailedandSuspended”

The following command was used to bring the remainder of the DB’s back to a healthy state

Get-MailboxDatabaseCopyStatus –Server (MBXServerName) | Where-Object {$_.Status –eq “FailedandSuspended”} | Update-MailboxDatabaseCopy –DeleteExistingFiles –SourceServer (SourceMBXServerName)


Job done 🙂

Posted in Exchange 2010, PowerShell | Tagged: , , , | Leave a Comment »