简体   繁体   English

Powershell加快Get-MessageTrackingLog

[英]Powershell Speed Up Get-MessageTrackingLog

Currently I am trying to get an output of all disabled users and their message counts in exchange. 目前,我正在尝试获取所有禁用用户及其消息计数的输出以作为交换。 This is easy enough through a foreach loop: 通过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
    }

The issue is this takes several hours to complete because it is being ran one user at a time. 问题是这需要几个小时才能完成,因为它一次只能运行一个用户。 My Goal is to run multiple inquiries at a time either through jobs or in parallel. 我的目标是一次通过作业或并行运行多个查询。 This needs to be ran in blocks of 10 due to the policy restrictions on the exchange server. 由于交换服务器上的策略限制,此操作必须以10块为单位运行。

Edit (more information on why): 编辑(有关原因的更多信息):

The reason to find the message counts of the users is, they are disabled and sitting an a disabled OU. 查找用户的邮件计数的原因是,他们被禁用并坐在一个禁用的OU中。 The reason for this is their mail is fw to another recipient. 原因是他们的邮件被转发给另一个收件人。 Or, their mailbox has been delegated. 或者,他们的邮箱已被委派。 This is intended for house keeping. 这是用于家政服务。 The results of this search will be filtered by MessageCount = 0. Then it will either be reported/saved as csv/users removed. 此搜索的结果将由MessageCount = 0过滤。然后将其报告/保存为csv /用户删除。

Disclosure: I am very ignorant on running jobs or running in parallel within powershell. 披露:我非常不了解运行作业或在Powershell中并行运行。 And, my google-foo seems to be broken. 而且,我的google-foo似乎已损坏。 Any guidance or help with this would be very appreciated. 任何指导或对此的帮助将不胜感激。

Version info: 版本信息:

Name             : Windows PowerShell ISE Host
Version          : 5.1.15063.966

UPDATE: 更新:

After Following Shawn's guidance, I was able to successfully speed up these requests quite significantly. 在遵循Shawn的指导之后,我能够成功地大大加快这些请求的速度。

Updated code: 更新的代码:

$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

The issue I am having is every user ( except the last 3 users ) are showing 0 as the message count. 我遇到的问题是每个用户( 最后3个用户除外 )都显示0作为消息计数。 I know this wrong. 我知道这是错的。 Could this somehow not be waiting for the query of Get-MessageTrackingLog -sender to finish? 难道这不应该等待Get-MessageTrackingLog -sender的查询完成吗?

Example (77 Users total): 示例(总共77个用户):

All but the last three show: 除最后三个节目外,所有节目:

Email : ab@something.com 电邮:ab@something.com

DisabledDate : 02/08/2018 禁用日期:02/08/2018

Login : ab 登录:ab

Type : OnPrem 类型:OnPrem

User : a, b 用户:a,b

Location : Clearfield, IA 位置:爱荷华州Clearfield

MessagesReceived : 0 已接收消息:0

In order to speedup Get-MessageTrackingLog, you have to use pools. 为了加速Get-MessageTrackingLog,您必须使用池。

Original: 原版的:

$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
}

With Jobs: 有工作:

$MaxThread = 10
$RunspacePool = [runspacefactory]::CreateRunspacePool(
    [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
)
[void]$RunspacePool.SetMaxRunspaces($MaxThread)
$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


$OnPremScriptblock = {
    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://aserversomewhere.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


}

$jobs = New-Object System.Collections.ArrayList
foreach ($user in $OnPrem){

    $PowerShell = [PowerShell]::Create()

    $null = $PowerShell.AddScript($OnPremScriptblock)
    $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

    [void]$jobs.Add((
    [pscustomobject]@{
        PowerShell = $PowerShell
        Handle = $PowerShell.BeginInvoke()
    }
    ))
}

While($jobs.handle.IsCompleted -eq $false){
    Write-Host "." -NoNewline
    Start-Sleep -Milliseconds 100
}

$return = $jobs | foreach{
    $_.PowerShell.EndInvoke($_.Handle)
    $_.PowerShell.Dispose()
}
$jobs.Clear()
$return

The results are stored in $return 结果存储在$ return中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 具有Get-MessageTrackingLog的Powershell(Exchange 2007) - Powershell with Get-MessageTrackingLog (Exchange 2007) 术语“ Get-MessageTrackingLog”未被识别为cmdlet的名称 - The term 'Get-MessageTrackingLog' is not recognized as the name of a cmdlet 通过包括MB转换在内的新功能简化Get-Messagetrackinglog - Simplify Get-Messagetrackinglog with a new function including MB Conversion 时间段的powershell参数,即Get-MessageTrackingLog -Server Mailbox01-开始“ 03/13/2015 09:00:00”-结束“ 03/15/2015 17:00:00” - powershell parameter of time period, i.e. Get-MessageTrackingLog -Server Mailbox01 -Start “03/13/2015 09:00:00” -End “03/15/2015 17:00:00” 无法使用 Get-MessageTrackingLog 作为 Sender@domain.com.CSV 导出外部电子邮件收件人列表? - Unable to export list of external email recipient using Get-MessageTrackingLog as Sender@domain.com.CSV? 加快“获取计数器” PowerShell cmdlet的速度 - Speed up 'Get-Counter' PowerShell cmdlet 如何加快 Powershell 中的 Get-ChildItem - How to speed up Get-ChildItem in Powershell Powershell | 加快在 Powershell 作业中运行 Get-ADUser - Powershell | Speed up Running Get-ADUser in Powershell jobs 使用PowerShell加速卸载 - Speed up uninstallation with PowerShell 加快Powershell脚本的速度 - Speed Powershell Script Up
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM