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


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, and provided only for authorised used according to policies. This system may be subject to monitoring for lawful purposes and to ensure compliance with policies in accordance with all applicable legislation. Use of this system constitutes consent to lawful monitoring, policies and all applicable legislation."

$SplitAt = 67
$Start = 0
$MessageLength = $Message.Length
$MessageArray = @()
$more = $True
$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}
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"

Write-Host "Getting Mailbox Count"
ForEach($db in $dbs){
$tmpMatrix = "" | Select database, usercount, Server
$tmpMatrix.Server = $db.Server
$dn = $db.DistinguishedName
$tmpMatrix.database = $
[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 ;-)