Using powershell to list users accessing OWA

Sometimes it’s useful to identify how many users are using Outlook Web Access, particularly for capacity management. Just because an account has OWA enabled, doesn’t mean it’s being used.

The below PowerShell script will enumerate the IIS logs looking for OWA access, if found it’ll add the user account to a list of accounts accessing OWA.

$path = "C:\WINDOWS\system32\LogFiles\W3SVC1\ex*"

# Create new DataTable to hold log entries
$tblLog = New-Object System.Data.DataTable "Log"
$arrUsers = New-Object System.Collections.ArrayList($null)
$bFirstRun = $TRUE;

foreach ($file in Get-ChildItem $path)
	# Get the contents of the file, excluding the first three lines.
	$fileContents = Get-Content $file.FullName | where {$_ -notLike "#[D,S-V]*" }

	# Create DataTable columns. No handling for different columns in
	# each log file.
	if( $bFirstRun )
		$columns = (($fileContents[0].TrimEnd()) -replace "#Fields: ", "" -replace "-","" -replace "\(","" -replace "\)","").Split(" ")
		$colCount = $columns.Length

		# Create a DataColumn from the column string and add to our DataTable.
		foreach ($column in $columns)
			$colNew = New-Object System.Data.DataColumn $column, ([string])
			$tblLog.Columns.Add( $colNew )
		$bFirstRun = $FALSE;
		Write-Host "Columns complete"
	# Get the row contents from the file, filtering what I want to retrieve.
	$rows = $fileContents | where {$_ -like "*/owa/Default.aspx*"}

	# Loop through rows in the log file.
	foreach ($row in $rows)

		$rowContents = $row.Split(" ")
		$newRow = $tblLog.newrow()
		for($i=0;$i -lt $colCount; $i++)
			$columnName = $columns[$i]
			$newRow.$columnName = $rowContents[$i]
		$tblLog.Rows.Add( $newRow )
	Write-Host $file.Name "Done"
$tblLog | foreach {  if(! $arrUsers.Contains( $_.csusername ) ) { $arrUsers.Add( $_.csusername ) } }

Continue reading Using powershell to list users accessing OWA

Locating PST files on a network

In order to size any mail archiving solution it is important to understand the amount of archive data currently in use. For many companies this is in the form of Outlook Data Files (PST’s). Unforutnately, the only resource Microsoft provide is a VBScript dating back to 2005 on the technet script center.

I decided to have a go at implementing two methods to locate PST files on the network using Powershell, the two options for locating files I came up with are:

  • Enumerate the Outlook settings on client computers to determine PST files loaded on client computers;
  • Use WMI to call the search APIs on remote computers to locate the files;

In testing the two options, using the search APIs via WMI located twice as many files as just relying on the information located in the windows registry. Both scripts will also read the first 11 bytes of the PST file to determine the file format, whether it’s an ANSI or Unicode PST file.

Continue reading Locating PST files on a network

Blackberry calendar not synchronising from device to Exchange

An issue was recently escalated to me where BES users were experiencing problems with their Blackberry calendar synchronisation. Appointments would appear on the device if they were created in Outlook, but not the other way around.

Blackberry Enterprise Server (BES) was running 5.0.3 on a Windows 2003 Virtual-Machine (VMware ESX).

Looking back over the logs on the server, the problem could be traced back to the installation of BES 5.0 Service Pack 3. The Changes in 5.0 SP3 didn’t show anything that could obviously cause this, so the first task was to update MAPI CDO to the latest version.

Digging throught the Messaging Agent log files yielded the following:

[40000] (01/06 00:00:04.871):{0x268} Failed to start CDO helper 070FD658 in StartCalHelper, retcode = 128
[40000] (01/06 00:00:04.871):{0x268} {} StartCalHelper() failed in RunCalHelper
[40000] (01/06 00:00:04.871):{0x268} {} CDO helper 078FD658 returned error '100' failed for LongTermEntryId=0 in LaunchCalHelper
[40000] (01/06 00:00:04.950):{0x268} {} Unable to launch CDO helper in SynchronizeHelper
[40000] (01/06 00:00:04.950):{0x268} {} Unable to process message with LongTermEntryId=0 in SynchronizeHelper
[20216] (01/06 00:00:04.950):{0x268} {} Synchronize() failed: ERR_FAIL, Tag=2242466
[40000] (01/06 00:00:04.950):{0x268} {}-UserControl::SlowSyncComplete-Entering SessID=4fce8f76
[40000] (01/06 00:00:04.950):{0x268} {}-UserControl::SlowSyncComplete-Exits result=OK
[40000] (01/06 00:00:04.950):{0x268} {}-HandleAppointmentToSynchronize-Exit-rc=Error
[40279] (01/06 00:00:04.950):{0x268} {} SubmitToRelaySendQ, Tag=2242466

After trying everything I could possibly think of, the problem turned out to be outdated NIC drivers. BES was running under VMware ESX using an emulated e1000 NIC which shows up in Windows as an “Intel PRO/1000 MT”. The out-the-box driver was version (from 2002). The latest version (from 2008) can be downloaded from the Intel website.

Updating to the latest driver resolved the problem (amazingly).