如何更好地优化此O365 PowerShell脚本?

如何更好地优化此O365 PowerShell脚本?

问题描述:

该脚本打开到O365的连接,然后遍历所有查找可能是恶意的收件箱规则的邮箱。如何更好地优化此O365 PowerShell脚本?

在我们的12K邮箱组织中,该脚本需要运行24小时以上。

$CloudCredentials = import-clixml C:\tools\CloudCreds.xml 
Write-Host "Connecting To Exchange Online..." -foregroundcolor white 
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell ` 
        -Credential $CloudCredentials -Authentication Basic - 
AllowRedirection -WarningAction SilentlyContinue 
Import-PSSession $Session -Prefix Cloud -DisableNameChecking -AllowClobber | Out-Null 
Connect-MsolService -Credential $CloudCredentials 
Invoke-Command -Session (Get-PSSession | ?{$_.state -eq "Opened"}) -ScriptBlock {GEt-Mailbox -resultsize unlimited | Select-Object PrimarySMTPAddress,UserPrincipalName} 
foreach ($MB in $MBs) {  
    [email protected]() 
    $Rules += Get-CloudInboxRule -Mailbox $MB.UserPrincipalName -WarningAction SilentlyContinue 
    if ($Rules.Length -gt 0) { 
     foreach ($R in $Rules) { 
      if (($R.Name -eq "postmaster") -or 
       ($R.Name -eq ".net") -or 
       ($R.Name -eq ".com") -or 
       ($R.Name -eq ".org") -or 
       ($R.Name -eq ".") 
       ) 
      { 
      write-host $MB.UserPrincipalName 
      #Remove-CloudInboxRule -Mailbox $MB.UserPrincipalName -Id $R.Name -Confirm:$false 
      } 
     } 
    } 
} 

使用Get-InboxRule(这里更名为获取-CloudInboxRule)迭代似乎采取的时间最长。就目前而言,此代码每1000个邮箱需要大约1小时。这意味着对于我们的15K用户来说,这需要15个小时的时间来扫描......在垃圾邮件日志开始之前尝试查找恶意规则的时间很长。

p.s这是张贴在超级用户,但我意识到这是一个Powershell编程问题,不是一个真正的权力用户问题。

+1

您还没有考虑分割处理多个[后台作业(https://docs.microsoft.com/en-us/powershell/模块/ microsoft.powershell.core /开始工作?视图=的powershell-5.1)? – vonPryz

+1

嗨dragonspeed,优化工作解决方案的网站将[codereview](https://codereview.stackexchange.com/),但请避免跨站点帖子。 – bummi

+0

@vonPryz - 我只是试过,但最终得到了不同的结果:( 不知道如何发布我的修改版本的代码 – dragonspeed

你可能想看看Powershell Workflows的并行处理,我还没有使用这个规模,但它应该加快大或慢的ForEach循环。 当我必须连接或ping到大量计算机时,我通常会使用它。

示例代码

CLS 

### Worflows, Functions, etc. 

#Workflow 
workflow CheckMailBoxesForBadRules 
{  
    #Mailboxes 
    $MailBoxes = @(
     @{Name="Mailbox1"; [email protected]('rule1','rule2','rule3')} 
     @{Name="Mailbox2"; [email protected]('rule1','rule2')} 
     @{Name="Mailbox3"; [email protected]('rule1','rule3')} 
     @{Name="Mailbox4"; [email protected]('rule2','rule3')} 
     @{Name="Mailbox5"; [email protected]('rule1')} 
     @{Name="Mailbox6"; [email protected]('rule2')}   
     @{Name="Mailbox7"; [email protected]('rule3')} 
     @{Name="Mailbox8"; [email protected]()} 
     ) 


    ForEach -Parallel ($Mailbox in $MailBoxes) 
    {  
     $BadRules = @() 
     Foreach ($Rule in $Mailbox.Rules) 
     { 
      #logic 
       $BadRules += $Rule 
     } 

     If ($BadRules){ 
      "$($MailBox.Name) " + 
      "bad-rules: $($BadRules -join ", ")" 
     } 
    } 
} 

### Script Execution 

# Workflow Start 
CheckMailBoxesForBadRules 

输出

Mailbox7 bad-rules: rule3 
Mailbox6 bad-rules: rule2 
Mailbox5 bad-rules: rule1 
Mailbox4 bad-rules: rule2, rule3 
Mailbox3 bad-rules: rule1, rule3 
Mailbox2 bad-rules: rule1, rule2 
Mailbox1 bad-rules: rule1, rule2, rule3 
+0

我似乎“失去”了工作流中的Exchange会话,所以我的Get-InboxRule变为一个无效的命令 – dragonspeed

+0

这是一个简单的例子,工作流可以看起来像一个函数,但它们是不同的,我改变了代码以向你展示一种不同的方法,但是你是否可以使用它们是你必须自己测试的。 – SteloNLD