用来搜索不正确的 msExchMasterAccountSid 状态的示例脚本
上一次修改主题: 2005-10-12
以下脚本示例说明了搜索 Active Directory® 目录服务以查找 msExchMasterAccountSid 状态不正确的 Microsoft® Exchange Server 邮箱帐户的方法。它将搜索启用了 Exchange 邮箱的启用的和禁用的 Active Directory 帐户。此脚本还会从启用的 Active Directory 帐户中删除“关联的外部帐户”权限,这同时会清除 msExchMasterAccountSid;还会为禁用的帐户设置“关联的外部帐户”权限,这同时会设置 msExchMasterAccountSid。如果已启用邮箱的禁用的 Active Directory 帐户没有“关联的外部帐户”权限,则“关联的外部帐户”和 msExchMasterAccountSid 将设置为已知的自身安全标识符 (SID)。对发现的问题和所做的更改进行记录的日志文件名为 NoMAS_VBS.log。
' Begin script
Option Explicit
const LOGFILE = "NoMAS_VBS.log"
' Do not change anything below here unless you really know what you are doing.
const ACCESS_ALLOWED = &h0
const FULL_MAILBOX_ACCESS = &h1
const SEND_AS = &h2
const CONTAINER_INHERIT_ACE = &h2
const ASSOCIATED_EXTERNAL = &h4
const READ_PERMISSIONS = &h20000
Dim oConnection
Dim oRecordSet
Dim oRecordSet2
Dim oCommand
Dim strQuery
Dim strDomainNC
Dim oRootDSE
Dim i
Dim FSO
Set FSO = CreateObject("Scripting.FileSystemObject")
Dim TextStream
Set TextStream = FSO.OpenTextFile(LOGFILE, 8, TRUE)
TextStream.WriteLine("****************************************************************************")
TextStream.WriteLine("NoMAS.vbs, v0.2005.1.20, Microsoft Product Support Services")
TextStream.WriteLine("Started logging " + Cstr(Date()) + ", " + Cstr(Time()))
TextStream.WriteLine("****************************************************************************")
Dim oAce
Set oAce = CreateObject("AccessControlEntry")
oAce.Trustee = "NT AUTHORITY\SELF"
oAce.AccessMask = (FULL_MAILBOX_ACCESS + SEND_AS + ASSOCIATED_EXTERNAL + READ_PERMISSIONS)
oAce.AceFlags = CONTAINER_INHERIT_ACE
oAce.AceType = ACCESS_ALLOWED
set oRootDSE = GetObject("LDAP://RootDSE")
strDomainNC = oRootDSE.Get("defaultNamingContext")
set oRootDSE = Nothing
Set oConnection = CreateObject("ADODB.Connection")
oConnection.Provider = "ADsDSOObject"
oConnection.Open "Active Directory Provider"
Set oCommand = CreateObject("ADODB.Command")
Set oCommand.ActiveConnection = oConnection
Dim strDomainQuery
strDomainQuery = "<LDAP://cn=System," + strDomainNC + ">;(objectCategory=trustedDomain);trustPartner;onelevel"
oCommand.CommandText = strDomainQuery
Set oRecordSet = oCommand.Execute
If oRecordSet.Eof Then
TextStream.WriteLine("Didn't find any trusts, assuming single domain...")
PerDomain(strDomainNC)
Else
While Not oRecordSet.Eof
strDomainNC = oRecordSet.Fields(0)
PerDomain(strDomainNC)
oRecordSet.MoveNext
Wend
End If
'Clean up
oRecordSet.Close()
oRecordSet2.Close()
oConnection.Close()
TextStream.WriteLine("Finished at " + Cstr(Date()) + ", " + Cstr(Time()))
TextStream.WriteBlankLines(1)
TextStream.Close()
Set oRecordSet = Nothing
Set oRecordSet2 = Nothing
Set oConnection = Nothing
Sub PerDomain(strDomainNC)
Dim strDisabledQuery
strDisabledQuery = "<LDAP://"&strDomainNC&">;(&(objectCategory=user)(userAccountControl:1.2.840.113556.1.4.803:=2)(!(msExchMasterAccountSid=*))(msExchHomeServerName=*)(homeMDB=*));AdsPath;subTree"
oCommand.CommandText = strDisabledQuery
oCommand.Properties("Page Size") = 100
Set oRecordSet2 = oCommand.Execute
if oRecordSet2.Eof then
TextStream.WriteLine("No broken disabled users were found.")
Else
i = 1
While Not oRecordSet2.Eof
Dim oUser
Set oUser = GetObject(oRecordSet2.Fields("AdsPath").Value)
TextStream.WriteLine("Disabled user " + vbTab + oRecordSet2.Fields("AdsPath").Value + vbTab + " is missing msExchMasterAccountSid")
Dim mailboxSD
On Error Resume Next
Set mailboxSD = oUser.MailboxRights
If (Err.Number <> 0) Then
TextStream.WriteLine("Failed to get MailboxRights, error 0x" + CStr(Hex(Err.Number)) + " : " + Err.Description)
Err.Clear()
End If
Dim oDACL
Set oDACL = mailboxSD.DiscretionaryAcl
Dim bFoundMASInSD
bFoundMASInSD = FALSE
Dim ace
for each ace in oDACL
if ( ace.AccessMask And ASSOCIATED_EXTERNAL ) then
bFoundMASInSD = TRUE
end if
next
if (FALSE = bFoundMASInSD) then
oDACL.AddAce(oACE)
end if
ReorderDACL(oDACL)
mailboxSD.DiscretionaryAcl = oDACL
oUser.MailboxRights = Array(mailboxSD)
On Error Resume Next
oUser.SetInfo
If (Err.Number <> 0) Then
TextStream.WriteLine("Failed to SetInfo, error 0x" + CStr(hex(Err.Number)) + " : " + Err.Description)
Err.Clear()
End If
oDACL = Nothing
mailboxSD = Nothing
oUser = Nothing
i = i+1
On Error Goto 0
oRecordSet2.MoveNext
Wend
TextStream.WriteLine("No more broken disabled users were found.")
End if
'Clean up
oRecordSet2.Close()
Dim strEnabledQuery
strEnabledQuery = "<LDAP://"&strDomainNC&">;(&(objectCategory=user)(!userAccountControl:1.2.840.113556.1.4.803:=2)((msExchMasterAccountSid=*))(msExchHomeServerName=*)(homeMDB=*));AdsPath;subTree"
oCommand.CommandText = strEnabledQuery
Set oRecordSet2 = oCommand.Execute
if oRecordSet2.Eof then
TextStream.WriteLine("No broken enabled users were found.")
Else
i = 1
' Iterate through the objects that match the filter
While Not oRecordSet2.Eof
Set oUser = GetObject(oRecordSet2.Fields("AdsPath").Value)
TextStream.WriteLine("Enabled user " + vbTab + oRecordSet2.Fields("AdsPath").Value + vbTab + " has msExchMasterAccountSid")
On Error Resume Next
Set mailboxSD = oUser.MailboxRights
If (Err.Number <> 0) Then
TextStream.WriteLine("Failed to get MailboxRights, error 0x" + CStr(hex(Err.Number)) + " : " + Err.Description)
Err.Clear()
End If
Set oDACL = mailboxSD.DiscretionaryAcl
for each ace in oDACL
if ((ace.AccessMask And ASSOCIATED_EXTERNAL) = ASSOCIATED_EXTERNAL) then
ace.AccessMask = ace.AccessMask And Not ASSOCIATED_EXTERNAL
end if
next
ReorderDACL(oDACL)
mailboxSD.DiscretionaryAcl = oDACL
oUser.MailboxRights = Array(mailboxSD)
On Error Resume Next
oUser.SetInfo
If (Err.Number <> 0) Then
TextStream.WriteLine("Failed to SetInfo, error 0x" + CStr(hex(Err.Number)) + " : " + Err.Description)
Err.Clear()
End If
oDACL = Nothing
mailboxSD = Nothing
oUser = Nothing
i = i+1
On Error Goto 0
oRecordSet2.MoveNext
Wend
TextStream.WriteLine("No more broken enabled users were found.")
End If
end Sub
Sub ReorderDACL(dacl)
Set newdacl = CreateObject("AccessControlList")
Set ImpDenyDacl = CreateObject("AccessControlList")
Set InheritedDacl = CreateObject("AccessControlList")
Set ImpAllowDacl = CreateObject("AccessControlList")
Set InhAllowDacl = CreateObject("AccessControlList")
Set ImpDenyObjectDacl = CreateObject("AccessControlList")
Set ImpAllowObjectDacl = CreateObject("AccessControlList")
For Each ace In dacl
If ((ace.AceFlags And ADS_ACEFLAG_INHERITED_ACE) = ADS_ACEFLAG_INHERITED_ACE) Then
InheritedDacl.AddAce ace
Else
Select Case ace.AceType
Case ADS_ACETYPE_ACCESS_ALLOWED
ImpAllowDacl.AddAce ace
Case ADS_ACETYPE_ACCESS_DENIED
ImpDenyDacl.AddAce ace
Case ADS_ACETYPE_ACCESS_ALLOWED_OBJECT
ImpAllowObjectDacl.AddAce ace
Case ADS_ACETYPE_ACCESS_DENIED_OBJECT
ImpDenyObjectDacl.AddAce ace
Case Else
End Select
End If
Next
For Each ace In ImpDenyDacl
newdacl.AddAce ace
Next
For Each ace In ImpDenyObjectDacl
newdacl.AddAce ace
Next
For Each ace In ImpAllowDacl
newdacl.AddAce ace
Next
For Each ace In impAllowObjectDacl
newdacl.AddAce ace
Next
For Each ace In InheritedDacl
newdacl.AddAce ace
Next
Set InheritedDacl = Nothing
Set ImpAllowDacl = Nothing
Set ImpDenyObjectDacl = Nothing
Set ImpDenyDacl = Nothing
newdacl.AclRevision = dacl.AclRevision
Set dacl = nothing
Set dacl = newdacl
end Sub
'End Script
有关详细信息
有关 msExchMasterAccountSid 属性的详细信息,请参阅检测并纠正 msExchMasterAccountSid 问题。