Thursday, August 16, 2012

A meeting update message or a meeting cancellation message from an Exchange 2003 user is not delivered to external attendee


It was brought to my attention that there is a random issue when a user cancels a meeting and some of the attendees are not notified via a cancellation. Upon digging further, the users that are not receiving these cancellation are found to be external users.
Conversation with the IT folks in these users' companies are that their messaging infrastructure is running on Lotus Notes and Exchange 2007.
The issue has been found to be that of the below and the procedures listed can be used to check if the issue is affecting your Exchange 2003 setup.
Issue
When sending meeting changes or cancellations to another mail server outside of your exchange 2003 organization messages get stuck in the queue and if the diagnostics logging of the MSExchangeTransport component is set to maximum, the following warning is logged:
Event Type: Warning
Event Source: MSExchangeTransport
Event Category: Exchange Store Driver
Event ID: 327
If an administrator tries to open the message in the Exchange System Manager console, the administrator may receive the following error message:Unable to open for delivery
To verify this is the issue follow these steps on the message that is stuck.
  1. Launch MFCMAPI and select OK. (MFCMAPI can be downloaded from  http://mfcmapi.codeplex.com/)
  2. Choose Session –> Logon –> Display Store Table
  3. Select the proflle used to open the mailbox
  4. In the returned items look for the row that has "Mailbox – <username>" and double click to open the row
  5. In the new "Mailbox – <username>" window expand the Root – Mailbox folder
  6. Expand the IPM_SUBTREE (or the mailbox) folder
  7. Open the calendar folder by double clicking on it.
  8. In the new "Calendar" window navigate to the appointment item (you can sort by Subject by clicking the Subject column)
  9. Right click the appointment item and choose "Display Recipient Table" from the menu
  10. In the recipients table scroll to the right until you can view the column named "PR_RECIPIENT_TRACKSTATUS"
  11. Note the number value for each recipient and this will indicate their tracking status on the item.
  12. If the value is 0 then it means that the tracking status is not available.
The solution
A hotfix is released by Microsoft to correct this issue as the KB below
http://support.microsoft.com/kb/938650



Wednesday, August 8, 2012

Token Size report for users

I was posed a question as to how can we tell what is the Token Size for each users in the environment.
Microsoft provides a tool for use to calculate 1 user (http://www.microsoft.com/en-us/download/details.aspx?id=1448). But this tool from what I know only allows calculation of the token size for the current logon user and if computation of token size for another user is needed, the user's credentials will have to be provided (Which is a challenging task).
With that I set out to create a vbs for this and the below is the output that I would like to share.
The computation formula is based on 


Following formula to determine whether it is necessary to modify the MaxTokenSize value or not
TokenSize = [12 X number of user rights] + [token overhead] + [40 X number of group memberships] + 8s
This formula uses the following values:
·         d:  The number of domain logical groups a user is a member of plus the number of universal groups outside the user’s account domain plus the number of groups represented in SID history.
·         s:  The number of security global groups that a user is a member of plus the number of universal groups in a user’s account domain.
·         User rights include rights such as “Log on locally” or “Access this Computer from the network”. The only user rights that are added to an access token are those user rights that are configured on the server that hosts a secured resource.  Most of the users are likely to have only two or three user rights on the Exchange server. Administrators may have dozens of user rights. Each user right requires 12 bytes to store it in the token.
·         Token overhead includes multiple fields such as the token source, expiration time, and impersonation information. For example, a typical domain user has no special access or restrictions; token overhead is likely to be between 400 and 500 bytes.
·         Estimated value for ticket overhead can vary depending on factors such as DNS domain name length, client name and other factors.
·         Each group membership adds the group SID to the token together with an additional 16 bytes for associated attributes and information. The maximum possible size for SID is 68 bytes.  Therefore, each security group to which a user belongs typically adds 44 bytes to the user’s token size.

*** Assumes that [12 X number of user rights] + [token overhead] = 1200

The script is as below. To user copy and save the file as vbs

'Start of VBS

Const ForReading = 1

Const ADS_SCOPE_SUBTREE = 2

TotalGroups=0
UniversalGroup=0
LocalGroup=0
GlobalGroup = 0
I = 2

' Clean up.
Set objGroupList = Nothing
Set objUser = Nothing

'_________________________________________________________________________________

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(INPUT_FILE_NAME, FOR_READING)
strSite = objFile.ReadAll
objFile.Close

' Create Excel Spreadsheet
Set app = CreateObject("Excel.Application")
Set wb = app.Workbooks.Add
wb.Activate
Set ws = wb.Sheets.Add

On Error Resume Next
app.Visible = True

ws.Cells(1,1).Value = "Display Name"
ws.Columns(1).ColumnWidth = 30
ws.cells(1,2).value = "SAMACCountName"
ws.columns(1,2).columnwidth = 30
'ws.Cells(1,3).Value = "Total Groups"
'ws.Columns(3).ColumnWidth = 10
ws.Cells(1,4).Value = "Local group"
ws.Columns(4).ColumnWidth = 10
ws.Cells(1,5).Value = "Universal group"
ws.Columns(5).ColumnWidth = 10
ws.Cells(1,6).Value = "Global group"
ws.Columns(6).ColumnWidth = 10

ws.Cells(1,6).Value = "Token Size"
ws.Columns(6).ColumnWidth = 10


'Replace the domain with your domain in your environment
Strdomain = "DC=contoso,DC=msft"

Set objConnection = CreateObject("ADODB.Connection")
Set objCommand =   CreateObject("ADODB.Command")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"

Set objCOmmand.ActiveConnection = objConnection
objCommand.CommandText = _
    "Select SAMAccountname,distinguishedname,displayname from 'LDAP://" & strDomain & "' " _
        & "Where objectcategory='user' AND SAMAccountname = '*'"
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
Set objRecordSet = objCommand.Execute
objRecordSet.MoveFirst


Do Until objRecordSet.EOF

ws.cells(I,1).Value = objRecordSet.Fields("displayname").Value
ws.cells(I,2).value = objRecordSet.Fields("SAMAccountname").Value
  On Error Resume Next
wscript.echo objRecordSet.Fields("distinguishedname").Value

' Bind to the user object in Active Directory with the LDAP provider.
Set objUser = GetObject("LDAP://" & objRecordSet.Fields("distinguishedname").Value)

' Bind to dictionary object.
Set objGroupList = CreateObject("Scripting.Dictionary")

' Enumerate group memberships.
Call EnumGroups(objUser)
' ws.cells(I,3).value = TotalGroups
ws.cells(I,4).value = LocalGroup
ws.cells(I,5).value = UniversalGroup
ws.cells(I,6).value = GlobalGroup
'Token Size Computation based on http://support.microsoft.com/kb/327825
Tokensize = 1200 + localgroup*40 + 8*(UniversalGroup + GlobalGroup)
ws.cells(I,7).value = Tokensize

'To reset the numbers after each user
TotalGroups=0
UniversalGroup=0
LocalGroup=0
GlobalGroup = 0

objRecordSet.MoveNext
I = I + 1

Loop

'You may wish to change this to any path as needed.
ws.SaveAs "D:\Scripts\CalculateTokenSize\" & "usertoken.xlsx"
app.quit

'_____________________________________________________________


Sub EnumGroups(objADObject)
' Recursive subroutine to enumerate user group memberships.
' Includes nested group memberships.
Dim colstrGroups, objGroup, j
objGroupList.CompareMode = vbTextCompare
colstrGroups = objADObject.memberOf

If IsEmpty(colstrGroups) Then
Exit Sub
End If


If TypeName(colstrGroups) = "String" Then
Set objGroup = GetObject("LDAP://" & colstrGroups)
If Not objGroupList.Exists(objGroup.sAMAccountName) Then
objGroupList(objGroup.sAMAccountName) = True
Select Case objGroup.GroupType
    Case 2
        GlobalGroup = GlobalGroup +1
    Case 4
localgroup = Localgroup +1
    Case 8
UniversalGroup=UniversalGroup +1
    Case -2147483646
GlobalGroup = GlobalGroup +1
    Case -2147483644
        localgroup = Localgroup +1
    Case -2147483640
UniversalGroup=UniversalGroup +1
End Select


Call EnumGroups(objGroup)
End If
Set objGroup = Nothing
Exit Sub
End If

For j = 0 To UBound(colstrGroups)
Set objGroup = GetObject("LDAP://" & colstrGroups(j))
If Not objGroupList.Exists(objGroup.sAMAccountName) Then
objGroupList(objGroup.sAMAccountName) = True

Select Case objGroup.GroupType
    Case 2
        GlobalGroup = GlobalGroup +1
    Case 4
localgroup = Localgroup +1
    Case 8
UniversalGroup=UniversalGroup +1
    Case -2147483646
GlobalGroup = GlobalGroup +1
    Case -2147483644
        localgroup = Localgroup +1
    Case -2147483640
UniversalGroup=UniversalGroup +1
End Select

Call EnumGroups(objGroup)

End If

TotalGroups=TotalGroups+1


Next
Set objGroup = Nothing
End Sub

'End of VBS

Friday, July 27, 2012

SCOM Subscriptions automatically disabled repeatedly

An issue was flagged to my side that certain IT teams are not getting the alerts that they have been subscribed to.

Upon logging onto the SCOM Console it has been found that these notification subscriptions were getting disabled every 30 minutes. The weird thing was that not all subscriptions were being disabled and the same subscriptions were the same subscriptions every time. I tried re-enabling them and had the same result, the subscriptions kept being disabled. After some digging through the operations manager logs I found this warning:


Log Name: Operations Manager
Source: Health Service Modules
Date: 7/27/2012 5:53:22 PM
Event ID: 11452
Task Category: None
Level: Warning
Keywords: Classic
User: N/A

Computer: RMSserver

Description:
Validate alert subscription data source module encountered an alert subscription data source with configuration that has gone out of scope. Disabling the alert subscription data source module.

Alert subscription name: Subscription45c18cec_e95d_4af6_877e_072844d147d0

One or more workflows were affected by this.
Workflow name: Microsoft.SystemCenter.ValidateAlertSubscription
Instance name: RMSServer
Instance ID: {AF86A1AC-F1F5-9BF7-1E89-F60F73982EB6}
Management group: ManagementGRP



The problem turned out to be that someone in the team has just recently cleaned up the SCOM Admins user group and one of the users removed from the group had created this subscriptions. By putting the user back in the SCOM Admins group and re-enabling the subscriptions the problem was solved but we really didn’t want this user (Who has left the company) in the SCOM Admins group.

What is the root cause of this? When a subscription is created the user who created the subscriptions SID is associated with that subscription. There is a workflow that checks every half hour for SIDs no longer valid. They could be invalid because their accounts access that had been removed, or possibly because the account has been disabled or deleted.

The Solution

To fix the issue permanently, the management pack “Microsoft.SystemCenter.Notifications.Internal” is exported in xml format.
This management pack is unsealed and contains all subscriptions.
Inside the management pack I searched for one of the subscriptions that were being disabled and one that was wasn’t. I then replaced the SID of the subscription that is disabled with the SID of the subscription which is enabled.
After replacing the SIDs I re-imported the management pack and re-enabled all subscriptions and the problem was solved for good.
Here is an example of one of the SIDs I had to replace.

<ExpirationStartTime>12/01/2010 10:00:21</ExpirationStartTime>
<IdleMinutes>5</IdleMinutes>
<PollingIntervalMinutes>1</PollingIntervalMinutes>
<UserSid>S-1-5-21-1202660629-706699826-839522115-63827</UserSid>
<LanguageCode>ENE</LanguageCode>
<ExcludeNonNullConnectorIds>false</ExcludeNonNullConnectorIds>
<RuleId>$MPElementlt;/RuleId>