Tuesday, November 18, 2014

Missing mailbox / Distribution list in Offline Address Book

You might experience this error during an Offline Address Book generation cycle:

Index : 94460
EntryType : Warning
EventID : 9327
Message : OALGen skipped some entries in the offline address list ‘\Global Address List’. To see which entries are affected, event logging for the OAL Generator must be set to at least medium.
- Default Offline Address List
Category : OAL Generator
CategoryNumber : 13
ReplacementStrings : {\Global Address List, Default Offline Address List}
Source : MSExchangeSA

After you set the event log level for the OAL Generator to at least medium, eg. by using this EMS command:
Set-EventLogLevel ‘MSExchangeSA\OAL Generator’ -level Medium
You start seeing these errors:

Index : 94454
EntryType : Error
EventID : 9325
Message : OALGen will skip user entry ‘user1′ in address list ‘\Global Address List’ because the SMTP address ” is invalid.
- Default Offline Address List
Category : OAL Generator
CategoryNumber : 13
ReplacementStrings : {user1, \Global Address List, , Default Offline Address List}
Source : MSExchangeSA

As we can see from the error in the Event Log, OAL Generator claims that the SMTP address ” (blank) is invalid. This is not surprising, as a blank address can not be used for anything.
I have discovered one reason for this error, there might be more. If the user’s primary SMTP address does not match the value in the mail attribute in Active Directory, this error is generated. This happens if you change the primary SMTP address in EMC. EMC does not update the address in the mail attribute. To see if you have any recipients in your organization that have a mismatch between these two values, run these EMS commands:

get-mailbox -resultsize unlimited | where { $_.WindowsEmailAddress -ne $_.PrimarySmtpAddress } | ft –auto

get-distributiongroup -resultsize unlimited | where { $_.WindowsEmailAddress -ne $_.PrimarySmtpAddress } | ft –auto

get-dynamicdistributiongroup -resultsize unlimited | where { $_.WindowsEmailAddress -ne $_.PrimarySmtpAddress } | ft –auto

This should be possible to do with Get-Recipient as well, but I cannot make it work. Get-Recipient always return every recipient in the organization.

To remedy this situation, these EMS commands may be of interest:

get-mailbox -resultsize unlimited | where { $_.WindowsEmailAddress -ne $_.PrimarySmtpAddress } | ForEach { Set-Mailbox $_ -WindowsEmailAddress $_.PrimarySMTPAddress }

get-distributiongroup -resultsize unlimited | where { $_.WindowsEmailAddress -ne $_.PrimarySmtpAddress } | ForEach { Set-distributiongroup $_ -WindowsEmailAddress $_.PrimarySMTPAddress}

get-dynamicdistributiongroup -resultsize unlimited | where { $_.WindowsEmailAddress -ne $_.PrimarySmtpAddress } | ForEach { Set-dynamicdistributiongroup $_ -WindowsEmailAddress $_.PrimarySMTPAddress}

You should probably test these commands with the –whatif parameter added to the Set cmdlets.
A good pointer as to which recipients have a mismatch between these values, are those recipients who no longer have their Email addresses updated by a recipient policy. You can quickly list which recipients are in this state:

get-mailbox -ResultSize unlimited | where { $_.EmailAddressPolicyEnabled -eq $false } | ft –auto

get-distributiongroup -ResultSize unlimited | where { $_.EmailAddressPolicyEnabled -eq $false } | ft –auto

get-dynamicdistributiongroup -ResultSize unlimited | where { $_.EmailAddressPolicyEnabled -eq $false } | ft –auto

Also recipients who are targets of E-Mail address policies (EAP), but where those policies have not been applied, are candidates for this error.

Lastly, you cannot set the mail attribute if a recipient is a target of an EAP.
Remember to set the Event Log level back to it’s original value after you have finished troubleshooting:

Set-EventLogLevel ‘MSExchangeSA\OAL Generator’ -level lowest

Monday, October 27, 2014

HyperV VHD Permissions

Due to a lack of resources on one of our HyperV hosts, I had to move the VHD to another drive to perform some work. When I moved the VHD back to the original location, I could not start it!
Apparently my earlier actions has stripped the Virtual Machine SID permissions and therefore Hyper-V couldn't take control of the file as necessary.  In order to restore the file permissions I ran the following:

icacls “<path to VHD>.vhd” /grant “NT VIRTUAL MACHINE\<virtual machine SID>”:F

If you don’t know the virtual machine SID, navigate to the folder storing your virtual machine files and click on the Virtual Machines subfolder.  Inside this folder is an XML document named the same as the SID

Thursday, October 9, 2014

Source IP Address Preference with Multiple IPs on a NIC

Deploying SCOM agents on servers in the DMZ isn't that difficult, what is so difficult about this?
All that is needed is to raise a Change Request for the Firewall Team to open up TCP 5723 between the SCOM Management Server and the server to be monitored. Well, you are right.
What about if the server is having a single NIC that is assigned several IP addresses?
That's where the challenge will come.

A behavior that changed with the introduction of Server 2008 is that the source IP address on a NIC will always be the lowest numerical IP. So that whole idea of your primary IP being the first one you put on the NIC will be used by the server to communicate is no longer valid.

For example, let’s say we build a new web server and configure the NIC with IP 10.0.0.100. This IP is registered in DNS and the server uses this IP as the source when communicating with other servers. Our fantastic network administrator has also created a NAT rule on the firewall to map this IP to a particular public IP for outbound SMTP so that our PTR lookups match up.

But now we want to add another IP for a new website and the network admin hands you a free IP which happens to be 10.0.0.50. You add this as an additional IP on the NIC and voila – you have a couple issues:

1) You just registered two names for the same server in DNS if dynamic registration is enabled.
2) Your server is now sending all outbound traffic from 10.0.0.50! (because 50 is lower than 100)

One of these is easily solved – just turn off dynamic registration and manually create the DNS records for the server. The other one is a little trickier because Server 2008 and 2008 R2 will still be sending traffic as the 10.0.0.50 IP.

Fortunately, there is a way to tell Windows not to use the lower numbered IP as a source address by adding the IP via the netsh.exe command. For Server 2008 SP2 and 2008 R2 RTM we need to apply a hotfix first. 2008 R2 SP1 included this fix by default so it is no longer required. Without the hotfix or SP1 you’ll find netsh.exe does not display or recognize the special flag.

Hotfix Downloads:
2008 SP2: http://support.microsoft.com/kb/975808
2008 R2 RTM: http://support.microsoft.com/kb/2386184/

The key to this is the IP address must be added via netsh.exe with a particular flag. So if you’ve already added the IP address via the GUI you’ll need to remove it first. After that, use this command to add the secondary IP:

netsh int ipv4 add address "Local Area Connection" 1.2.3.4/24 SkipAsSource=true

The SkipAsSource flag does two things – first, it instructs Windows not to use this IP as a source IP for outgoing traffic. And secondly, it prevents the registration of this IP in DNS if dynamic registration is enabled. Two birds with one stone!

You can always view the status of the IPs and their SkipAsSource status with the following command:

netsh int ipv4 show ipaddresses level=verbose

Once you have done the above, you can now put in the correct IP address to be allowed for communications through the firewall in your change request.
:)

Friday, October 3, 2014

Free Powershell Hyper-V Cookbook by Altaro


A new ebook has been published by the good people at Altaro for the community.
The ebook which come FREE is packed with scripts to manage Hyper-V using PowerShell.

Go it your copy of The Altaro PowerShell Hyper-V Cookbook by Jeffery Hicks now!



Wednesday, September 24, 2014

SCCM Client breaks after Site Signing Certificate Renewal


The ConfigMgr sites in where I work is running in Native Mode and this means that there will be certificates required for this. Recently, the site signing certificate for one of my sites is expiring and hence renewal is required. The renewal went smooth for the Document Signing. However, after the new site signing certificate was issued  and assigned to the site, all clients stopped getting policies.

We got this error on the clients's PolicyAgent.log:




Everything looked fine, all certificates got issued, all clients trusted the new certificate, but still the ConfigMgr agent would not work. However, uninstalling and re-installing the client solved the problem, but I can't possibly be doing this for over 10000 clients?

Technically speaking, renewing/replacing the site signing certificate issued from the same Certificate Authority should not cause this issue but... Usually the new certificate will be automatically downloaded when renewing the certificate
But for my case, this unfortunately did not happen.
I had to remove the old site signing certificate on the ConfigMgr client agents. This is stored in the registry, and can be worked out with a simple Group Policy Preferences fix.

For me, I used the vbs below with a combination of psexec to do the same

const HKEY_LOCAL_MACHINE = &H80000002

strComputer = "."

Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")

strKeyPath = "SOFTWARE\Microsoft\CCM\Security"
strValueName = "AllowedRootCAHashCode"
strValue = ""

objRegistry.SetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strValue

Basically what you need to do is to remove the client copy of the site server signing certificate if you change the root certification, locate the value named AllowedRootCAHashCode (type REG_SZ) and delete the associated value data that appears as a string of hexadecimal numbers.”
For x86-systems: HKLM\SOFTWARE\Microsoft\CCM\Security
For x64-systems: HKLM\SOFTWARE\Wow6432Node\Microsoft\CCM\Security

After this is done, you should restart the SMS Agent service and you should continue to monitor the PolicyAgent.log for the cleanup of machine policy and after which all should work. 

Tuesday, September 9, 2014

Managing Distribution Groups with hidden membership (when hideDLMembership is true)

There are situations in messaging environments where we want to manage distribution groups through Outlook client and want to ensure that its membership is visible to none but the distribution group owner. In legacy versions of Exchange it was quite straight forward, but Exchange 2010 presents little complexity that can be easily overcome by following a workaround.

Exchange Server 2010

With Exchange Server 2010, things change a little bit. Two aspects that need to be considered - RBAC & Address Book Service.

Let's go by an example.

We have mailbox-enabled users Jeff Oscar , Kevin Pascal, Laura Qunitero, Mike Ruth and Noel Swan on Exchange Server 2010.

We have a distribution group - Escalation Services, Noel Swan being the distribution group owner.







If the distribution group owner has mailbox on Exchange 2010, then even he can’t see the membership details, if hideDLMembership attribute is set to TRUE.

It’s something like below.






In addition, if the owner attempts to modify the membership of the distribution group through Outlook, following message pops up (even though the check box “Manager can update membership list” is selected).






So, for both issues the reason(s) there are couple of different workaround(s).

In Exchange 2010, with the introduction of RBAC, we have to perform some additional steps to ensure that the owner can modify the membership (even with the check box “Manager can update membership list” selected.).

The steps are documented in KB 982349 “Changes to the distribution list membership cannot be saved" error message when you try to remove members from an Exchange Server 2010 distribution list”

Solution 1: If you just want to enable the owner to modify the distribution group membership (with membership hidden for owner as well), then just run following commands - (i) to create a new role group, (ii) add Noels as member, (iii) and verify the membership.

[PS] C:\>New-RoleGroup DistributionGroupManagement -Roles "Distribution Groups"

Name
----
DistributionGroupManagement

[PS] C:\>Add-RoleGroupMember DistributionGroupManagement -Member Noels
[PS] C:\>Get-RoleGroupMember DistributionGroupManagement

Name
----
Noel Swan



Now, the distribution group membership can be modified by the owner via Outlook client (obviously only additions, as s/he can't see the membership).

Solution 2: If you want to enable the owner (a) to view distribution group membership (b) to modify distribution group membership through Outlook client, then just hard code the Outlook client to talk to closest GC, by following the KB 319206 “How to configure Outlook to a specific global catalog server or to the closest global catalog server”.

HKEY_CURRENT_USER\Software\Microsoft\Exchange\Exchange Provider
On the Edit menu, click Add Value, and then add the following registry value:

Value name: DS Server
Data type: REG_SZ (string)
Value data: FQDN of the global catalog server


And, one more interesting aspect that I would like to mention.

If, following conditions are true..
The check box for "Manager can update membership list" in Active Directory Users and Computers is not selected on the Distribution Group property.
Distribution Group owner has been provided appropriate RoleGroupMembership [ RBAC "DistributionGroups"].

[ These will be the most likely situations when the distribution group and distribution group owner are created via Exchange Management Console in Exchange Server 2010 environments.]

Then, the result as observed by Distribution Group owner via Outlook client will be as follows.


Without "DS Server" registry key --

a. Will not be able to see membership in Outlook client.

b. But will be able to add members to the distribution group via Outlook client


With the "DS Server" registry key --

a. Will be able to see membership in Outlook client.

b. But will not be able to remove/add members to the distribution group via Outlook client.


So, the solution -- ensure that the check box "Manager can update membership list" is selected, if you want the distribution group owner to see & modify the membership.

Thursday, September 4, 2014

Event ID 10 AD MP DC Local Discovery : Active Directory Helper Objects Installation unsuccessful. MSI was not found at the specified location


Encountered a situation where the SCOM agent was installed on a Windows 2008 R2 Domain Controller but was unable to locate it under the DC state in the AD MP folder.
I found this EventID in the OpsMgr event log on all DCs reporting to a SCOM R2 Gateway Server.



As it turned out, the AD Helper Object (OOMADs.msi) was missing on the DC. The SCOM R2 Gateway Server did not have this file in place so it never arrived on the DC to be monitored by SCOM.

To remediate this issue and stop it from re-occuring ever again. 
This is what was dome:

Corrected the SCOM R2 Gateway Server
Copied the file OOMADs.msi from the installation media of SCOM R2 (~\HelperObjects\<ARCHITECTURE>) to the installation folder of the SCOM R2 Gateway Server (~:\Program Files\System Center Operations Manager 2007\HelperObjects).

Corrected the Agent Staging Folder
Copied the file OOMADs.msi from the installation media of SCOM R2 (~\HelperObjects\<ARCHITECTURE>) to the Agent Staging folder of the SCOM R2 Gateway Server (~:\Program Files\System Center Operations Manager 2007\AgentManagement\<ARCHITECTURE>). 

Copied the AD Helper Object to the Agent
Copied the file OOMADs.msi from the installation media of SCOM R2 (~\HelperObjects\<ARCHITECTURE>) to the installation folder of the SCOM R2 Agent (~:\Program Files\System Center Operations Manager 2007\HelperObjects).

Corrected the Agent
Stopped the HealthService, removed the cache file (~:\Program Files\System Center Operations Manager 2007\Health Service State), installed the AD Helper Object manually and restarted the HealthService. Checked the OpsMgr event log for EventID 10. It did not return. Closed the Alerts (based on a Rule) in the SCOM Console per fixed DC and the Alerts did not come back.

Now all is well and the DC are monitored in a proper manner. 

Thursday, August 28, 2014

Updated SCOM Management Packs

Some SCOM management packs have been upated as of 27th August 2014.
Those updated includes

1) DHCP MP
2) DNS MP
3) MSMQ MP
4) Cluster MP
5) AD MP
6) Windows Server Core MP

More details is available here

Thursday, August 14, 2014

Customizing Information in SCOM Subscriptions

Custom Properties for Alert Description and Notification:
Alert Description Variables:
For event Rules:
EventDisplayNumber (Event ID):             $Data/EventDisplayNumber$ 
EventDescription (Description):               $Data/EventDescription$ 
Publisher Name (Event Source):              $Data/PublisherName$ 
EventCategory:                                    $Data/EventCategory$ 
LoggingComputer:                                $Data/LoggingComputer$ 
EventLevel:                                          $Data/EventLevel$ 
Channel:                                              $Data/Channel$ 
UserName:                                           $Data/UserName$ 
EventNumber:                                      $Data/EventNumber$ 
Event Time:                                          $Data/@time$
For event Monitors:
EventDisplayNumber (Event ID):            $Data/Context/EventDisplayNumber$ 
EventDescription (Description):              $Data/Context/EventDescription$ 
Publisher Name (Event Source):             $Data/Context/PublisherName$ 
EventCategory:                                    $Data/Context/EventCategory$ 
LoggingComputer:                                $Data/Context/LoggingComputer$ 
EventLevel:                                         $Data/Context/EventLevel$ 
Channel:                                             $Data/Context/Channel$ 
UserName:                                          $Data/Context/UserName$ 
EventNumber:                                     $Data/Context/EventNumber$ 
Event Time:                                         $Data/Context/@time$

For Repeating Event Monitors:
EventDisplayNumber (Event ID):              $Data/Context/Context/DataItem/EventDisplayNumber$ 
EventDescription (Description):                $Data/Context/Context/DataItem/EventDescription$ 
Publisher Name (Event Source):              $Data/Context/Context/DataItem/PublisherName$ 
EventCategory:                                      $Data/Context/Context/DataItem/EventCategory$ 
LoggingComputer:                                  $Data/Context/Context/DataItem/LoggingComputer$ 
EventLevel:                                            $Data/Context/Context/DataItem/EventLevel$ 
Channel:                                                $Data/Context/Context/DataItem/Channel$ 
UserName:                                             $Data/Context/Context/DataItem/UserName$ 
EventNumber:                                         $Data/Context/Context/DataItem/EventNumber$
  
Performance Threshold Monitors:
Object (Perf Object Name):                    $Data/Context/ObjectName$ 
Counter (Perf Counter Name):                $Data/Context/CounterName$ 
Instance (Perf Instance Name):              $Data/Context/InstanceName$ 
*Value (Perf Counter Value):                  $Data/Context/Value$  
**Last Sampled Value                            $Data/Context/SampleValue$
*Value will show the actual performance value for simple and avg monitors.
It will show number of samples for consecutive threshold monitors. 
**Last Sampled Value works to show the last value evaluated in a consecutive sample value monitor.
Service Monitors:
Service Name                         $Data/Context/Property[@Name='Name']$ 
Service Dependencies             $Data/Context/Property[@Name='Dependencies']$ 
Service Binary Path                $Data/Context/Property[@Name='BinaryPathName']$ 
Service Display Name             $Data/Context/Property[@Name='DisplayName']$ 
Service Description                 $Data/Context/Property[@Name='Description']$

Logfile Monitors:
Logfile Directory :                  $Data/Context/LogFileDirectory$ 
Logfile name:                        $Data/Context/LogFileName$ 
String:                                  $Data/Context/Params/Param[1]$

Logfile rules:
Logfile Directory:                   $Data/EventData/DataItem/LogFileDirectory$ 
Logfile name:                        $Data/EventData/DataItem/LogFileName$ 
String:                                  $Data/EventData/DataItem/Params/Param[1]$

General:
To show the name of the Windows Computer host: 
$Target/Host/Property[Type="Windows!Microsoft.Windows.Computer"]/NetworkName$

Notifications:
$Data/Context/DataItem/AlertId$                                       The AlertID GUID 
$Data/Context/DataItem/AlertName$                                   The Alert Name 
$Data/Context/DataItem/Category$                                    The Alert category 
$Data/Context/DataItem/CreatedByMonitor$                       True/False 
$Data/Context/DataItem/Custom1$                                     CustomField1 
$Data/Context/DataItem/Custom2$                                    CustomField2 
$Data/Context/DataItem/Custom3$                                    CustomField3 
$Data/Context/DataItem/Custom4$                                    CustomField4 
$Data/Context/DataItem/Custom5$                                    CustomField5 
$Data/Context/DataItem/Custom6$                                     CustomField6 
$Data/Context/DataItem/Custom7$                                     CustomField7 
$Data/Context/DataItem/Custom8$                                     CustomField8 
$Data/Context/DataItem/Custom9$                                     CustomField9 
$Data/Context/DataItem/Custom10$                                  CustomField10 
$Data/Context/DataItem/DataItemCreateTime$                      UTC Date/Time of Dataitem created 
$Data/Context/DataItem/DataItemCreateTimeLocal$               LocalTime Date/Time of Dataitem created 
$Data/Context/DataItem/LastModified$                                 UTC Date/Time DataItem was modified 
$Data/Context/DataItem/LastModifiedLocal$                          Local Date/Time DataItem was modified 
$Data/Context/DataItem/ManagedEntity$                               ManagedEntity GUID 
$Data/Context/DataItem/ManagedEntityDisplayName$             ManagedEntity Display name 
$Data/Context/DataItem/ManagedEntityFullName$                   ManagedEntity Full name 
$Data/Context/DataItem/ManagedEntityPath$                          Managed Entity Path 
$Data/Context/DataItem/Priority$                                          The Alert Priority Number (High=1,Medium=2,Low=3) 
$Data/Context/DataItem/Owner$                                           The Alert Owner 
$Data/Context/DataItem/RepeatCount$                                  The Alert Repeat Count 
$Data/Context/DataItem/ResolutionState$                               Resolution state ID (0=New, 255= Closed) 
$Data/Context/DataItem/ResolutionStateLastModified$                 UTC Date/Time ResolutionState was last modified 
$Data/Context/DataItem/ResolutionStateLastModifiedLocal$          Local Date/Time ResolutionState was last modified 
$Data/Context/DataItem/ResolutionStateName$                       The Resolution State Name (New, Closed) 
$Data/Context/DataItem/ResolvedBy$                                     Person resolving the alert 
$Data/Context/DataItem/Severity$                                          The Alert Severity ID 
$Data/Context/DataItem/TicketId$                                           The TicketID 
$Data/Context/DataItem/TimeAdded$                                       UTC Time Added 
$Data/Context/DataItem/TimeAddedLocal$                               Local Time Added 
$Data/Context/DataItem/TimeRaised$                                      UTC Time Raised 
$Data/Context/DataItem/TimeRaisedLocal$                              Local Time Raised 
$Data/Context/DataItem/TimeResolved$                                  UTC Date/Time the Alert was resolved 
$Data/Context/DataItem/WorkflowId$                                      The Workflow ID (GUID) 
$Data/Recipients/To/Address/Address$                                    The name of the recipient

The Web Console URL: 
$Target/Property[Type="Notification!Microsoft.SystemCenter.AlertNotificationSubscriptionServer"
/WebConsoleUrl$

The principalname of the management server: 
Target/Property[Type="Notification!Microsoft.SystemCenter.AlertNotificationSubscriptionServer"
/PrincipalName$

Wednesday, August 13, 2014

New Office 365 MP

On July 29th 204, Microsoft has released System Center Management Pack for Office 365 and it can be downloaded from here

This management pack can be used to
1.       Add and configure Office 365 subscriptions to be monitored in Operations Manager
2.       Proactively monitor connection health for subscriptions
3.       Automatically discover services and features available for each subscription
4.       Proactively notify when Office 365 Incidents that affects services operational status appear, being changed or resolved
5.       Reflect Office 365 Incidents and informational Messages for the subscription to Operations Manager alerts
Intuitively visualize subscriptions health and corresponding alerts via dashboard

I will blog about this in future after importing this into my environment.


Tuesday, August 5, 2014

How to enable the Disk Cleanup tool on Windows Server 2008 R2

For some odd reason Microsoft decided to leave this feature disabled by default, and place it within a optional feature set called "Desktop Experience".

If your hard drive is getting full and you wish to do a disk cleanup, there are two ways to enable the Disk Cleanup tool. We recommend using option #2 below for several reasons:

- Installing the Desktop Experience feature will not only install Disk Cleanup, but a lot of other utilities you likely don't need on a server (sound recorder, desktop themes, etc).

- Installing the Desktop Experience feature will require a server reboot


How to enable the Disk Cleanup tool:

1) Go to Programs & Features, and in the Features section, enable/install "Desktop Experience". The downside to this is that you will need to reboot your server after installing this and it installs other components you do not need on a server.


2) [RECOMMENDED] - All you really need to do is copy some files that are already located on your server into specific system folders, as described at http://technet.microsoft.com/en-us/library/ff630161(WS.10).aspx


The location of the files you need to copy depend on your version of Windows:


Once you have located the files move them to the following locations:

Copy Cleanmgr.exe to %systemroot%\System32
Copy Cleanmgr.exe.mui to %systemroot%\System32\en-US.

You can now launch the Disk cleanup tool by running Cleanmgr.exe from the command prompt.

Thursday, July 24, 2014

Permission to perform this operation was denied (VMWare Convertor)

Encountered an issue while attempting to convert a HyperV server to a vSphere server.
Using the VMWare vCenter converter as per normal, I was faced with a roadblock when I attempted to select the hyperV server for conversion.

Error that was flagged is
"Permission to perform this operation was denied "

In the back of my mind, I was thinking out loud "How could I be denied when I was the domain admin!"
After futile attempts which included running the VMWare convertor as "Administrator", I resorted to the last means which is to turn of the UAC for my account.
After the restart following the change, all works!
Weird but true....

Friday, July 18, 2014

Exchange 2010 Health Check Report

This script is a fast and efficient way of checking if you have any severe issues with your Exchange 2010 setup.
All credits to go to the scripts original author at ExchangeServerPro

http://exchangeserverpro.com/powershell-script-health-check-report-exchange-2010

All that is need is to download the file from the link above.


The command line in PowerShell to run the script is as follows

Single Server
.\test-ExchangeServerHealth.ps1 -reportmode $true -sendemail $true -server <Exchange Server Name>

Entire Organization
.\test-ExchangeServerHealth.ps1 -reportmode $true -sendemail $true -server *

Servers Starting with perhaps a site with Server Prefixed with "SIN"
.\test-ExchangeServerHealth.ps1 -reportmode $true -sendemail $true -server sin*

The PS script can be downloaded from the link below
http://inside.exchangeserverpro.com/members/test-exchangeserverhealth/

The Test-ExchangeServerHealth.ps1 script is run from the Exchange Management Shell. You can use a few builtin parameters to control what it does.
.PARAMETER Server
Perform a health check of a single server

.PARAMETER ReportMode
Set to $true to generate a HTML report. A default file name
is used if none is specified.

.PARAMETER ReportFile
Allows you to specify a different HTML report file name than
the default. Implies -ReportMode

.PARAMETER SendEmail
Sends the HTML report via email using the SMTP configuration
within the script. Implies -ReportMode

.PARAMETER AlertsOnly
Only sends the email report if at least one error or warning
was detected.

.PARAMETER Log
Writes a log file to help with troubleshooting.
If you use the report mode you’ll get a HTML file containing the health check results, and/or an email to your designated address if you also use the send email option.
For the email functionality to work please update these variables in the script to suit your environment.

#...................................
# Modify these Email Settings
#...................................

$smtpsettings = @{
 To =  "yourname@yourdomain.com"
 From = "exchangeserverhealthcheck@yourdomain.com"
 Subject = "Exchange Server Health Report - $now"
 SmtpServer = "smtp.yourdomain.com"
 }

Thursday, July 17, 2014

Useful SCOM 2007 R2 Powershell

Get list Operations Manager Commands
Get-OperationsManagerCommand

Get list of unavailable/unresponsive agents
Get-Monitoringclass -name "Microsoft.Windows.Computer" | Get-MonitoringObject | Where-Object {$_.IsAvailable -eq $False} | Select-Object DisplayName, IsAvailable | Format-Table

Resolve the healthserviceid to Agent Name
Get-Agent | Where-Object {$_.hostedHealthService.id -eq "healthserviceid"} | Select-Object name

Export All Unsealed Management Packs to UnsealedMPBackup Folder
Get-ManagementPack | where {$_.Sealed -eq $false} | Export-Managementpack -path C:\UnsealedMPBackup

Get the Management Server information including the Management Server Action Account identity
Get-ManagementServer | Select-Object DisplayName, IsRootManagementServer, ActionAccountIdentity, HealthState | Format-Table -autosize

Get the User Roles and its Members
Get-Userrole | Select-Object DisplayName, Users

Export all rules in imported management packs to rules.csv
Get-rule | select-object @{Name="MP";Expression={ foreach-object {$_.GetManagementPack().DisplayName }}},DisplayName | sort-object -property MP | export-csv "c:\rules.csv"

Get List of agent managed machines and their ip address
Get-agent | format-list -property, displayname, IPAddress

Enable Agent Proxy for all agents where it is disabled
$NoProxy = get-agent | where {$_.ProxyingEnabled -match "false"}
$NoProxy|foreach {$_.ProxyingEnabled = $true}
$NoProxy|foreach {$_.ApplyChanges()}

Friday, May 23, 2014

Server in which SCCM Collection?

Most servers in SCCM would be a member in a couple collections and it would be pretty challenging to track which collections it is a member of.
The following SQL query will enable you just to do that 

select v_FullCollectionMembership.CollectionID, v_Collection.Name, v_R_System.Name0 from v_FullCollectionMembership 
JOIN v_R_System on v_FullCollectionMembership.ResourceID = v_R_System.ResourceID 
JOIN v_Collection on v_FullCollectionMembership.CollectionID = v_Collection.CollectionID 
Where v_R_System.Name0='Servername'

** Replace Servername with the servername you are checking against.

Wednesday, May 21, 2014

Cleaning up expired updates in SCCM


In SCCM, it is essential to house keep the update lists to remove expired updates in order to ensure that the compliance is reported correctly.

Of course you can manually go through all the update lists and deployment packages that you have created to remove those but why not use some tools to help you achieve that instead?

The below post is a VBS written by someone in the community which is very useful for this.

http://blogs.msdn.com/b/minfangl/archive/2012/10/16/script-to-clean-expired-updates-from-update-lists-packages-and-deployments.aspx

I have made minor amendments to the vbs which you can download from here
To use simply download the file and place it in a folder on the SCCM Server.
Open up command prompt and run the command below in the folder where you have placed the vbs

cscript ExpireClear.vbs [-d] -l|-r:<remoteserver> -u:<Username> -p:<password>

Switches defnitions
-d enable debug logging
-l connect to local machine
-r connect to remote machine

If -r is used, the user's credentials has to be provided.

When the vbs completes, you will be prompted to run a full synchronization whihc can be achieve using the below

1) In the Configuration Manager console at the highest site in the hierarchy with an active software update point, navigate to System Center Configuration Manager / Site Database / Computer Management / Software Updates / Update Repository.

2) Right-click Update Repository, and then click Run Synchronization. Software updates synchronization is initiated as soon as possible.
When synchronization is complete, a request is sent to child sites to initiate synchronization.


List Alerts for Specific SCOM Group

There was a query in the Microsoft System Center Community Forum requesting for assistance for a SQL query to list all alerts for a particular SCOM Group within a specific time frame.
I have create the query below and hopefully this will help anyone that needs something similar.
All is needed is to replace those in bold and underlined based on your needs.

select AlertName
,RGV.targetMonitoringObjectDisplayName [Server Name]
,RGV.SourceMonitoringObjectDisplayName [SCOM Group Name]
,AlertDescription [Alert]
,ars.DWCreatedDateTime [Alert Date]
,alt.Priority [Priority]
,alt.Severity [Severity]
      ,day(ars.DWCreatedDateTime) [triggerdate]
    ,month(ars.DWCreatedDateTime) [triggermonth]
      ,year(ars.DWCreatedDateTime) [triggeryear]
       from Alert.vAlertResolutionState ars
inner join Alert.vAlertDetail adt on ars.alertguid = adt.alertguid
inner join Alert.vAlert alt on ars.alertguid = alt.alertguid
left join dbo.vManagedEntity ME on ME.ManagedEntityRowId = alt.ManagedEntityRowId
left join OperationsManager.dbo.RelationshipGenericView RGV on RGV.TargetMonitoringObjectDisplayName = ME.DisplayName
where ars.DWCreatedDateTime between 'start date (mm/dd/yy)' and  'end date (mm/dd/yy)'
and ME.DisplayName in (select TargetMonitoringObjectDisplayName
from OperationsManager.dbo.RelationshipGenericView
where isDeleted=0
AND SourceMonitoringObjectDisplayName = 'Group Name' )

Thursday, May 15, 2014

Retrieving Local Administrators on Machines by SCCM


IT in some Organizations may grant users with local admin rights
As time goes by when there is a time when we need to know who has local admin rights on their machines , this would be a potential challenge if the process is not defined clearly.

SCCM can be utilized to get this information using the steps below

1) The DCM Configuration Item.
- Create a new, General Configuration Item and name it whateveryou wish, but you'll need to use that name later in a report.

For this case, the name is "Local Group Members into WMI", click Next
- There are no Objects, click Next
- Under Settings, Select New, Script.
- Display Name doesn't matter, I'll call it "WMIFramework For LocalGroupMembers"
- Description can be anything, sych as "Custom WMI Namespace of root\cimv2\cm_localgroupmembers"
- copy and paste the vbs as below

======================================================================
on error resume next
'Steps
'enumerate from win32_group where localaccount=1
'Read in the members of each local group returned
'Add the returned information to a custom WMI namespace
'sms-def.mof to pull that back.
Set fso = CreateObject("Scripting.FileSystemObject") 
Set nwo = CreateObject("Wscript.Network") 
Set sho = CreateObject("Wscript.Shell") 
TempFolder = sho.ExpandEnvironmentStrings("%temp%")
strWindir = sho.ExpandEnvironmentStrings("%windir%")
strComputer = nwo.ComputerName
Dim wbemCimtypeSint16 
Dim wbemCimtypeSint32 
Dim wbemCimtypeReal32 
Dim wbemCimtypeReal64 
Dim wbemCimtypeString 
Dim wbemCimtypeBoolean 
Dim wbemCimtypeObject 
Dim wbemCimtypeSint8 
Dim wbemCimtypeUint8 
Dim wbemCimtypeUint16 
Dim wbemCimtypeUint32 
Dim wbemCimtypeSint64 
Dim wbemCimtypeUint64 
Dim wbemCimtypeDateTime 
Dim wbemCimtypeReference 
Dim wbemCimtypeChar16 

wbemCimtypeSint16 = 2 
wbemCimtypeSint32 = 3 
wbemCimtypeReal32 = 4 
wbemCimtypeReal64 = 5 
wbemCimtypeString = 8 
wbemCimtypeBoolean = 11 
wbemCimtypeObject = 13 
wbemCimtypeSint8 = 16 
wbemCimtypeUint8 = 17 
wbemCimtypeUint16 = 18 
wbemCimtypeUint32 = 19 
wbemCimtypeSint64 = 20 
wbemCimtypeUint64 = 21 
wbemCimtypeDateTime = 101 
wbemCimtypeReference = 102 
wbemCimtypeChar16 = 103 
' Remove classes 
Set oLocation = CreateObject("WbemScripting.SWbemLocator") 
'===================
'If this is a Domain Controller, bail!
'===================
Set oWMI = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\.\root\cimv2")
Set colComputer = oWMI.ExecQuery _
("Select DomainRole from Win32_ComputerSystem")
For Each oComputer in colComputer
 if (oComputer.DomainRole = 4 or oComputer.DomainRole = 5) then
   'wscript.quit
 Else
'==================
'If it is NOT a domain controller, then continue gathering info 
'and stuff it into WMI for later easy retrieval
'==================

Set oServices = oLocation.ConnectServer(,"root\cimv2") 
set oNewObject = oServices.Get("CM_LocalGroupMembers") 
oNewObject.Delete_ 
'==================
'Get the local Group Names
'==================
Dim iGroups(300)
i=0
Set objWMIService = GetObject("winmgmts:" _
        & "{impersonationLevel=impersonate}!\\.\root\cimv2")
Set colGroup = objWMIService.ExecQuery("select * from win32_group where localaccount=1")
for each obj in colGroup
  igroups(i)=obj.Name
  i=i+1
next
'===============
'Get all of the names within each group
dim strLocal(300)
k=0
Set oLocation = CreateObject("WbemScripting.SWbemLocator") 
Set oServices = oLocation.ConnectServer(, "root\cimv2" ) 

'group name, domain name, user or group
for j = 0 to i-1

squery = "select partcomponent from win32_groupuser where groupcomponent = ""\\\\" &_
 strComputer & "\\root\\cimv2:Win32_Group.Domain=\""" & strComputer &_
 "\"",Name=\""" &igroups(j) & "\""""" 

Set oInstances = oServices.ExecQuery(sQuery) 
 FOR EACH oObject in oInstances 
  strLocal(k)=igroups(j) & "!" & oObject.PartComponent

  k=k+1

 Next
next
'==================
'Drop that into a custom wmi Namespace
'==================


' Create data class structure 
Set oDataObject = oServices.Get 
oDataObject.Path_.Class = "CM_LocalGroupMembers" 
oDataObject.Properties_.add "Account" , wbemCimtypeString 
oDataObject.Properties_("Account").Qualifiers_.add "key" , True 
oDataObject.Properties_.add "Domain" , wbemCimtypeString
oDataObject.Properties_.add "Category" , wbemCimtypeString
oDataObject.Properties_.add "Type" , wbemCimtypeString
oDataObject.Properties_.add "Name" , wbemCimtypeString
oDataObject.Properties_("Name").Qualifiers_.add "key" , True
oDataObject.Put_ 

for m = 0 to k-1
Set oNewObject = oServices.Get("CM_LocalGroupMembers" ).SpawnInstance_ 
str0 = Split(strLocal(m), "!", -1, 1)
str1 = Split(str0(1), "," , -1, 1) 
str2 = Split(str1(0), "\" , -1, 1) 
str4 = Split(str2(4), Chr(34), -1, 1) 


' The Account name or Group Name is inside the quotes after the comma 
str3 = Split(str1(1), Chr(34), -1, 1) 
' if the wmi source name is the same as the domain name inside the quotes, it' s a local account 
' str2(2) is the wmi source name, str4(1) is the domain name inside the quotes. 
If lcase(str2(2)) = lcase(str4(1)) Then 
oNewObject.Type = "Local" 
Else 
oNewObject.Type = "Domain" 
End If
oNewObject.Domain = str4(1) 
oNewObject.Account = str3(1) 
oNewObject.Name = str0(0)
Select Case lcase(str4(0))
  case "cimv2:win32_useraccount.domain="
   oNewObject.Category = "UserAccount"
  Case "cimv2:win32_group.domain="
   oNewObject.Category = "Group"
  Case "cimv2:win32_systemaccount.domain="
   oNewObject.Category = "SystemAccount"
  case else
   oNewObject.Category = "unknown"
end select
oNewObject.Put_ 
Next

 end if
Next

wscript.quit
======================================================================

- Click on the Validation Tab, and change Severity to "Information - no Windows Event Message". Retain the check box for "report a non-compliance event when this instance count fails, of Greater than 0. Click Ok
- In Applicability Tab select "All Windows Platforms."

2) Create a DCM Baseline to target to a collection (If you are gathering information for all clients + servers, you can consider targeting the "All Systems" Collection.). Add the CI to the "These applications and general configuration items are required and must be properly configured"
When you assign, you are required to select a schedule. I recommend a Simple Schedule, and to make it be the same as your existing Simple Hardware Inventory schedule, i.e., if you have Hinv every 3 days, make this every 3 days.

3) Add the mof snippet to the bottom of sms_def.mof on your primarty sites' inboxes\clifiles.src\hinv

//=====================Local Group Members, Includes Administrators
//Pre-requisite: recurring Advertisement, or Recurring DCM Baseline/CI
//====================================================================
#pragma deleteclass ("LocalGroupMembers",NOFAIL)
[ SMS_Report (TRUE),
SMS_Group_Name ("LocalGroupMembers"),
SMS_Class_ID ("CUSTOM|LocalGroupMembers|1.0") ]
class cm_LocalGroupMembers : SMS_Class_Template
{
[SMS_Report (TRUE), key ] string Account;
[SMS_Report (TRUE) ] string Category;
[SMS_Report (TRUE) ] string Domain;
[SMS_Report (TRUE), key ] string Name;
[SMS_Report (TRUE) ] string Type;
};

A sample report if you would like to get the list of machines with users' being granted administrators rights is as below.
The query below is working on the assumption that the machines are not "hot seats".

select CS.Name0 [Machinename], account0 [Account Name],lgm.name0 [Groupname] ,lgm.type0 [Accounttype] from v_gs_localgroupmembers0 lgm
left join v_GS_COMPUTER_SYSTEM CS on CS.ResourceID = lgm.resourceid
where CS.UserName0 like '%'+lgm.account0 and lgm.name0 = 'Administrators'


Friday, May 9, 2014

OpsMgr 2012 Scheduled Maintenance Mode tool


This is a very neat new tool, that enabled you to create schedules for agents and groups to go into maintenance mode.

It is a web service, with a VERY simple user interface, to allow users to create schedules for maintenance mode, or for on-demand maintenance mode.
It even includes a nice tool/icon to place on all your servers desktops, to allow server admins to immediately place a server into maintenance mode from the server itself
http://www.scom2k7.com/scom-2012-maintenance-mode-scheduler/

All System Center Cmdlets you are looking for

Microsoft has released System Center CmdLets reference for all the system center components.
It will definitely be a great help to any System Center Admins.

The reference can be downloaded from the below
http://www.microsoft.com/en-us/download/details.aspx?id=41196&WT.mc_id=rss_alldownloads_all

Wednesday, April 30, 2014

Removing Orphaned Packages from SCCM Child Site

Packages that are deleted at a parent site can be orphaned at a child site if the child site unavailable or down at the time of deletion or the replication process is unsuccessful. You won’t be able to delete those packages from child site because they will be locked in the console as the packages originate from the Central Site. In this case, we will need to use the backdoor to fix the problem by modifying the package record from the child site database. Only when this is done, we will be allowed to delete the package from the child site SCCM console.

Procedure to Remove Orphan Packages

To remove orphan packages from the SQL Server database, please follow the below

** You will need to have SA rights for these actions

1. Open SQL Server Management Studio, and use the site database of the child site cs1(SMS_CHILD).

2. Type and run the following command in the query window:

select PkgId, Name, SourceSite from SMSPackages

3. Search for the PkgID file that you want to remove.

4. Type and run the following command in the query window:

Update SMSPackages Set SourceSite='<Child Site Code>' Where PkgID= '<Package ID>'

5. The package is now set to a local package and you can delete it from within the SCCM Administrator console.

Deletion should be performed from the SCCM console instead of via the database level to ensure that the deletion is clean.

Thursday, April 24, 2014

Mass Import IP for Exchange Receive Connector

There are times when you are required to add many IPs addresses to the receive connector on Exchange 2010. This IPs are required to enable the exchange server to relay emails for alerts etc.
The powershell script below is something that is found from the community that is extremely useful

Copy the below and save it as a ps1 file

<#
.DESCRIPTION
Simple Powershell script that can bulk import remote IP ranges from a text file in a determined Exchange Receive Connector.
The Import of the Remote IP ranges maintains the original values which are already present on the Selected Connector.
.PARAMETERS
None - execute directly from the Exchange Management Shell

.Compatibility

Exchange 2007
Exchange 2010
Exchange 2013
#>
function Select-FileDialog
{
param([string]$Title,[string]$Directory,[string]$Filter="Text Files (*.txt)|*.txt")
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
$objForm = New-Object System.Windows.Forms.OpenFileDialog
$objForm.InitialDirectory = $Directory
$objForm.Filter = $Filter
$objForm.Title = $Title
$objForm.ShowHelp = $true
$Show = $objForm.ShowDialog()

if ($Show -eq "OK")
{
return $objForm.FileName
}
else
{
exit
}
}
function get_RecConnector{
$RecConns = Get-ReceiveConnector | Select -ExpandProperty Identity
$Count = 0;
Write-Host "Bulk Import of Remote IP Addresses for Exchange Receive Connectors" -ForegroundColor Green
Write-Host "Version 0.1" -ForegroundColor Green
Write-Host "www.telnetport25.com" -ForegroundColor Green
Write-Host ""
Write-Host "Detected Receive Connectors: " -ForegroundColor Cyan
Write-Host ""
foreach($Connector in $RecConns){

Write-Host $Count "." $Connector -ForegroundColor White
$Count ++
}

Write-Host ""
$Choice = Read-Host "Please select the Receive Connector that you wish to work with."
Write-Host ""
import_RemoteIPRanges $RecConns[$Choice]
}
function import_RemoteIPRanges{
param($ConnectorID)
$FileName = Select-FileDialog "Open IP Range Text File..."
$IPs = Get-Content $FileName

foreach($IP in $IPs){
Write-Host "Adding IP Address :" $IP " to "$ConnectorID -ForegroundColor Cyan
$Rcnn = Get-ReceiveConnector "$ConnectorID"
$Rcnn.RemoteIPRanges += $IP
Set-ReceiveConnector "$ConnectorID" -RemoteIPRanges $Rcnn.RemoteIPRanges
}
}

get_RecConnector
Write-Host ""
Write-Host "Script Completed." -ForegroundColor Yellow


How to use

Before you use the script you should ensure that you have all of the IP addresses that you wish to add to a particular Receive Connector stored within a text file.

Each host should appear on a separate line. You can also use the CDIR address notation for an entire subnet if you wish to allow all hosts in a range to relay (for example add a line for 172.31.253.0/24) .

1) Open the Exchange Management Shell, navigate to the directory where you have downloaded the script file and type:

<path>.\<FileName of th3 ps1 file you saved earlier>.ps1

2) You will then be presented with a list of all the detected receive connectors that the script has located. Choose the connector via its numerical identifier (the numbers on the left hand side).


3) You will then be prompted to locate your IP Range text file which you created earlier – browse to it and then click on the “Open” button.

4)The script will then process each host entry and add it to the selected Receive Connector.


5) After the script has completed – if you check the [ Network –> Receive Mail from remote servers that these IP addresses ] in the Exchange Management Console, you should see that your addresses have been added.

Tuesday, April 22, 2014

SCCM Actions via WMI


Using WMIC to trigger SCCM Client Actions from command line:

Request for policy:
WMIC /namespace:\\root\ccm path sms_client CALL TriggerSchedule "{00000000-0000-0000-0000-000000000021}" /NOINTERACTIVE

To Evaluate policy:
WMIC /namespace:\\root\ccm path sms_client CALL TriggerSchedule "{00000000-0000-0000-0000-000000000022}" /NOINTERACTIVE

Disable Software-Distribution:
WMIC /namespace:\\root\ccm\policy\machine\requestedconfig path ccm_SoftwareDistributionClientConfig CREATE ComponentName="Disable SWDist",Enabled="false",LockSettings="TRUE",PolicySource="local",PolicyVersion="1.0" ,SiteSettingsKey="1" /NOINTERACTIVE

Re-Activate Software-Distribution:
WMIC /namespace:\\root\ccm\policy\machine\requestedconfig path ccm_SoftwareDistributionClientConfig WHERE ComponentName="Disable SWDist" delete /NOINTERACTIVE

Trigger Hardware Inventory:
WMIC /namespace:\\root\ccm path sms_client CALL TriggerSchedule "{00000000-0000-0000-0000-000000000001}" /NOINTERACTIVE

Trigger Software Inventory:
WMIC /namespace:\\root\ccm path sms_client CALL TriggerSchedule "{00000000-0000-0000-0000-000000000002}" /NOINTERACTIVE

Trigger DataDiscoverRecord (DDR) update:
WMIC /namespace:\\root\ccm path sms_client CALL TriggerSchedule "{00000000-0000-0000-0000-000000000003}" /NOINTERACTIVE

Force a FULL HW Inventory on next HW-Inv Schedule:
WMIC /namespace:\\root\ccm\invagt path inventoryActionStatus where InventoryActionID="{00000000-0000-0000-0000-000000000001}" DELETE /NOINTERACTIVE

Repair SMS/SCCM Agent on a remote client:
WMIC /node:%MACHINE% /namespace:\\root\ccm path sms_client CALL RepairClient

Repair a list (all clients listed in clients.txt) of remote SCCM Agents:
WMIC /node:@clients.txt /namespace:\\root\ccm path sms_client CALL RepairClient

Wednesday, April 16, 2014

Removing Obsolete Product Connector in SCOM 2007 R2

We used to be using Jalasoft for monitoring network devices which is integrated with SCOM and this product creates a product connector to pipe the data to SCOM.
However as this is no longer needed, I had to remove this obsolete Connector from a SCOM R2 environment. 
This cannot be done via the regular SCOM R2 console and has to be execute via one of the 3 methods below 

As Kevin Holman describes
This is not the official method but it works and gives you pretty much more control on what is being executed.

The official supported method, KB2626670
Basically a PS script which goes through the steps as per what is described by Kevin Holman :)

A community based tool
Un-official tool form the community

As you can see there are multiple options available to get to the end game
When you want to play is safe use KB2626670 since that’s the officially supported way.

Outlook: Unable to perform a Check Name or connect to an Exchange mailbox

Microsoft has released a quick publish article for Outlook Connectivity issues to Exchange.
Version of Outlook affected is 2007 and above.

Error Deleting Distributed Application in SCOM (Failed to verify View with ID)


I encountered the below trying to delete a distributed application and gotten the error similar to the below

Application: System Center Operations Manager 2007 R2
Application Version: 6.1.7221.0
Severity: Error
Message:

: Verification failed with [1] errors:
——————————————————-
Error 1:
: Failed to verify View with ID: View_1f3465325fe94ccb9876d7154bfa30c
Target property :ManagementPackElement=Service_ceecc43c88ee428197f7eafbf91236e2 in ManagementPack:[Name=my.managementpack, KeyToken=, Version=1.0.0.0] for this View is incorrect.Cannot find ManagementPackElement [Type=ManagementPackClass, ID=Service_ceecc43c88ee428197f7eafbf91236e2] in ManagementPack [ManagementPack:[Name=my.managmentpack, KeyToken=, Version=1.0.0.0]]
——————————————————-
This is due to a view that was created in the Monitoring Console to display the distributed application. The view have to be deleted first before the distributed application can be deleted

Tuesday, April 15, 2014

Outlook 2010 Crashes opening meetings


Here's a scenario we recently had reported: Machine running Outlook 2010 installs KB 2553248, and now Outlook crashes when they try to open meetings that were created using Exchange Web Services (EWS).
Here's the few other scenarios where Outlook crashes:

1) Create a Meeting request using EWS and send it to yourself. When you receive it in Outlook 2010 as a No Response Required meeting request, just selecting the meeting request crashes Outlook.
2) Opening the meeting in the Organizer's Calendar crashes Outlook.
3) If the attendee sends an acceptance, selecting the acceptance in the Explorer crashes Outlook.
4) Dismissing reminders crashes Outlook.

The issue is happening because there was a change made in Outlook which caused it to crash when it encounters a Time Zone property on a meeting which does not have a name. If we use MFCMAPI to dump out the properties of a Meeting we can see the problem is with PidLidAppointmentTimeZoneDefinitionStartDisplay.
 Notice that szKeyName is null.

<property tag = "0x80380102" type = "PT_BINARY"> <NamedPropGUID>{00062002-0000-0000-C000-000000000046} = PSETID_Appointment</NamedPropGUID> <NamedPropName>id: 0x825E=33374 = PidLidAppointmentTimeZoneDefinitionStartDisplay, dispidApptTZDefStartDisplay</NamedPropName> <Value>cb: 76 lpb: 000000000000000000000000000000000000000000000000000000000000000000000000000000</Value> <AltValue><![CDATA[............>...A...............ð...........................................]]> </AltValue> <SmartView><![CDATA[Time Zone Definition: bMajorVersion = 0x02 (2) bMinorVersion = 0x01 (1) cbHeader = 0x0006 (6) wReserved = 0x0002 (2) cchKeyName = 0x0000 (0) szKeyName = (null) cRules = 0x0001 (1) TZRule[0x0].bMajorVersion = 0x02 (2) TZRule[0x0].bMinorVersion = 0x01 (1) TZRule[0x0].wReserved = 0x003E (62) TZRule[0x0].wTZRuleFlags = 0x0002 = TZRULE_FLAG_EFFECTIVE_TZREG <Value>04:00:00.000 PM 5/5/2012</Value> <AltValue>Low: 0x1FE4C000 High: 0x01CD2AD8</AltValue> </property>

Fortunately, the fix is now available and included in the June 2012 CU for Office 2010.

If you're running into this issue you have a couple options:
1) Uninstall KB 2553248 (obviously).
2) Fix the Exchange Web Services code so that new meetings that are created do not crash Outlook.

What do I need to do to fix the existing code? The change is simple:

For Exchange Web Services Proxy code, remember to specify the Time Zone Name along with the Base Offset:


DateTime startTime = new DateTime(2012, 05, 05, 8, 00, 00, DateTimeKind.Unspecified); appointment.Start = startTime; appointment.End = startTime.AddHours(4); appointment.StartSpecified = appointment.EndSpecified = true; TimeZoneType tzUSMST = new TimeZoneType(); tzUSMST.TimeZoneName = "Atlantic Standard Time"; tzUSMST.BaseOffset = "PT4H"; appointment.MeetingTimeZone = tzUSMST;
For Exchange Web Services Managed API provide the TimeZone like below:


appointment.StartTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Atlantic Standard Time");

Thursday, April 10, 2014

The Infra Guys Android App

The beta version of The Infra Guys Android application is now ready for download.

This application will enable you to follow us on Facebook and get notifications whenever a new post is available.
You will be able to download the apk from the link below
The Infra Guys Apk

Do install and feel free to provide me with your honest feedback.