添加检查 CSV 中是不是已存在 ExternalEmailAddress 以及它是不是不执行任何操作

Posted

技术标签:

【中文标题】添加检查 CSV 中是不是已存在 ExternalEmailAddress 以及它是不是不执行任何操作【英文标题】:Add a Check if ExternalEmailAddress already exists in the CSV and if it does do nothing添加检查 CSV 中是否已存在 ExternalEmailAddress 以及它是否不执行任何操作 【发布时间】:2021-11-08 22:47:10 【问题描述】:

我该怎么做?有任何想法吗?如果 ExternalEmailAddress 已经存在,我只想确保我的脚本不会尝试创建新的 mailContact。

If (Test-Path $CSVFileName) 

    #Import the CSV file
    $csvfile = Import-CSV $CSVFileName
        
    #Loop through CSV file
    foreach ($line in $csvfile) 

        try 
            #Create the mail contact    
            New-MailContact -domaincontroller $dc -Name $line.Name -ExternalEmailAddress $line.ExternalEmailAddress  -OrganizationalUnit $OU -ErrorAction STOP
            Set-Contact -domaincontroller $dc -Identity $line.Name -Department $line.Department -Title "Sales Team" -StreetAddress $line.StreetAddress -City $line.City -StateOrProvince $line.StateOrProvince -PostalCode $line.PostalCode -Office $line.Office -CountryOrRegion $line.CountryOrRegion
            "$($line.Name) was created successfully." | Out-File $logfile -Append
        
        catch 
            
            $message = "A problem occured trying to create the $($line.Name) contact"
            $message | Out-File $logfile -Append
            Write-Warning $message
            Write-Warning $_.Exception.Message
            $_.Exception.Message | Out-File $logfile -Append
        

    

【问题讨论】:

【参考方案1】:

我没有发现您的方法存在任何根本问题。如果您担心对其进行测试,请创建 CSV 文件的截断版本,以查看脚本如何与某些测试帐户或其他类似的反应。您还可以使用NewSet 命令上的-WhatIf 参数来检查哪些对象会受到影响,但无需进行更改。

我必须假设 $OU 变量是在别处定义的。我建议的唯一另一件事是使用 splatting 使其更具可读性。这可能看起来像这样:

$NewParams = @
   DomainController     = $dc
   OrganizationalUnit   = $OU
   ErrorAction          = 'Stop'


$SetParams = @
   DomainController = $dc      
   Title            = 'Sales Team'      


If (Test-Path $CSVFileName) 

   #Import the CSV file
   $csvfile = Import-CSV $CSVFileName
   
   # Adjust splatting hash tables per incoming line:
   $NewParams['Name']                 = $line.Name
   $NewParams['ExternalEmailAddress'] = $line.ExternalEmailAddress

   # Adjust splatting hash for the set command:
   $SetParams['Identity']             = $line.Name
   $SetParams['Department']           = $line.Department
   $SetParams['StreetAddress']        = $line.StreetAddress
   $SetParams['City']                 = $line.City
   $SetParams['StateOrProvince']      = $line.StateOrProvince
   $SetParams['PostalCode']           = $line.PostalCode
   $SetParams['Office']               = $line.Office
   $SetParams['CountryOrRegion']      = $line.CountryOrRegion

   #Loop through CSV file
   foreach ($line in $csvfile) 

       try 
           #Create the mail contact    
           New-MailContact @NewParams
           Set-Contact @SetParams
           "$($line.Name) was created successfully." | Out-File $logfile -Append
       
       catch 
           
           $message = "A problem occured trying to create the $($line.Name) contact"
           $message | Out-File $logfile -Append
           Write-Warning $message
           Write-Warning $_.Exception.Message
           $_.Exception.Message | Out-File $logfile -Append
       

   

此示例设置了 2 个具有常量值的哈希表。然后在循环内,它将添加和/或更改散列中的变量参数,每行输入。他们只是将这些哈希值作为New-MailContactSet-Contact 命令的参数引用。

Exchange 命令行管理程序不允许您复制 SMTP 地址。如果您尝试这样做,将返回如下错误:

The proxy address "SMTP:Example@Example.com" is already being used by the proxy addresses or LegacyExchangeDN of "local.domian/Users/OtheMailEnabledObject". Please choose another proxy address.

但是,如果您想完全防止错误和/或防止将这些特定类型的错误写入日志,您可以做一些事情。

从代码的角度来看,最简单的做法是使用 Get-Recipient 命令添加一个 If 块。

#...
    #Loop through CSV file
    foreach ($line in $csvfile) 
        If( !(Get-Recipient $line.ExternalEmailAddress) ) 
            try 
                #Create the mail contact    
                New-MailContact @NewParams
                Set-Contact @SetParams
                "$($line.Name) was created successfully." | Out-File $logfile -Append
            
            catch             
                $message = "A problem occured trying to create the $($line.Name) contact"
                $message | Out-File $logfile -Append
                Write-Warning $message
                Write-Warning $_.Exception.Message
                $_.Exception.Message | Out-File $logfile -Append
            
        
    

注意:Get-RecipientGet-MailContact 更彻底。

另一种方法可能是简单地以不同方式处理这些特定错误。

#...
    #Loop through CSV file
    foreach ($line in $csvfile) 
        try 
            #Create the mail contact    
            New-MailContact @NewParams
            Set-Contact @SetParams
            "$($line.Name) was created successfully." | Out-File $logfile -Append
        
        catch 
            If( $Error[0].CategoryInfo.Reason -ne 'ProxyAddressExistsException' )
                $message = "A problem occured trying to create the $($line.Name) contact"
                $message | Out-File $logfile -Append
                Write-Warning $message
                Write-Warning $_.Exception.Message
                $_.Exception.Message | Out-File $logfile -Append
            
        
    

因此,在这种情况下,您只会在错误不是重复代理地址时进行记录。您当然可以根据需要创建其他逻辑。

如果您有大量联系人来创建这两种方法可能会相当慢。这是因为他们会执行很多他们不需要的命令。对于后一种方法,性能损失与实际发生的重复错误的数量有关。对于前者,每次循环迭代都会受到影响,因为无论New-MailContact 命令是否成功,您总是在检查。

所以最后一种方法是创建一个现有代理地址列表,您可以在尝试创建新联系人之前对其进行检查。

编译所有 SMTP 代理地址的列表:

$ExistingAddresses = 
Get-Recipient ResultSize Unlimited | 
Select-Object -ExpandProperty EmailAddresses | 
Where-Object$_.PrefixString -eq 'SMTP' |
Select-Object -ExpandProperty SmtpAddress

但是,Get-Recipient 可能在对大型查询返回的大型集合进行分页时遇到问题。取决于你的环境。如果您确实遇到问题,您可以使用 AD cmdlet 的替代方法,在任何情况下都会更快。

$ExistingAddresses =
Get-ADObject -Filter "mailnickname -like '*'" -Properties 'ProxyAddresses' |
 ForEach-Object 
    ForEach($ProxyAddress in $_.ProxyAddresses)
    
        If( $ProxyAddress -match "^smtp" ) 
            $ProxyAddress.Split(':')[1]
        
    

一旦您填充了$ExistingAddresses,您就可以更改循环以首先检查列表:

foreach ($line in $csvfile) 
    If( $line.ExternalEmailAddress -notin $ExistingAddresses ) 
        try 
            #Create the mail contact    
            New-MailContact @NewParams
            Set-Contact @SetParams
            "$($line.Name) was created successfully." | Out-File $logfile -Append
        
        catch 
            $message = "A problem occured trying to create the $($line.Name) contact"
            $message | Out-File $logfile -Append
            Write-Warning $message
            Write-Warning $_.Exception.Message
            $_.Exception.Message | Out-File $logfile -Append
        
    

同样,如果需要,您可以构建额外的逻辑。例如,Else... 如果您想报告发现重复等...

基于额外的 cmets。如果您想对那些已经存在的联系人运行 set 命令。这里有 1 个例子:

#Loop through CSV file
foreach ($line in $csvfile) 
    If( !(Get-Recipient $line.ExternalEmailAddress) ) 
        try 
            #Create the mail contact    
            New-MailContact @NewParams
            "$($line.Name) was created successfully." | Out-File $logfile -Append
        
        catch             
            $message = "A problem occured trying to create the $($line.Name) contact"
            $message | Out-File $logfile -Append
            Write-Warning $message
            Write-Warning $_.Exception.Message
            $_.Exception.Message | Out-File $logfile -Append
        
    
    # The contact either already exists or was just created, so long as you
    # Use the same domain controller go ahead and perform the Set...
    Set-Contact @SetParams

同样,有上千种方法可以安排这样的事情。而且,所有上述方法都可能被修改以满足新的要求。但是,这不会告诉您哪些属性得到更新。如果你想要那种属性级别的比较,我们还得写更多的代码。

【讨论】:

Steven,我如何在上面的代码中添加 If 语句,以检查 ExternalEmailAddress 是否已经存在? 在我看来,您不需要这样做。 ESM 不允许您复制地址,并且它生成的错误将被捕获。我认为防止错误总是比依赖捕获它更明智,所以我将更新一些示例。 已更新以涵盖您需要的一切。如果你觉得舒服,请接受答案。无论哪种方式,如果您有任何其他问题,请告诉我。 您的示例可以解决问题,但是如果我想检查联系人是否已被修改怎么办? 如果已修改,请更新该字段。

以上是关于添加检查 CSV 中是不是已存在 ExternalEmailAddress 以及它是不是不执行任何操作的主要内容,如果未能解决你的问题,请参考以下文章

检查 SQL Server 登录是不是已存在

在我添加错误消息以检查 CapNum 是不是为空或已存在于数据库中之前,我的代码一直在工作

检查列是不是已存在,如果不存在,则在 sqlite 中更改表

检查 Flutter Firestore 中是不是已存在字段

如何使用BufferedReader检查csv中是不是存在多个条件字符串?

如何检查对象是不是已存在于列表中