Fix-ResynchronizingOrInitializing.ps1

#MsExchange #Powershell

Sometimes you get databases in a DAG with an Initializing or Resynchronizing state.  The way I have found to fix this is to Suspend the database copy and then resume it.

If you have quite a few databases its a pain in the butt using the console to do this .. so I wrote this.  You have to run it on the server that has a copy in either Initializing or Resynchronizing state.

##########################################################################################
#Load the Exchange 2010 bits & bobs
#########################################################################################
$xPsCheck = Get-PSSnapin | Select Name | Where {$_.Name -Like "*Exchange*"}
If ($xPsCheck -eq $Null) {Write-Host "Loading Exchange Snapin"; Add-PsSnapin Microsoft.Exchange.Management.PowerShell.e2010}

$gmdcs = Get-MailboxDatabaseCopyStatus
ForEach($item in $gmdcs){
  $tmpstatus = $item.Status
  $tmpName   = $item.Name
  Write-Host $tmpName "["$tmpStatus"]"
  IF (($tmpStatus -eq "Resynchronizing") -OR ($tmpStatus -eq "Initializing")){
    Write-Host "- Suspending"
    suspend-MailboxDatabaseCopy -Identity $tmpName -Confirm:$False
    Write-Host "- Resuming"
    resume-MailboxDatabaseCopy -Identity $tmpName
  }
}

Exchange 2013 Command Log

#MsExchange #Powershell

One of the things I like about Exchange 2010 is the ability in the Exchange Management Console to view the command log.  So typically I would do some in the console, the get the command by clicking View and selecting View Exchange Management Shell Command Log, finding the command I just ran and using it in a script.

Well Exchange 2013 is all web based now and that feature has gone :-( but you can still get the information by using the  Search-AdminAuditLog cmdlet.

This works for both Exchange 2010 and 2013 .. enjoy

$whoai = ([System.Security.Principal.WindowsIdentity]::GetCurrent()).Name
 $saal = Search-AdminAuditLog -UserIds $whoai | Sort RunDate -Descending
 $Matrix = @()
 ForEach($Item in $saal){
 $tmpMatrix = ""|Select Caller, When, Change
 $tmpMatrix.Caller = $Item.Caller
 $tmpMatrix.When = $Item.RunDate
 $tmpMatrix.Change = $Item.CmdLetName + " "
 $tmpMatrix.Change += "'" + $item.ObjectModified + "' "
$tmpCmdletParameters = $item.CmdletParameters
 $Param = ""
 ForEach($tmpParam in $tmpCmdletParameters){
 $Param += " -" + $tmpParam.Name + " '" + $tmpParam.Value + "' "
 }
 $tmpMatrix.Change += $Param
 $Matrix += $tmpMatrix
 }
$Matrix | ft -auto -wrap

NetApp SnapManager for Exchange Reports and Powershell Brackets

#NetApp #Powershell

SME is a great tool, but it has an undocumented feature, where it doesn’t flush it’s report files.  Now these files get big and I wanted a way to zip or delete the files.

The issue is that the folder name has brackets in it [servername] and powershell treats brackets as “special”.
Try it! Open powershell, create a folder and put a file in the folder

md C:\ps\[test]

now dir it:

dir C:\ps\[test]

Nothing right, but it works with the command prompt.  It took figging ages and a fair amount of Bing time to work a way around it, it’s dead simple:

dir -LiteralPath C:\ps\[test]

Yeah baby! using -LiteralPath does the trick

Powershell Split String

#Powershell

I wanted to put a disclaimer in my profile.ps1 file, but I wanted it to look nice.  I wanted it to split at 67 characters and split whole words.

It was a painful exercise, but this works!

$message="This system is the property of Flaphead.com, and provided only for authorised used according to Flaphead.com policies. This system may be subject to monitoring for lawful purposes and to ensure compliance with Flaphead.com policies in accordance with all applicable legislation. Use of this system constitutes consent to lawful monitoring, Flaphead.com policies and all applicable legislation."

$SplitAt = 67
$Start = 0
$MessageLength = $Message.Length
$MessageArray = @()
$more = $True
While($more){
$CharsLeft = $MessageLength - $Start
$splitNow = [math]::min($SplitAt, $CharsLeft)
$chars = $Message.substring($start,$SplitNow)
if($splitNow -ne $SplitAt){$tmpLine = $Chars}ELSE{ $tmpLine = $Message.substring($start,$chars.lastindexof(" ")+1)}
$start += $tmpLine.Length
IF([string]::IsNullOrEmpty($tmpLine)){$more=$False}ELSE{ $MessageArray += $tmpLine}
$tmpLine
if($start -gt $MessageLength){$more=$False}
}

Number of Mailboxes on an Exchange Server

#MsExchange #Powershell

I wanted to look at a quicker way to discover the number of mailboxes per database.  Sure you could run something like Get-MailboxDatabase | Get-Mailbox, but depending on the environment and number of mailboxes this does take an age.  Instead I discovered that the actual mailbox count per database is hidden in the AD!

So open the Exchange Management shell and run this!

Write-Host "Getting Mailbox Databases"
[array] $dbs = Get-MailboxDatabase
Write-Host ($dbs.count) "Found"

$matrix=@()
Write-Host "Getting Mailbox Count"
ForEach($db in $dbs){
$tmpMatrix = "" | Select database, usercount, Server
$tmpMatrix.Server = $db.Server
$dn = $db.DistinguishedName
$tmpMatrix.database = $db.name
[ADSI] $objDB = "GC://$($dn -replace ‘/’,'\/’)"
if ( ($objDB.objectClass -ne $null) -and ($objDB.objectClass.Contains(“msExchPrivateMDB”)) ) {
$tmpMatrix.usercount = [Math]::Max(0,([Int] ($objDB.homeMDBBL.Count)) – 1)
}
$matrix += $tmpMatrix
}

Quick ;-)