środa, 21 grudnia 2016

Script Displaying All Deployments for a Computer Asset



    You might have a need to identify any possible deployments, that are assigned to a particular machine in SCCM. This script will create a list of such deployments and dump it into a .csv file

Usage:
 
    Save the code below to a .ps1 file. Replace the following strings:

1. SMS_Provider_Server_FQDN - replace with an FQDN of you SMS Provider server
2. root\SMS\Site_XXX - replace the XXX with your SCCM Site code

    If you wish to add additional filter you can add additional condition here (replace XXX with the pattern you want to look up):

$Deployments = (Get-WmiObject @ConnectionObj -Query "Select * From SMS_DeploymentInfo WHERE CollectionID='$($Collection.CollectionID)' AND TargetName LIKE '%XXX%'")
 
    If you want to change the output location change the directory and a file name in the last line of the script.

Additional Notes:
 
    The script is a remake of another script found on the Internet. The original idea of the script dumping User deployments to the screen was adapted to the needs of the organization.

Code:
$ConnectionObj = @{
    ComputerName = "SMS_Provider_Server_FQDN"
    NameSpace = "root\SMS\Site_XXX"
}
$Array = @()
$Computer = Get-WMIObject @ConnectionObj -Query "Select * From SMS_R_System WHERE Name = 'XXX'"
$Collections = Get-WmiObject -Class sms_fullcollectionmembership @ConnectionObj -Filter "ResourceID = '$($Computer.resourceid)'"

Foreach ($Collection in $collections)
{                 
    $Deployments = (Get-WmiObject @ConnectionObj -Query "Select * From SMS_DeploymentInfo WHERE CollectionID='$($Collection.CollectionID)'")
    Foreach ($Deploy in $Deployments)
    {
        $Properties = @{
            ComputerName = $Computer.Name
            CollectionName = $Deploy.CollectionName
            CollectionID = $Deploy.CollectionID
            DeploymentID = $Deploy.DeploymentID
            DeploymentName = $Deploy.DeploymentName
            ApplicationName = $Deploy.TargetName
            ApplicationSubName = $Deploy.TargetSubname
        }       
        $Array += $(New-Object -TypeName PSObject -prop $Properties)
    }
}
$Array | Export-CSV -NoTypeInformation "C:\Temp\Applications.csv"

poniedziałek, 19 grudnia 2016

Advanced Troubleshooting - NLB Address for SCOM Console

Symptoms:


    After the installation of a brand new SCOM environment one of the lasts steps before handing the system over to the production was to ensure, that the SCOM Console is available for all the users via Network Load Balancing address in both Web and thick client versions. The Active Directory team set up appropriate DNS entry and the Network team set up the load balancing....

    After the configuration was completed it turned out, that even though the web console was working properly the application one behaved very strange. It was connecting properly from any place to the direct servers' FQDN addresses without any authentication prompt, but when directed to the NLB address it didn't recognize the user account and was asking for credentials. When provided with the valid ones it was throwing the following error:

Operations Manager Console error when connecting via NLB address

    The whole output of the error message is below:

====================================================
Date: 12/8/2016 5:19:09 PM
Application: Operations Manager
Application Version: 7.0.9538.1136
Severity: Error
Message: Failed to connect to server 'XXX'

Microsoft.EnterpriseManagement.Common.ServerDisconnectedException: The client has been disconnected from the server. Please call ManagementGroup.Reconnect() to reestablish the connection. ---> System.ServiceModel.ProtocolException: You have tried to create a channel to a service that does not support .Net Framing. It is possible that you are encountering an HTTP endpoint. ---> System.IO.InvalidDataException: Expected record type 'PreambleAck', found '72'.
   --- End of inner exception stack trace ---

Server stack trace:
   at System.ServiceModel.Channels.FramingDecoder.ValidatePreambleAck(FramingRecordType foundType)
   at System.ServiceModel.Channels.ClientDuplexDecoder.Decode(Byte[] bytes, Int32 offset, Int32 size)
   at System.ServiceModel.Channels.ConnectionUpgradeHelper.ValidateUpgradeResponse(Byte[] buffer, Int32 count, ClientFramingDecoder decoder)
   at System.ServiceModel.Channels.ConnectionUpgradeHelper.InitiateUpgrade(StreamUpgradeInitiator upgradeInitiator, IConnection& connection, ClientFramingDecoder decoder, IDefaultCommunicationTimeouts defaultTimeouts, TimeoutHelper& timeoutHelper)
   at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.SendPreamble(IConnection connection, ArraySegment`1 preamble, TimeoutHelper& timeoutHelper)
   at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.DuplexConnectionPoolHelper.AcceptPooledConnection(IConnection connection, TimeoutHelper& timeoutHelper)
   at System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout)
   at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
   at System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]:
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at Microsoft.EnterpriseManagement.Common.Internal.IDispatcherService.Connect(SdkClientConnectionOptions connectionOptions)
   at Microsoft.EnterpriseManagement.Common.Internal.SdkDataLayerProxyCore.Initialize(EnterpriseManagementConnectionSettings connectionSettings, SdkChannelObject`1 channelObjectDispatcherService)
   at Microsoft.EnterpriseManagement.Common.Internal.SdkDataLayerProxyCore.CreateEndpoint[T](EnterpriseManagementConnectionSettings connectionSettings, SdkChannelObject`1 channelObjectDispatcherService)
   --- End of inner exception stack trace ---
   at Microsoft.EnterpriseManagement.Common.Internal.ExceptionHandlers.HandleChannelExceptions(Exception ex)
   at Microsoft.EnterpriseManagement.Common.Internal.SdkDataLayerProxyCore.CreateEndpoint[T](EnterpriseManagementConnectionSettings connectionSettings, SdkChannelObject`1 channelObjectDispatcherService)
   at Microsoft.EnterpriseManagement.Common.Internal.SdkDataLayerProxyCore.ConstructEnterpriseManagementGroupInternal[T,P](EnterpriseManagementConnectionSettings connectionSettings, ClientDataAccessCore clientCallback)
   at Microsoft.EnterpriseManagement.Common.Internal.SdkDataLayerProxyCore.RetrieveEnterpriseManagementGroupInternal[T,P](EnterpriseManagementConnectionSettings connectionSettings, ClientDataAccessCore callbackDispatcherService)
   at Microsoft.EnterpriseManagement.Common.Internal.SdkDataLayerProxyCore.Connect[T,P](EnterpriseManagementConnectionSettings connectionSettings, ClientDataAccessCore callbackDispatcherService)
   at Microsoft.EnterpriseManagement.ManagementGroup.InternalInitialize(EnterpriseManagementConnectionSettings connectionSettings, ManagementGroupInternal internals)
   at Microsoft.EnterpriseManagement.Mom.Internal.UI.Common.ManagementGroupSessionManager.Connect(String server, String username, SecureString password, String domain)
   at Microsoft.EnterpriseManagement.Monitoring.Console.Internal.ConsoleWindowBase.ConnectWithCredentials(Exception ex, ConsoleJobEventArgs args)
System.ServiceModel.ProtocolException: You have tried to create a channel to a service that does not support .Net Framing. It is possible that you are encountering an HTTP endpoint. ---> System.IO.InvalidDataException: Expected record type 'PreambleAck', found '72'.
   --- End of inner exception stack trace ---

Server stack trace:
   at System.ServiceModel.Channels.FramingDecoder.ValidatePreambleAck(FramingRecordType foundType)
   at System.ServiceModel.Channels.ClientDuplexDecoder.Decode(Byte[] bytes, Int32 offset, Int32 size)
   at System.ServiceModel.Channels.ConnectionUpgradeHelper.ValidateUpgradeResponse(Byte[] buffer, Int32 count, ClientFramingDecoder decoder)
   at System.ServiceModel.Channels.ConnectionUpgradeHelper.InitiateUpgrade(StreamUpgradeInitiator upgradeInitiator, IConnection& connection, ClientFramingDecoder decoder, IDefaultCommunicationTimeouts defaultTimeouts, TimeoutHelper& timeoutHelper)
   at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.SendPreamble(IConnection connection, ArraySegment`1 preamble, TimeoutHelper& timeoutHelper)
   at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.DuplexConnectionPoolHelper.AcceptPooledConnection(IConnection connection, TimeoutHelper& timeoutHelper)
   at System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout)
   at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.CallOnceManager.CallOnce(TimeSpan timeout, CallOnceManager cascade)
   at System.ServiceModel.Channels.ServiceChannel.EnsureOpened(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]:
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at Microsoft.EnterpriseManagement.Common.Internal.IDispatcherService.Connect(SdkClientConnectionOptions connectionOptions)
   at Microsoft.EnterpriseManagement.Common.Internal.SdkDataLayerProxyCore.Initialize(EnterpriseManagementConnectionSettings connectionSettings, SdkChannelObject`1 channelObjectDispatcherService)
   at Microsoft.EnterpriseManagement.Common.Internal.SdkDataLayerProxyCore.CreateEndpoint[T](EnterpriseManagementConnectionSettings connectionSettings, SdkChannelObject`1 channelObjectDispatcherService)
System.IO.InvalidDataException: Expected record type 'PreambleAck', found '72'.
 ====================================================

Reason:


    The error message is very uncommon for SCOM configuration and I haven't found any trace of the similar error occurring in regards to the SCOM Console application. There is no further need to any configuration on the SCOM side of things in order to set up Console NLB. Neither firewalls seemed to be a problem, as the same behavior occurred locally on the server and moreover there was no trace of dropped traffic in the firewall logs system. However looking up particular parts of the error message provided some traces - apparently in some cases error message was caused by improper port redirection, for instance when outgoing port was different from the incoming one. That lead to the configuration of the NLB settings, which turned out to be a culprit

Resolution:

    After taking a closer look at the configuration of NLB it turned out, that even though:

1. Traffic IP group was set up correctly and was pointing to a proper NLB address
2. The Pool was configured correctly and contained all the SCOM server nodes inside
3. The Virtual Server was configured to forward port 5724

    There was a problem in the setup of Virtual Server. In general this configuration item looks as follows:

Problematic Configuration of NLB Virtual Server for SCOM Console Application

    As you can see, even though the forwarded port is properly setup to 5724, the Protocol is incorrectly configured as HTTP. It turned out this was the source of the problem. It was fixed by setting it to Generic Client First, which caused the error message to go away.

niedziela, 18 grudnia 2016

Troubleshooting - Microsoft KB3192391 crashing SCOM console

Symptoms:

    The SCOM console suddenly started crashing across the whole organization and it was not available for any of the users. It happens on all the computers - including end user workstations as well as the consoles ran directly on the Management Servers. In some cases application crashed right away after starting, in some other it was possible to browse a little bit through the menu and it would crash or freeze after a few clicks. When this happens you might observe all or some of the following error messages in the Application Event Viewer logs:


====================================================
Faulting application name: Microsoft.EnterpriseManagement.Monitoring.Console.exe, version: 7.0.9538.1123, time stamp: 0x54314363
Faulting module name: clr.dll, version: 4.0.30319.36365, time stamp: 0x579fd37e
Exception code: 0xc0000005
Fault offset: 0x00000000000919df
Faulting process id: 0x115c4
Faulting application start time: 0x01d24180b6dc8014
Faulting application path: C:\Program Files\System Center Operations Manager 2012\Console\Microsoft.EnterpriseManagement.Monitoring.Console.exe
Faulting module path: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Report Id: 35f64cec-ad74-11e6-b4f6-0030846dd8a4
Application: Microsoft.EnterpriseManagement.Monitoring.Console.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an internal error in the .NET Runtime at IP 000007FEF33019DF (000007FEF3270000) with exit code 80131506.
 ====================================================
 The program Microsoft.EnterpriseManagement.Monitoring.Console.exe version 7.0.9538.1123 stopped interacting with Windows and was closed. To see if more information about the problem is available, check the problem history in the Action Center control panel.
 Process ID: 121b0
 Start Time: 01d2418008176db6
 Termination Time: 27
 Application Path: C:\Program Files\System Center Operations Manager 2012\Console\Microsoft.EnterpriseManagement.Monitoring.Console.exe
 Report Id: f104753a-ad73-11e6-b4f6-0030846dd8a4

The protocol host process 21628 did not respond and is being forcibly terminated {filter host process 67228}.
====================================================
 Faulting application name: Microsoft.EnterpriseManagement.Monitoring.Console.exe, version: 7.0.9538.1136, time stamp: 0x559bf219

Faulting module name: KERNELBASE.dll, version: 6.1.7601.23543, time stamp: 0x57d2fe27
Exception code: 0xe0434352
Fault offset: 0x000000000001a06d
Faulting process id: 0x13a2c
Faulting application start time: 0x01d241a75ac7a3f6
Faulting application path: C:\Program Files\System Center Operations Manager 2012\Console\Microsoft.EnterpriseManagement.Monitoring.Console.exe

Faulting module path: C:\Windows\system32\KERNELBASE.dll
Report Id: dedc128e-ad9a-11e6-b4f6-0030846dd8a4
==================================================== 


Reason:

    It turns out, that this issue started approximately at the same moment, at which October 2016 cumulative updates for Windows have been deployed to the servers and workstations. The cause of the error is the installation of Security Update for Microsoft Windows (KB3192391), which has been confirmed by Microsoft here:

https://support.microsoft.com/en-us/kb/3200006


Resolution:

    In order to fix the problem you have to download and install the fix from the Microsoft Update Catalog web page:

http://www.catalog.update.microsoft.com/Search.aspx?q=3200006

Additional Notes:

     The version of the installed fix has to match the version of the operating system on which the SCOM console application is crashing

czwartek, 8 grudnia 2016

Script Inventorying Web Application Transaction Monitors' settings

    With the extensive usage of Web Application Transaction Monitors you might face a challenge of inventorying settings in order to keep them in one clear file in human readable format. I tried to approach the problem with both Operations Manager Shell and T-SQL query on the operations Manager DB, but seems like none of the information I was interested in was available in there. Therefore I came up with an idea of parsing .xml file created by export of Management Pack containing the Web Application Transaction Monitor objects. The script collects the following settings from the .xml file:

Name - containing the name of the Web Application Transaction Monitor displayed in SCOM
GUID - containing the GUID of the Web Application Transaction Monitor object
AuthenticationScheme - containing information about the way Watcher Nodes authenticate against the URL (eg. None, NTLM, Negotiate and so on)
WatcherNodesList - containing the list of FQDNs of watcher nodes (each watcher node has it's own entry under this parent property)
URLsList - containing the list of FQDNs of monitored URLs (each URL has it's own entry under this parent property)

    This data is published in the output .xml file. It looks as follows:


Web Application Transaction Monitor .xml parser output


Usage:
   
    Save the code below into the .ps1 file. You have to provide the location of the Management Pack file exported in .xml format in this line:
$MPXMLLocation = "C:\Temp\xxx.xml"
     You also need to provide the file name and the location of the output file here:
 $OutputXMLLocation = "C:\Temp\xxxReport.xml"
    Additional field to modify in the script is the one below, where you need to provide the search expresssion, if you would like to scope the report only to the applications matching it:
$ApplicationNames = $QoSMP.ManagementPack.Monitoring.Discoveries.Discovery | ?{$_.DataSource.DisplayName -match "*XXXXX*"}
    Otherwise you can modify the line to the following one:
$ApplicationNames = $QoSMP.ManagementPack.Monitoring.Discoveries.Discovery | ?{$_.DataSource.DisplayName -match "*"}


Additional Notes:
    The script can be easily modified in order to add any other properties that are of one's interest. It would require the addition of more lines in the section including Add-Member cmdlets

Code:
$MPXMLLocation = "C:\Temp\xxx.xml"
$OutputXMLLocation = "C:\Temp\xxxReport.xml"


[xml]$QoSMP = Get-Content $MPXMLLocation
$WebApplications = @()

$ApplicationNames = $QoSMP.ManagementPack.Monitoring.Discoveries.Discovery | ?{$_.DataSource.DisplayName -match "*XXXXX*"}

foreach ($ApplicationName in $ApplicationNames) {
    $object = New-Object -TypeName PSObject
    $Object | Add-Member -Name "Name" -MemberType Noteproperty -Value $ApplicationName.DataSource.DisplayName
    $Object | Add-Member -Name "GUID" -MemberType Noteproperty -Value $ApplicationName.ID.Substring(0,$ApplicationName.ID.IndexOf("."))
    $Object | Add-Member -Name "AuthenticationScheme" -MemberType Noteproperty -Value ""
    $Object | Add-Member -Name "WatcherNodesList" -MemberType Noteproperty -Value ($ApplicationName.DataSource.WatcherComputersList -replace '[()]','' -split "\|")
    $Object | Add-Member -Name "URLsList" -MemberType Noteproperty -Value ""
    $WebApplications += $object
}

foreach ($DataSourceModuleType in $QoSMP.ManagementPack.TypeDefinitions.ModuleTypes.DataSourceModuleType){
    foreach ($Application in $WebApplications){
        IF ($Application.GUID -match $DataSourceModuleType.ID.Substring(0,$DataSourceModuleType.ID.IndexOf("."))){
            $Application.AuthenticationScheme = $DataSourceModuleType.ModuleImplementation.Composite.MemberModules.ProbeAction.AuthenticationScheme
            foreach ($Request in $DataSourceModuleType.ModuleImplementation.Composite.MemberModules.ProbeAction.Requests.Request){
            $Application.URLsList += $Request.URL + "|"
        }
            $Application.URLsList = $Application.URLsList.SubString(0,$Application.URLsList.Length-1)
            $Application.URLsList = $Application.URLsList -split "\|"
        }
    }
}

($WebApplications | ConvertTo-XML -NoTypeInformation).Save($OutputXMLLocation)