[Quest ActiveRoles Management Shell for Active Directory] QADProxyAddress命令相关的bug。

时间:2021-08-31 00:34:45

This post also be published in English: http://www.cnblogs.com/LarryAtCNBlog/p/3923882.html

称之为bug真得好吗?不过想想也没错呀,因为QADProxyAddress相关的命令基本上都不能用了都。

事情大概是这样,

我们公司因为业务以前有很多smtp address,现在大统一要清除AD里面一些SMTP domain,公司用的是Quest ARServer管理权限,因此实际上我本人虽然身为管理员,其实权限对AD本身就是一个普通user,所有的操作都必须通过Quest console来实现,很高兴的是Quest公司出品了powershell版的console,让我可以通过命令行来做batch job。

当然,这次的smtp domain清理大行动又落在了我身上,咦~~我为什么要说又~

打开ISE,开始码代码,其实写脚本,或者说编程,核心干活的代码绝不能排在第一位,logging至少是与其并列,log是当事情干完之后一旦出问题,唯一能够拯救世界的东西。

扯远了,代码并不复杂,根据project team每次所给我的batch job,我只需要读该文本,取出user名字,用Get-QADUser的方法从AD里把该user抓到,然后判断其ProxyAddresses属性有没有匹配到目标domain就好了,没有匹配到的话,则跳过该user,匹配到的话就提取出匹配项,然后执行Remove-QADProxyAddress命令就行了。这么简单想想都有点小激动呢。

代码写一半,打算用自己的账号测试一下Remove-QADProxyAddress这个cmdlet的用法及错误返回。

哟,果然what the hell了,心凉一截,这错儿是怎么事儿?感觉要被坑呢?

[Quest ActiveRoles Management Shell for Active Directory] QADProxyAddress命令相关的bug。

明明通过console UI界面操作,不用每一个type的address都要有一个primary才对呀,可以直接做才对呀,果断搜了一搜,发现如下某人给Dell (没错Quest被Dell收购啦) report了同样的问题,话说Dell没人管是怎么事儿?这都快2年了!

http://en.community.dell.com/techcenter/powergui/f/4834/t/19574623.aspx

我公司用的还是ARS 6.7.0, ARS powershell module的相应版本是1.5.1,最新的是ARS 6.8.0,不清楚该bug修复了没有,无论怎么样服务器端要有对应的版本,不然光下载个最近的客户端也连接不上服务器,会被拒绝。

怎么办呢?其实问题很简单,QADProxyAddress相关的几个cmdlet在运行的时候都会检查每个proxy address的type,每种type都要有一个primary,没设置的话是不行的。而且,就算为了修正该问题,想对每个type都设一个primary,也是不行。困为如果同时存在两种以上的type没有primary,在纠正其中一个type的时候,会报另外的type没有primary的错误,比如同时有sip和x500两个type没有primary,在运行如下命令纠正sip的时候,就会报x500没有primary,称为被坑不为过呀

[Quest ActiveRoles Management Shell for Active Directory] QADProxyAddress命令相关的bug。

怎么办怎么办,都不要脸地答应人project manager了,现在说做不到不是要丢死人了吗?

AD账号本身又没权限,通过ARS又有该bug,最后想到exchange 2010,我的账号是有修改mailbox的权限的,看看mailbox上有没有同样的属性先。

于是果断登上exchange,打开powershell,Get-Mailbox | fl * 一瞅果断有同样的属性。这就是传说中的救命稻草,赶紧把Y按地上。用Set-Mailbox果然能无视primary修改proxy address,于是脚本改成用exchange powershell执行。于是有了下面的脚本,会读取Process.list.txt里的user list,然后从user的address找smtp地址的匹配,找到的话就删掉,没有找到就跳过。

. 'D:\Program Files\Microsoft\Exchange Server\v14\bin\RemoteExchange.ps1'
Connect-ExchangeServer -auto

$users = cat '.\Process.list.txt' | ?{$_} | %{$_.Trim()}
$addressToRemove = 'regular expression'

$Date = Get-Date
$strDate = $Date.ToString('yyyy-MM-dd')
$strLogFile = "$strDate.log"

function Add-Log{
    PARAM(
        [String]$Path,
        [String]$Value,
        [String]$Type
    )
    $Type = $Type.ToUpper()
    Write-Host "$((Get-Date).ToString('[HH:mm:ss] '))[$Type] $Value"
    if($Path){
        Add-Content -Path $Path -Value "$((Get-Date).ToString('[HH:mm:ss] '))[$Type] $Value"
    }
}

$Total = $users.Count
Add-Log -Path $strLogFile -Value "Users count: [$Total]" -Type Info

$users | %{$Processed = 0}{
    $Processed++
    Add-Log -Path $strLogFile -Value "Processing: [$Processed/$Total][$_]" -Type Info
    $mailbox = $null
    $mailbox = Get-Mailbox -Identity $_
    if(!$mailbox)
    {
        Add-Log -Path $strLogFile -Value "Failed to get user's mailbox" -Type Error
        return
    }
    Add-Log -Path $strLogFile -Value "All 1: [$(($mailbox.EmailAddresses | %{$_.ProxyAddressString}) -join '], [')]" -Type Info
    $addresses = $mailbox.EmailAddresses | ?{$_.Prefix.DisplayName -eq 'SMTP'} | %{$_.SmtpAddress}
    $addressMatch = $null
    $addressMatch = $addresses -imatch $addressToRemove
    if($addressMatch)
    {
        Add-Log -Path $strLogFile -Value "Matched: [$($addressMatch -join '], [')]" -Type Info
        $mailbox | Set-Mailbox -EmailAddresses @{remove=$addressMatch} -ErrorAction:SilentlyContinue
        if(!$?)
        {
            Add-Log -Path $strLogFile -Value 'Remove address failed, cause:' -Type Error
            Add-Log -Path $strLogFile -Value $Error[0] -Type Error
        }
        $mailbox = Get-Mailbox -Identity $_
        Add-Log -Path $strLogFile -Value "All 2: [$(($mailbox.EmailAddresses | %{$_.ProxyAddressString}) -join '], [')]" -Type Info
    }
    else
    {
        Add-Log -Path $strLogFile -Value "No SMTP address matched, move to next." -Type Info
        return
    }
}