Powershell加速Get-MessageTrackingLog

时间:2018-03-23 13:55:52

标签: powershell powershell-v5.0 exchange-server-2013 exchange-management-shell powershell-jobs

目前我正在尝试获取所有已禁用用户的输出及其消息计数。通过foreach循环这很容易:

    $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://aserversomewhere.local/PowerShell/ -Authentication Kerberos -Credential $UserCredential
    Import-PSSession $Session -AllowClobber    

    Import-Module ActiveDirectory    

    $Users = Get-ADUser -filter * -Properties * -SearchBase "OU=Disabled User Accounts,DC=Private,DC=Private"

    $Today = (Get-Date).ToShortDateString()
    $OneMonthAgo = (Get-Date).AddMonths(-1).ToShortDateString()

    $results = @()

    $OnPrem = $Users | Where-Object {$_.mDBUseDefaults -eq "True"}
    $365 = $Users | Where-Object{$_.mDBUseDefaults -ne "True"}

    Write-Host "Start Date: " $OneMonthAgo -ForegroundColor Green
    Write-Host "Total Users OnPrem: " ($OnPrem.mail).Count -ForegroundColor Green

    foreach($User in $OnPrem)
    {
        Write-Host "Checking User: "$User.DisplayName -ForegroundColor Yellow
        $MessageCount = Get-MessageTrackingLog -recipients $User.Mail -Start $OneMonthAgo.ToString() | Where-Object {$_.EventID -eq "RECEIVE"} | Measure-Object

        Write-Host $User.Name": MessageCount: "$MessageCount.Count -ForegroundColor Cyan

         $Object = New-Object PSObject -Property @{
            User = $User.Name
            Email = $User.Mail
            Type = "OnPrem"
            DisabledDate = $User.Modified
            Location = $User.Office
            MessagesReceived = $MessageCount.Count
         }

         $script:results += $Object
    }

问题是这需要几个小时才能完成,因为它一次只运行一个用户。我的目标是通过工作或并行一次运行多个查询。由于交换服务器上的策略限制,这需要以10块为单位运行。

修改(有关原因的更多信息):

  

找到用户的消息计数的原因是,它们是   禁用并坐在禁用的OU中。原因是他们的原因   邮件是fw给另一个收件人。或者,他们的邮箱已被委派。   这是用于家务。搜索结果将是   通过MessageCount = 0过滤。然后它将被报告/保存为   删除了csv / users。

披露:我对在PowerShell中运行或并行运行非常无知。而且,我的google-foo似乎被打破了。任何指导或帮助都将非常感激。

版本信息:

Name             : Windows PowerShell ISE Host
Version          : 5.1.15063.966

更新:

在遵循Shawn的指导之后,我能够非常显着地成功加快这些要求。

更新代码:

$RunSpaceCollection = @()
$RunspacePool = [RunspaceFactory]::CreateRunspacePool(1, 10)
$RunspacePool.ApartmentState = "MTA"
$RunspacePool.Open()


$UserCredential = Get-Credential

Import-Module ActiveDirectory


$Users = Get-ADUser -filter * -Properties * -SearchBase "OU=Disabled User Accounts,DC=private,DC=private"

$Today = (Get-Date).ToShortDateString()
$OneMonthAgo = (Get-Date).AddMonths(-1).ToShortDateString()

[Collections.ArrayList]$results = @()

$OnPrem = $Users | Where-Object {$_.mDBUseDefaults -eq "True"}
$365 = $Users | Where-Object{$_.mDBUseDefaults -ne "True"}

Write-Host "Start Date: " $OneMonthAgo -ForegroundColor Green
Write-Host "Total Users OnPrem: " ($OnPrem.mail).Count -ForegroundColor Green

$scriptblock = {
    Param (
        [System.Management.Automation.PSCredential]$Credential,
        [string]$emailAddress,
        [string]$startTime,
        [string]$userName,
        [string]$loginName,
        [string]$DisabledDate,
        [string]$OfficeLocation
    )      

    $Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://someserver.local/PowerShell/ -Authentication Kerberos -Credential $Credential
    Import-PSSession $Session -AllowClobber -DisableNameChecking -Verbose:$false | Out-Null

    $MessageCount = Get-MessageTrackingLog -recipients $emailAddress -Start $startTime.ToString() -ResultSize unlimited  

    $Object = New-Object PSObject -Property @{
        User = $userName
        Login = $loginName
        Email = $emailaddress
        Type = "OnPrem"
        DisabledDate = $DisabledDate
        Location = $OfficeLocation
        MessagesReceived = $MessageCount.Count.ToString()
        }           

     $Object


}

foreach($User in $OnPrem)
{
    $Powershell = [PowerShell]::Create()
    $null = $Powershell.AddScript($scriptblock)
    $null = $Powershell.AddArgument($UserCredential)
    $null = $Powershell.AddArgument($user.mail)
    $null = $Powershell.AddArgument($OneMonthAgo)
    $null = $Powershell.AddArgument($user.Name)
    $null = $Powershell.AddArgument($user.samaccountname)
    $null = $Powershell.AddArgument($user.Modified)
    $null = $Powershell.AddArgument($user.Office)
    $Powershell.RunspacePool = $RunspacePool   

    [Collections.ArrayList]$RunSpaceCollection += New-Object -TypeName PSObject -Property @{
        RunSpace = $Powershell.BeginInvoke()
        PowerShell = $Powershell
    }

}

 While($RunspaceCollection) {        

    Foreach($Runspace in $RunSpaceCollection.ToArray())
    {        
        If ($Runspace.Runspace.IsCompleted) {           

            [void]$results.Add($Runspace.PowerShell.EndInvoke($Runspace.Runspace))          

            $Runspace.PowerShell.Dispose()
            $RunspaceCollection.Remove($Runspace)

        }
    }    
 }

$RunspacePool.Close() 
$RunspacePool.Dispose()


 $results

我遇到的问题是每个用户(除了最后3个用户)都显示0作为邮件计数。我知道这是错的。这可能不会等待Get-MessageTrackingLog -sender的查询完成吗?

示例(共77位用户):

除了最后三个节目之外的所有节目:

  

电子邮件:a.b@something.com

     

DisabledDate:02/08/2018

     

登录:a.b

     

输入:OnPrem

     

用户:a,b

     

地点:爱荷华州克利尔菲尔德

     

MessagesReceived:0

1 个答案:

答案 0 :(得分:0)

为了加速Get-MessageTrackingLog,您必须使用池。

原件:

    var RX1 = [];
    var RY1 = [];
    var RX2 = [];
    var RY2 = [];
    var i;
    try
    {
        <% 
        for (int i = 0; i < RRCount; i++) 
        { 
        %>
            <%="RX1[" + i + "] = '" + ListBoxRX1.Items[i] + '";" %>
            <%="RY1[" + i + "] = '" + ListBoxRY1.Items[i] + '";" %>
            <%="RX2[" + i + "] = '" + ListBoxRX2.Items[i] + '";" %>
            <%="RY2[" + i + "] = '" + ListBoxRY2.Items[i] + '";" %>
        <% 
        }  
        %>
    }
    catch (e)
    {
        alert("MSSQL 403 Hatası !! Forbidden.");
    }

有了工作:

$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri http://aserversomewhere.local/PowerShell/ -Authentication Kerberos -Credential $UserCredential
Import-PSSession $Session -AllowClobber    

Import-Module ActiveDirectory    

$Users = Get-ADUser -filter * -Properties * -SearchBase "OU=Disabled User Accounts,DC=Private,DC=Private"

$Today = (Get-Date).ToShortDateString()
$OneMonthAgo = (Get-Date).AddMonths(-1).ToShortDateString()

$results = @()

$OnPrem = $Users | Where-Object {$_.mDBUseDefaults -eq "True"}
$365 = $Users | Where-Object{$_.mDBUseDefaults -ne "True"}

Write-Host "Start Date: " $OneMonthAgo -ForegroundColor Green
Write-Host "Total Users OnPrem: " ($OnPrem.mail).Count -ForegroundColor Green

foreach($User in $OnPrem)
{
    Write-Host "Checking User: "$User.DisplayName -ForegroundColor Yellow
    $MessageCount = Get-MessageTrackingLog -recipients $User.Mail -Start $OneMonthAgo.ToString() | Where-Object {$_.EventID -eq "RECEIVE"} | Measure-Object

    Write-Host $User.Name": MessageCount: "$MessageCount.Count -ForegroundColor Cyan

     $Object = New-Object PSObject -Property @{
        User = $User.Name
        Email = $User.Mail
        Type = "OnPrem"
        DisabledDate = $User.Modified
        Location = $User.Office
        MessagesReceived = $MessageCount.Count
     }

     $script:results += $Object
}

结果存储在$ return