Share via


Windows PowerShell Script for Detecting Location of Service Behavior Configuration

WCF 4.0 adds an ability to merge service behaviors from multiple configuration files in the configuration hierarchy. This feature makes it easier to define common behaviors at a high-level configuration file (for example, site-level web.config) and define additional behaviors at the lower configuration files. The following example illustrates how this works:

Site-level web.config

  <configuration>
    <system.serviceModel>
      <behaviors>
        <serviceBehaviors>
          <behavior name="MyBehavior">
            <serviceDebug includeExceptionDetailInFaults="True" />
            <serviceMetadata httpGetEnabled="True" />
          </behavior>
        </serviceBehaviors>
      </behaviors>
    </system.serviceModel>
  </configuration>

Application-level web.config

  <configuration>
    <system.serviceModel>
      <behaviors>
        <serviceBehaviors>
          <behavior name="MyBehavior">
            <etwTracking profileName="Troubleshooting Tracking Profile" />
          </behavior>
        </serviceBehaviors>
      </behaviors>
    </system.serviceModel>
  </configuration>

A WCF service that is inside the application and is configured to use the “MyBehavior” will effectively inherit both serviceDebug/serviceMetadata and etwTracking configuration. More details about the merged behavior configuration can be found at Behavior Merge in WCF 4.0 Configuration (https://go.microsoft.com/fwlink/?LinkId=194422) and .NET Configuration Merge Default Behavior (https://go.microsoft.com/fwlink/?LinkId=194423).

Despite the flexibility of the merged behavior configuration, it sometimes creates confusion because the service’s effective behavior configuration may be different from what defined in the local web.config. This sample demonstrates how to write a PowerShell script, in a cmdlet form, that analyzes the service behavior configuration and reports the locations of the configuration files that contain the effective settings.

Note

Samples are provided for educational purposes only. They are not intended to be used in a production environment and have not been tested in a production environment. Microsoft does not provide technical support for these samples.

Prerequisites

Users should be familiar with Windows PowerShell scripting and AppFabric cmdlets.

The sample has the following prerequisites:

  • PowerShell v2 is installed

  • Default AppFabric installation has been performed.

Sample Location and Files

The sample files include the following:

  • Readme.mhtml

  • Code\detectServiceBehaviorConfigLocation.ps1

Setting Up and Running This Sample

  1. The following example shows how to run the script cmdlet from a PowerShell console:

    PS> cd <samples>\Samples\Management\DetectServiceBehaviorConfigLocation\Code
    
    PS> . .\detectServiceBehaviorConfigLocation.ps1 #the first dot is for loading the ps1 as a function library
    
    PS> Get-ServiceBehaviorConfigLocation -SiteName "Default Web Site" -VirtualPath /App/service.svc
    
    Name                                                        Location
    ----                                                        --------
    etwTracking                                                 MACHINE/WEBROOT/APPHOST/Default Web Site
    serviceDebug                                                MACHINE/WEBROOT/APPHOST/Default Web Site/App
    serviceMetadata                                             MACHINE/WEBROOT/APPHOST/Default Web Site/App
    

    Note

    You may need to change the execution policy from ‘Restricted’ to ‘RemoteSigned’ for the sample to work.

    Note

    The Get-ServiceBehaviorConfigLocation cmdlet takes two parameters, which specify the SiteName and VirtualPath of a target service, and return a list of effective behavior configuration settings which includes configuration file locations in IIS path format.

  2. The cmdlet also accepts output from the AppFabric ’s Get-ASAppService cmdlet via the pipeline. Among other things, this allows the cmdlet to work with all services discovered under a specified scope, which is demonstrated in the next example:

    PS> Get-ASAppService -SiteName "Default Web Site" | 
          foreach-object {$service=$_; Get-ServiceBehaviorConfigLocation $service | 
          select-object @{Name="SiteName"; Expression={$service.SiteName}}, @{Name="VirtualPath"; Expression={$service.VirtualPath}}, "Name", "Location"}
    
    SiteName                      VirtualPath                   Name                          Location
    --------                      -----------                   ----                          --------
    Default Web Site              /App/service.svc            serviceDebug                  MACHINE/WEBROOT/APPHOST/De...
    Default Web Site              /App/service.svc            serviceMetadata               MACHINE/WEBROOT/APPHOST/De...
    Default Web Site              /AnotherApp/HelpRequestT... etwTracking                   MACHINE/WEBROOT
    Default Web Site              /AnotherApp/HelpRequestT... workflowInstanceManagement    MACHINE/WEBROOT
    ...
    

    A list of services found by Get-ASAppService is piped to the Get-ServiceBehaviorConfigLocation and the foreach clause is used to format the final output. Note that it adds each service’s SiteName and VirtualPath to the original result so that the services and their behavior settings can be correlated.

Removing This Sample

  1. Simply close the PowerShell session since running this sample does not modify any resources on the computer.

Demonstrates

This sample’s script has four sections:

Initialization

The first part of the script ensures that all of the dependencies are loaded. This includes loading the AppFabric cmdlet module and Microsoft.Web.Administration library for IIS configuration reading.

if ((Get-Command -Module ApplicationServer) -eq $null)
{
    Import-Module ApplicationServer
}

[System.Reflection.Assembly]::LoadFrom( "C:\windows\system32\inetsrv\Microsoft.Web.Administration.dll" ) | Out-Null

Cmdlet Function

Another goal of this sample is to demonstrate how to author a cmdlet in script instead of in code. The Get-ServiceBehaviorConfigLocation is the function that defines the cmdlet. Unlike a normal function in PowerShell scripts, it contains Param, Process, and End, for defining cmdlet parameter sets, logic for record processing, and logic for cleaning up, respectively.

In our case, this cmdlet function is only responsible for normalizing the input parameter and calls the GetBehaviorConfigLocationPerService function, which contains the main logic for detection the location of behavior configuration settings.

The Main Function

The main function GetBehaviorConfigLocationPerService first opens the configuration file at the scope of the service. The sample uses a managed code API in Microsoft.Web.Administration.dll to read configuration files in IIS configuration hierarchy. The sample finds all <behavior> elements with a matching service configuration and enumerates through all of the child elements of each one.

The function maintains a hash table ($effectiveChildElementMap) that stores the list of effective behavior setting during the enumeration. The content of the hash table evolves as the enumeration walks down the configuration hierarchy, for example a setting X will be removed if a <remove name=”X”/> element is observed. Once the enumeration is complete, the final values in the hash table will correspond to the effective behavior configuration of the service.

Helper Functions

  • FindBehaviorElementsByName - Finds all <behavior> elements with "name" attribute matching the specified name.

  • IsClearTagPresent - Determines if <clear> element is present under the specified <behavior> element.

  • IsRemoveTagPresent - Determines if <remove> element with matching "name" attribute is present under the specified <behavior> element.

Known Issues/Limitations

  • The order of <remove>/<clear> element relative the other elements under the same parent <behavior> element cannot be determined by the Microsoft.Web.Administration API. The sample assumes that the <remove> and <clear> element appear first.

  2012-09-12