Powershell 加速 Get-MessageTrackingLog
Powershell Speed Up Get-MessageTrackingLog
目前我正在尝试获取所有禁用用户的输出以及他们的消息计数作为交换。通过 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"}
5 = $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
}
问题是这需要几个小时才能完成,因为它是一次 运行 一个用户。我的目标是通过作业或并行 运行 一次进行多个查询。由于 exchange 服务器的政策限制,这需要 运行 以 10 个为单位。
编辑(关于原因的更多信息):
The reason to find the message counts of the users is, they are
disabled and sitting an a disabled 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.
披露:我对 运行ning 作业或 运行ning 在 powershell 中的并行工作非常无知运行t。而且,我的 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"}
5 = $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 个用户):
除最后三个节目外的所有节目:
Email : a.b@something.com
DisabledDate : 02/08/2018
Login : a.b
Type : OnPrem
User : a, b
Location : Clearfield, IA
MessagesReceived : 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"}
5 = $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"}
5 = $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
目前我正在尝试获取所有禁用用户的输出以及他们的消息计数作为交换。通过 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"}
5 = $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
}
问题是这需要几个小时才能完成,因为它是一次 运行 一个用户。我的目标是通过作业或并行 运行 一次进行多个查询。由于 exchange 服务器的政策限制,这需要 运行 以 10 个为单位。
编辑(关于原因的更多信息):
The reason to find the message counts of the users is, they are disabled and sitting an a disabled 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.
披露:我对 运行ning 作业或 运行ning 在 powershell 中的并行工作非常无知运行t。而且,我的 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"}
5 = $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 个用户):
除最后三个节目外的所有节目:
Email : a.b@something.com
DisabledDate : 02/08/2018
Login : a.b
Type : OnPrem
User : a, b
Location : Clearfield, IA
MessagesReceived : 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"}
5 = $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"}
5 = $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