Nous avons été chargés de surveiller l'utilisation d'Exchange 2003, mais il ne semble pas y avoir de composant de rapport intégré à Exchange 2003 Standard. Cela signifie-t-il qu'il faut utiliser des services de rapports tiers ou puis-je utiliser des puits d'événements ou des journaux pour envoyer les données d'utilisation au serveur SQL pour un traitement différé ?
Les domaines que j'aimerais le plus connaître sont les suivants :
- Nombre de messages envoyés/reçus par l'utilisateur et dans son ensemble.
- Combien de messages non lus dans la boîte de réception des utilisateurs.
- Temps de connexion (remarque : BackupExec se " connecte " aux boîtes aux lettres)
Je suis également ouvert aux suggestions de bons indicateurs pour mesurer l'adoption des fonctionnalités par les utilisateurs finaux, par exemple le nombre de contacts, d'éléments de calendrier, de demandes de réunion, de notes, etc. dans la boutique.
Solution
J'ai choisi d'utiliser PowerShell pour collecter les statistiques d'Exchange, car en passant à Exchange 2007 et à PowerShell 2.0, il y a plus d'options pour collecter les données, et je peux m'appuyer sur les bases existantes.
Le script s'exécute à 0400 tous les jours et repose sur un serveur SQL 2005/2008 et LogParser étant installé sur un serveur ayant accès aux journaux de suivi des messages Exchange.
Nombre de messages envoyés/reçus
J'ai construit la ligne de commande en utilisant LogParser.exe puis je l'ai transposée dans l'objet COM que j'utilise dans le script de powershell dans la fonction suivante :
function Execute-LogParserQueryToSQL([string] $Query)
{
Write-Host $Query
$LogParser = New-Object -com MSUtil.LogQuery
$Input = New-Object -comObject MSUtil.LogQuery.W3CInputFormat
$Output = New-Object -comObject MSUtil.LogQuery.SQLOutputFormat
$Output.server = "<your server>"
$Output.database = "<your database>"
$Output.username = "<your username>"
$Output.Password = "<your password>"
$Result = $LogParser.ExecuteBatch($Query, $Input, $Output)
return $Result
}
La fonction qui parcourt en boucle tous les journaux créés hier ou avant (peut en faire plusieurs au cas où elle ne fonctionnerait pas un jour pour une raison quelconque) supprime ensuite le fichier journal. Si vous utilisez le suivi des messages dans un autre but, ne supprimez pas le fichier journal, utilisez un autre mécanisme pour le "marquer comme utilisé".
function Execute-SentReceivedSummary()
{
$TodaysLog = ("{0}.log" -f,(Get-Date -f yyyyMMdd))
$MessageTrackingDir = "D:\Exchange\Logs\PORSCHE.log"
$LogsToParse = Get-ChildItem -Path $MessageTrackingDir
$SentEmailQuery = "SELECT Date,Sender-Address AS Account,Count(*) AS Count INTO DailySentEmailByUser FROM '{0}' WHERE Event-ID=1027 GROUP BY Sender-Address,Date"
$ReceivedEmailQuery = "SELECT Date,Recipient-Address AS Account,Count(*) AS Count INTO DailyReceivedEmailByUser FROM '{0}' WHERE Event-ID=1028 GROUP BY Recipient-Address,Date"
foreach ($Log in $LogsToParse)
{
if ($Log.ToString() -ne $TodaysLog)
{
$Query = ($SentEmailQuery -f,$Log.FullName)
Execute-LogParserQueryToSQL $Query
$Query = ($ReceivedEmailQuery -f,$Log.FullName)
Execute-LogParserQueryToSQL $Query
Remove-Item $Log.FullName
}
}
return $true
}
Combien de messages non lus dans la boîte de réception de l'utilisateur ?
Finalement, nous avons décidé que la taille totale et le nombre d'éléments dans la boîte aux lettres constituaient une mesure plus utile. Certains membres du personnel avaient un nombre considérable de messages non lus mais consultaient leur courrier électronique tous les jours (généralement parce qu'il s'agissait d'e-mails de type FYI et que l'objet leur disait tout ce qu'ils avaient besoin de savoir).
Comme nous ne voulions que des données réelles (datant de 24 heures maximum), je devais tronquer le tableau avant d'insérer de nouvelles données :
function Truncate-TotalsTable()
{
$SqlConnection = new-object system.data.oledb.oledbconnection
$SqlConnection.connectionstring = "<your connect string>"
$SqlConnection.open()
$Query = "TRUNCATE TABLE TotalsTable"
$SqlCommand = New-Object system.data.oledb.oledbcommand
$SqlCommand.connection = $SqlConnection
$SqlCommand.commandtext = $Query
$SqlCommand.executenonquery()
$SqlConnection.close()
return $true;
}
Ensuite, nous utilisons WMI pour extraire les données du serveur Exchange et les pousser dans SQL :
function Execute-MailboxTotalsQuery()
{
$Result = Truncate-TotalsTable
$Count = 0;
$SqlConnection = new-object system.data.oledb.oledbconnection
$SqlConnection.connectionstring = "<your connect string>"
$SqlConnection.open()
$MailboxReport = Get-Wmiobject -class Exchange_Mailbox -Namespace ROOT\MicrosoftExchangev2 -ComputerName <your exchange server>
foreach ($Mailbox in $MailboxReport)
{
$MailboxDN = $Mailbox.MailboxDisplayName
$TotalItems = [int]$Mailbox.TotalItems
$TotalSize = [int]$Mailbox.Size
$MailboxDN = $MailboxDN -replace "'","''"
$Query = [String]::Format("INSERT TotalsTable Values ('{0}',{1},{2})",$MailboxDN, $TotalItems, $TotalSize)
$SqlCommand = New-Object system.data.oledb.oledbcommand
$SqlCommand.connection = $SqlConnection
$SqlCommand.commandtext = $Query
$Result = $SqlCommand.executenonquery()
$Count = $Count + $Result
}
$SqlConnection.close()
return $Count;
}
Temps de connexion
Après avoir utilisé LogParser pour examiner le journal des événements de sécurité, les résultats que nous avons obtenus n'étaient pas très utiles. L'ID de l'événement que nous recherchions était 540, ce qui couvrait à la fois les connexions Outlook et OWA (et d'autres connexions), nous avons décidé que la quantité de travail nécessaire pour mettre en œuvre cette solution ne valait pas le retour. Ceci est en partie dû au fait qu'il faudrait analyser et filtrer par corps de message pour isoler les différents types de connexion au-delà de l'événement 540.
Je suis ouvert aux suggestions et aux soumissions d'autres scripts PowerShell utiles.
0 votes
Génial, Richard ! Merci de partager. J'ai été assez évasif en ce qui concerne PowerShell, mais ceux-ci semblent être des scripts vraiment utiles et une grande utilisation des facilités fournies par Microsoft. Je vais leur donner une chance !
0 votes
Heureusement pour moi, je suis un programmeur (dans l'âme) employé en tant que Sys. J'ai donc pris plaisir à mettre en place ces scripts, je me suis longtemps tenu à l'écart de PowerShell, c'est le premier projet pour lequel il a vraiment du sens.