为什么此powershell脚本没有删除所有已回复的Outlook电子邮件?

为什么此powershell脚本没有删除所有已回复的Outlook电子邮件?,powershell,email,outlook,mapi,new-object,Powershell,Email,Outlook,Mapi,New Object,我编写此脚本是为了删除任何已由其他技术人员回复的Exchange隔离电子邮件 它“有效”,但它只是删除它发现的第一组已回复的电子邮件,原始邮件加上回复 如果我再次运行脚本,它将删除下一个集,依此类推 我不明白为什么它不循环并删除所有回复的电子邮件,而不仅仅是第一封 #connect to outlooks $outlook = new-object -comobject “Outlook.Application” $mapi = $outlook.getnamespace(“mapi”) #c

我编写此脚本是为了删除任何已由其他技术人员回复的Exchange隔离电子邮件

它“有效”,但它只是删除它发现的第一组已回复的电子邮件,原始邮件加上回复

如果我再次运行脚本,它将删除下一个集,依此类推

我不明白为什么它不循环并删除所有回复的电子邮件,而不仅仅是第一封

#connect to outlooks
$outlook = new-object -comobject “Outlook.Application”
$mapi = $outlook.getnamespace(“mapi”)

#connect to outlook inbox
$inbox = $mapi.GetDefaultFolder(6)

#find the subfolder named Exchange Quarantined
$subfolder = $inbox.Folders | Where-Object {$_.Name -eq “Exchange Quarantined”}

#loop through emails and if someone already replied to the email then delete all emails with that users name in it
ForEach ($email in $subfolder.Items) {
    $subject = $email.Subject

    #Get the users name out of the subject line
    $user = $subject.Split("(")
    $name = $user[0] -replace ".*device that belongs to "
    $name = $name.Trim()
    Write-host $name
    if($subject -like "*RE: A device that belongs to*") {
        ForEach ($emailDelete in $subfolder.Items) {
            $subjectDelete = $emailDelete.Subject

            if($subjectDelete -like "*$name*") {
                Write-Host "Delete $subjectDelete"
                $emailDelete.Delete()
            }
        }
    }
}
当我第一次运行脚本时,文件夹中有五封电子邮件,三封原始隔离电子邮件和两封回复。下面是三次运行的输出,每次运行时它只删除找到的第一组回复

PS H:\> C:\Users\todd.welch\Downloads\Exchange Quarantined.ps1
Lan Fill
Adam Pac
Adam Pac
Delete A device that belongs to Adam Pac (adam.pac) has been quarantined. Exchange ActiveSync will be blocked until you take action.
Delete RE: A device that belongs to Adam Pac (adam.pac) has been quarantined. Exchange ActiveSync will be blocked until you take action.

PS H:\> C:\Users\todd.welch\Downloads\Exchange Quarantined.ps1
Lan Fill
Antonia Gonz
Antonia Gonz
Delete A device that belongs to Antonia Gonz (antonia.gonz) has been quarantined. Exchange ActiveSync will be blocked until you take action.
Delete RE: A device that belongs to Antonia Gonz (antonia.gonz) has been quarantined. Exchange ActiveSync will be blocked until you take action.

PS H:\> C:\Users\todd.welch\Downloads\Exchange Quarantined.ps1
Lan Fill

永远不要删除“foreach”循环中的集合项-您正在修改集合,这会导致代码跳过至少一些项。使用向下“for”循环(从Items.countdown到1)


也就是说,您永远不应该在自己的代码中明确匹配项目-使用
items.Find/FindNext
items.Restrict
。让商店供应商来做这项工作。

为什么要有第二个内部循环?这似乎不是必需的。如果你有一个主题匹配,你应该能够
$email.Delete()
no?因为它需要删除回复和原件,而且我无法知道它将处理电子邮件的顺序,所以我唯一能想到的方法是再次运行所有电子邮件,删除内部循环中带有该用户名的任何电子邮件。啊,好的。我明白了。我猜你在改变外部循环的成员,就像你在删除内部循环的成员一样。因此,外部循环可能会尝试访问您已删除的邮件。我认为您可能需要一次查询所有邮件,然后在单独的操作中删除。。。或者重新查询
$subfolder.Items
,以确保获得更新的列表Hey Matt,这是我认为的,但我认为使用单独的ForEach循环可以解决这个问题。我甚至尝试使用一个单独的$subfolder变量,但指针可能位于outlook连接的更高级别上的更高级别上。因此,也许我需要循环一次来创建一个RE:emails用户名数组,然后在一个单独的循环中循环以删除包含用户名的所有电子邮件。感谢您的回复,我进行了研究,但我只是没有理解您的意思。因此,我想这是您的意思,但我得到了错误$messages=$subfolder.Items($i=$messages.count;$i-ge 1;$i--){Write Host$i$subject=$messages[$i]。subject写入主机“subject:$subject”if($subject-like“RE:属于的设备”){$user=$subject.Split(“(”)$name=$user[0]-替换“$name=$name.Trim()的设备)$deleteMessage=$subfolder.Find(“[Subject]=”.*$name.*'),而($deleteMessage){$deleteMessage.Delete()}}}方法调用失败,因为[System.\u ComObject]不包含名为“Find”的方法。位于C:\Users\todd.welch\Downloads\Exchange quantinted.ps1:34字符:9+$deleteMessage=$子文件夹.Find(“[Subject]=”.$name.*')+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~,RuntimeException+FullyQualifiedErrorId:MethodNotFoundFind/FindNext/Restrict方法由Items对象(从MAPIFolder.Items返回)实现,而不是MAPIFolder-请参见是我看到我的错误我更改了$deleteMessage=$subfolder.Items.Find(“[Subject]=”.$name.*”),但$deleteMessage为空,找不到任何电子邮件。