1

目前,我正在尝试获取所有禁用用户的输出及其消息计数作为交换。这很容易通过 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 中。这样做的原因是他们的邮件转发给另一个收件人。或者,他们的邮箱已被委派。这是用于管家的。此搜索的结果将由 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 个用户):

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

邮箱:ab@something.com

禁用日期:02/08/2018

登录:ab

类型 : OnPrem

用户:a,b

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

收到的消息:0

4

1 回答 1

0

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

原来的:

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

与工作:

$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

结果存储在 $return

于 2018-03-26T21:13:02.773 回答