evetsleep

Start-TransportLogSearch

Aug 6th, 2013
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #Requires -version 3
  2.  
  3. function Start-TransportLogSearch
  4. {
  5.     <#
  6.     .Synopsis
  7.     Searches one or more Exchange transport logs and sends the output to XML.
  8.    
  9.     .DESCRIPTION
  10.     Creates a PowerShell job for each Exchange transport server to be searched and
  11.     that job searches based onteh parameters defined in the search.  
  12.    
  13.     The output is exported as XML to the path defined.  By default only 4 jobs
  14.     run at a time.  As jobs complete additional jobs are submitted.
  15.        
  16.     .PARAMETER ComputerName
  17.     One or more computer names (Exchange transort servers) to search.
  18.        
  19.     .PARAMETER Start
  20.     The start time of the search
  21.        
  22.     .PARAMETER End
  23.     The end time of the search
  24.        
  25.     .PARAMETER Sender
  26.     Return results where the sender matches this address
  27.        
  28.     .PARAMETER Recipient
  29.     Return results for e-mail addressed to the recipient provided.
  30.        
  31.     .PARAMETER EventId
  32.     The eventId of the tracking event to match.
  33.        
  34.     .PARAMETER Threshold
  35.     How many transport jobs to spawn at one time.
  36.    
  37.     .PARAMETER Path
  38.     Where to create the resulting XML files.  The default is the current working directory.
  39.        
  40.     .EXAMPLE
  41.     Start-TransportLogSearch -ComputerName server01a,server01b,server01c -Start (get-date "08/01/2013 00:00") -end (get-date 08/02/2013 "00:00") -EventId RECEIVE -Sender '[email protected]'
  42.    
  43.     This starts 3 PowerShell jobs that run in parallel that searches for all mail with the
  44.     eventId of RECEIVE that was submitted by Mr. Gates 08/01/2013 through 08/02/2013.
  45.        
  46.     .EXAMPLE
  47.     $start     = (get-date).addDays(-3)
  48.     $end       = (get-date)
  49.     $recipient = '[email protected]'
  50.     $path      = 'c:\Temp\ExchangeLogs'
  51.     Get-TransportServer | Start-TransportLogSearch -start $start -end $end -recipient $recipient -Path $path
  52.    
  53.     This starts a transport log search against all transport servers in the Exchange organization for mail addressed to
  54.     [email protected] that has been submitted over the past 3 days.  Each job that is spawned will generate an XML
  55.     file that will be deposited in c:\Temp\ExchangeLogs that can be processed later.
  56.     #>
  57.     [CmdletBinding()]
  58.     Param
  59.     (
  60.         [Parameter(Mandatory=$true,
  61.                 ValueFromPipelineByPropertyName=$true,
  62.                 ValueFromPipeline=$true,   
  63.                 Position=0)]
  64.         [Alias('Identity')]
  65.         [String[]]$ComputerName,
  66.  
  67.         [Parameter(Mandatory=$false,
  68.                 ValueFromPipelineByPropertyName=$false,
  69.                 Position=1)]
  70.         [datetime]$Start = $(get-date).addHours(-1),
  71.  
  72.         [Parameter(Mandatory=$false,
  73.                 ValueFromPipelineByPropertyName=$false,
  74.                 Position=2)]
  75.         [datetime]$End = $(Get-Date),
  76.  
  77.         [Parameter(Mandatory=$false,
  78.                 ValueFromPipelineByPropertyName=$false,
  79.                 Position=3)]
  80.         [String]$Sender = $null,
  81.  
  82.         [Parameter(Mandatory=$false,
  83.                 ValueFromPipelineByPropertyName=$false,
  84.                 Position=4)]
  85.         [String]$Recipient = $Null,
  86.  
  87.         [Parameter(Mandatory=$false,
  88.                 ValueFromPipelineByPropertyName=$false,
  89.                 Position=5)]
  90.             [ValidateSet("BADMAIL","DEFER","DELIVER","DSN","EXPAND","FAIL","PROCESS","RECEIVE","RESOLVE","SEND","TRANSFER")]
  91.         [String]$EventId = 'RECEIVE',
  92.  
  93.         [Parameter(Mandatory=$false,
  94.                 ValueFromPipelineByPropertyName=$false,
  95.                 Position=6)]
  96.         [int]$Threshold = 4,
  97.  
  98.         [Parameter(Mandatory=$false,
  99.                 ValueFromPipelineByPropertyName=$false,
  100.                 Position=6)]
  101.         [String]$Path = (Get-Location).Path
  102.     )
  103.  
  104.     Begin
  105.     {
  106.         #Code to run within the job.
  107.         $openScriptBlock = {
  108.             param($serverName,$start,$End,$Sender,$Recipient,$EventId)
  109.            
  110.             Function Connect-ExchangeServer
  111.             {
  112.                 [CmdletBinding()]
  113.                 [OutputType([PSObject])]
  114.                 Param
  115.                 (
  116.                     #Computer name to connect to.
  117.                     [Parameter(Mandatory=$true,
  118.                             ValueFromPipelineByPropertyName=$false,
  119.                             Position=0)]
  120.                     [Alias('Identity')]
  121.                     $ComputerName,
  122.                
  123.                     #Computer name to connect to.
  124.                     [Parameter(Mandatory=$false,
  125.                             ValueFromPipelineByPropertyName=$false,
  126.                             Position=1)]
  127.                     [String[]]$Commands
  128.                 )
  129.  
  130.                 $sessionParam = @{
  131.                     ConfigurationName = 'Microsoft.Exchange'
  132.                     ConnectionUri     = "http://$ComputerName/PowerShell/"
  133.                     Authentication    = 'Kerberos'
  134.                     ErrorAction       = 'STOP'
  135.                     }  
  136.  
  137.                 Try
  138.                 {
  139.                     $psSession = New-PSSession @sessionParam       
  140.                 }
  141.                 # Catch specific types of exceptions thrown by one of those commands
  142.                 Catch
  143.                 {
  144.                     Write-Warning -Message ("[{0}]There was an error creating the PSSession: {1}" -f $ComputerName,$_.exception.message)
  145.                     return
  146.                 }  
  147.  
  148.  
  149.                 $sessionImport = @{
  150.                     Session             = $psSession
  151.                     AllowClobber        = $true
  152.                     ErrorAction         = 'STOP'
  153.                     }  
  154.                
  155.                 if ($Commands)
  156.                 {
  157.                     $Commands += 'Set-ADServerSettings'
  158.                     $sessionImport.Add('CommandName',$Commands)
  159.                 }
  160.  
  161.                 Try
  162.                 {
  163.                     Import-Module (Import-PSSession @sessionImport) -Global -DisableNameChecking
  164.                 }
  165.                 # Catch specific types of exceptions thrown by one of those commands
  166.                 Catch
  167.                 {
  168.                     Write-Warning -Message ("[{0}]Could not complete import: {1}" -f $ComputerName,$_.exception.message)
  169.                     return
  170.                 }
  171.  
  172.             } #END Connect-ExchangeServer
  173.  
  174.  
  175.             Connect-ExchangeServer -ComputerName $serverName -commands Get-MessageTrackingLog          
  176.            
  177.             #Parameters to pass to Get-MessageTrackingLog
  178.             $splat = @{
  179.                 Server     = $serverName
  180.                 Start      = $start
  181.                 End        = $end
  182.                 EventId    = $EventId
  183.                 ResultSize = 'Unlimited'
  184.                 }
  185.            
  186.             #If a sender is specified, add that as a parameter.                  
  187.             if($Sender)
  188.             {
  189.                 $splat.Add('Sender',$Sender)
  190.             }
  191.  
  192.             #Same thing as a recipient.
  193.             if($Recipient)
  194.             {
  195.                 $splat.Add('Recipient',$Recipient)
  196.             }
  197.  
  198.             #Get the data.
  199.             Get-MessageTrackingLog @splat
  200.             }
  201.  
  202.         #Keep track of batches
  203.         $batch = 0
  204.  
  205.         #BatchTime
  206.         [string]$batchTime = get-date -Format hhmmss
  207.     } #END BEGIN
  208.  
  209.     Process
  210.     {
  211.         #Go through each computer\identity and query the logs.
  212.         foreach ($computer in $ComputerName)
  213.         {
  214.             #Check to see if there are any running jobs.  If so wait until the count of
  215.             #running jobes is below the threshold before continuing.
  216.             while ( $(Get-Job -State Running).count -ge $Threshold )
  217.             {
  218.                 Write-Verbose -Message "There are $threshold jobs running.  Sleeping."
  219.                 Start-Sleep -Seconds 5
  220.             }
  221.  
  222.             #Check to see if there are any completed jobs.  If so export them and clean up.
  223.             if( $(Get-Job -State Completed) )
  224.             {
  225.                 foreach ($job in $(Get-Job -State Completed))
  226.                 {
  227.                     #Build the file name for the XML file that we'll generate.
  228.                     $timeStamp = Get-Date -Format hhmmss
  229.                     $jobName = $job.Name
  230.                     $XMLPath = Join-Path $path "Batch-$timeStamp-$jobName.xml"
  231.  
  232.                     try
  233.                     {
  234.                         #Get the results of the job and store them as an XML file.
  235.                         Receive-Job -Wait -AutoRemoveJob -id $job.Id -ErrorAction Stop | Export-Clixml -Path $XMLPath -Force -ErrorAction Stop
  236.                     }
  237.                     catch
  238.                     {
  239.                         Write-Warning -Message $("{0} : {1}" -f $computer,$_.exception.message)
  240.                         continue
  241.                     }
  242.  
  243.                     #Keeps memory usage optimal.
  244.                     Write-Verbose -Message "Taking out the garbage"
  245.                     [GC]::Collect()
  246.                 }
  247.             }
  248.  
  249.             #Start a new job.
  250.             Write-Verbose -Message $("Processing: {0}" -f $computer)
  251.             Start-Job -Name $computer -ScriptBlock $openScriptBlock -ArgumentList $computer,$Start,$End,$Sender,$Recipient,$EventId | Out-Null
  252.         } #END foreach computer
  253.  
  254.     } #END PROCESS
  255.     End
  256.     {
  257.         #Wait until all running jobs are done and then continue.
  258.         Write-Verbose "Waiting for jobs to finish"
  259.         Get-Job | Wait-Job | out-null
  260.  
  261.         Write-Verbose -Message "Cleaning up remaining jobs."
  262.         foreach ($job in $(Get-Job -State Completed))
  263.         {
  264.             $timeStamp = Get-Date -Format hhmmss
  265.             $jobName = $job.Name
  266.             $XMLPath = Join-Path $path "Batch-$timeStamp-$jobName.xml"
  267.            
  268.             try
  269.             {
  270.                 Receive-Job -Wait -AutoRemoveJob -id $job.Id -ErrorAction Stop | Export-Clixml -Path $XMLPath -Force -ErrorAction Stop
  271.             }
  272.             catch
  273.             {
  274.                 Write-Warning -Message $("{0} : {1}" -f $computer,$_.exception.message)
  275.                 continue
  276.             }
  277.             Write-Verbose -Message "Taking out the garbage"
  278.             [GC]::Collect()
  279.         }
  280.         Write-Verbose -Message "XML files written to $path"
  281.     }
  282. } #END Start-TransportLogSearch
Advertisement
Add Comment
Please, Sign In to add comment