El TecnoBaúl de Kiquenet

Kiquenet boring stories

Archive for 29 julio 2014

Create Windows Service With TopShelf

Posted by kiquenet en 29 julio 2014

Topshelf is an open-source hosting framework for building Windows Services using .NET. With Topshelf you can create in a few lines of code your own windows service. It’s a kind of internal DSL for building windows services.

First download Topshelf from GitHub, I used version 2.2 (direct link).

  1. Create a console application named ‘SampleWindowsService‘ inside Visual Studio
    – Be sure to change the target framework to ‘.NET Framework 4
  2. Reference the binaries TopShelf.dll and log4net.dll (included in Topshelf).
  3. Create a simple service called ‘SampleService’ that simply write every 5 seconds to the log. Note that we create explicit a Start and Stop method which is conceptually the minimum that a windows service need.

    C#

    public class SampleService

    {

    private Timer _timer = null;

    readonly ILog _log = LogManager.GetLogger(

    typeof(SampleService));

    public SampleService()

    {

    double interval = 5000;

    _timer = new Timer(interval);

    _timer.Elapsed += new ElapsedEventHandler(OnTick);

    }

    protected virtual void OnTick(object sender, ElapsedEventArgs e)

    {

    _log.Debug("Tick:" + DateTime.Now.ToLongTimeString());

    }

    public void Start()

    {

    _log.Info("SampleService is Started");

    _timer.AutoReset = true;

    _timer.Enabled = true;

    _timer.Start();

    }

    public void Stop()

    {

    _log.Info("SampleService is Stopped");

    _timer.AutoReset = false;

    _timer.Enabled = false;

    }

    }

  4. In the main method of our console application we will use Topshelf to host ourSampleService.
    We we are telling Topshelf how to start and stop the service, what the service name is, etc.
    Note that we need to configure log4net for Topshelf and our service!

    C#

    static void Main(string[] args)

    {

    XmlConfigurator.ConfigureAndWatch(new FileInfo(".\\log4net.config"));

    var host = HostFactory.New(x =>

    {

    x.EnableDashboard();

    x.Service(s =>

    {

    s.SetServiceName("SampleService");

    s.ConstructUsing(name => new SampleService());

    s.WhenStarted(tc =>

    {

    XmlConfigurator.ConfigureAndWatch(

    new FileInfo(".\\log4net.config"));

    tc.Start();

    });

    s.WhenStopped(tc => tc.Stop());

    });

    x.RunAsLocalSystem();

    x.SetDescription("SampleService Description");

    x.SetDisplayName("SampleService");

    x.SetServiceName("SampleService");

    });

    host.Run();

    }

  5. The only thing we have to do now is to configure log4net. Create a file called ‘log4net.config‘ with the following configuration.

    XHTML

    <!–?xml version="1.0" encoding="utf-8" ?–>

    This configuration enables to output to the console and through a UDP network protocol so that we can easily monitor the log statements when installed as a windows service. I used Log2Console (Codeplex) to monitor my log statements through UDP.
    – Make sure the output directory of log4net.config is set to ‘Copy always’
    – Note that there is an issue with log4net related to IPv6 and Windows Vista/7. You can fix it by adding the following ’127.0.0.1 log4view-local’ to your hosts file which can be found in folder C:\Windows\System32\drivers\etc\hosts.

When you fit F5 you will see that Topshelf outputs some log statements and you will see that the log statements of our SampleService is included and everything is working properly.

In order to install SampleService as a Windows Service you simply need to do the following through the command prompt.

Be sure to launch the command prompt as an administrator!

SampleWindowsService.exe install

After that when the windows service has been installed successfully we can start the service through services.msc or simply by typing

SampleWindowsService.exe start

Now we can open Log2Console to monitor our log files that is send through the UDP appender.


To uninstall the service we simply write

1

SampleWindowsService.exe uninstall

The sources can be found here (BitBucket)

References:
http://www.christophdebaene.com/blog/2011/03/16/create-a-net-windows-service-in-5-steps-with-topshelf/

Posted in .NET, Componentes | Etiquetado: , | Leave a Comment »

Powershell Version–What Version is installed

Posted by kiquenet en 29 julio 2014

Use $PSVersionTable.PSVersion to determine the engine version. If the variable does not exist, it is safe to assume the engine is version 1.0.

Note that $Host.Version and (Get-Host).Version are not reliable – they reflect the version of the host only, not the engine. PowerGUI, PowerShellPLUS, etc. are all hosting applications, and they will set the host’s version to reflect their product version, which is entirely correct.

PS C:\> $PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
4      0      -1     -1

$PSVersionTable is more reliable and returns $PSVersion. You can also use $PSVersionTable.PSVersion. Even if you are connected remotely to the machine running different version (invoke-command -computername myRemotePC -Credential foo {$host}), it looks like $host will just show the lowest version they agreed upon for serializing. While $PSVersionTable will show the true version

About Host vs $PSVersionTable

Get-Host or $PSVersionTable. As Andy Schneider points out, $PSVersionTable doesn’t work in version 1; it was introduced in version 2.
$host.version is just plain wrong/unreliable. This gives you the version of the hosting executable (powershell.exe, powergui.exe, powershell_ise.exe, powershellplus.exe etc) and not the version of the engine itself.

The engine version is contained in $psversiontable.psversion. For PowerShell 1.0, this variable does not exist, so obviously if this variable is not available it is entirely safe to assume the engine is 1.0, obviously.

 

Microsoft recommends checking the registry to see which version, if any, is installed
https://blogs.msdn.com/b/powershell/archive/2009/06/25/detection-logic-poweshell-installation.aspx?Redirected=true

  • To check if any version of PowerShell is installed, check for the following value in the registry:

    • Key Location: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1
    • Value Name: Install
    • Value Type: REG_DWORD
    • Value Data: 0x00000001 (1
  • To check whether version 1.0 or 2.0 of PowerShell is installed, check for the following value in the registry:
    • Key Location: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\PowerShellEngine
    • Value Name: PowerShellVersion
    • Value Type: REG_SZ
    • Value Data: <1.0 | 2.0>

Remember: 

  • Depending on any other registry key(s), or version of PowerShell.exe or the location of PowerShell.exe is not guaranteed to work in the long term.

  • PowerShell 2.0 doesn’t support side by side installations with 1.0, but 2.0 is back-wards compatible with 1.0.

To determine if PowerShell is installed, you can check the registry for the existence of HKEY_LOCAL_MACHINE\Software\Microsoft\PowerShell\1\Install and, if it exists, whether the value is 1 (for installed), as detailed in the blog post Check if PowerShell installed and version.

To determine the version of PowerShell that is installed, you can check the registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\PowerShellEngine\PowerShellVersion.

To determine the version of PowerShell that is installed from a .ps1 script, you can use the following one-liner, as detailed on PowerShell.com in Which PowerShell Version Am I Running.

For PowerScript 3.0 there seems to be a new entry,
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\3 (in addition toHKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1).


The proper place in this case for getting the version appears to be
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine\PowerShellV‌​ersion(sample value is "3.0").




$isV2 = test-path variable:\psversiontable

The same site also gives a function to return the version:

function Get-PSVersion {
    if (test-path variable:psversiontable) {$psversiontable.psversion} else {[version]"1.0.0.0"}
}

Test Powershell Version.cmd

@echo off
echo Checking powershell version...
del "%temp%\PSVers.txt" 2>nul
powershell -command "[string]$PSVersionTable.PSVersion.Major +'.'+ [string]$PSVersionTable.PSVersion.Minor | Out-File ([string](cat env:\temp) + '\PSVers.txt')" 2>nul
if errorlevel 1 (
 echo Powershell is not installed. Please install it from download.Microsoft.com; thanks.
) else (
 echo You have installed Powershell version:
 type "%temp%\PSVers.txt"
 del "%temp%\PSVers.txt" 2>nul
)
timeout 15

References:
http://stackoverflow.com/questions/1825585/how-to-determine-what-version-of-powershell-is-installed

Posted in PowerShell, Scripts | Etiquetado: , | Leave a Comment »

WMI Troubleshooting: WMIDiag

Posted by kiquenet en 28 julio 2014

WMI troubleshooting tool, WMIDIAG 2.1.

The WMI Diagnosis Tool is a VBScript based-tool for testing, validating, and analyzing WMI installation/issues. The tool collects data from WMI installations on all Microsoft Operating Systems at any or no service pack level.

WMI Diagnostics 2.1 requires you to have Local Administrator rights as well as Windows Script Host (WSH) enabled.

To download this tool, please click here.

After you download WMIDiag.exe, run it and extract the files to a local folder. If you double-click WMIDiag.vbs, the following message will appear:

clip_image001

If you want to see its activity, then you would run “cscript WMIDiag.vbs” from the command prompt.

WMIDIAG can be run from Windows Explorer, or from the command line. Each time it runs, the WMI Diagnosis Tool creates the following three files in the %TEMP% directory:

  • .LOG file containing all the WMI Diagnosis Tool activity as well as a WMI report at the end
  • .TXT file containing the WMI Diagnosis Tool report
  • .CSV file containing statistics that can be used to measure trends and issues

When the WMI Diagnosis Tool terminates, the ERRORLEVEL environment variable is set to one of the following values:

0 = SUCCESS

  • WSH has a script execution timeout setup (in machine or system environment)
  • Machine reports suspicious improper shutdowns
  • User Account Control (UAC) status is reported (Vista and above)
  • Local account token filter policy is reported (Vista and above)
  • Unexpected binaries in the WBEM folder
  • The Windows Firewall is enabled
  • Some WMI service installed in the machine are dependent on the WMI service (i.e. "SMS Agent)
  • WMI ADAP has a status different than ‘running’
  • Some WMI namespaces require a packet privacy encryption for a successful connection
  • Some WMI permanent subscriptions or timer instructions are configured
  • Some information about registry key configurations for DCOM and/or WMI was reported

1 = ERROR

  • System32 or WBEM folders are not in the PATH
  • WMI system file(s)\ repository is/are missing
  • WMI repository is inconsistent (XP SP2, 2003 SP1 and above)
  • DCOM is disabled
  • WMI service is disabled
  • The RPCSS and/or the WMI service(s) cannot be started
  • WMI DCOM setup issues
  • Expected default trustee or ACE has been removed from a DCOM or WMI security descriptor
  • The ADAP status is not available
  • One or more WMI connections failed
  • Some GET operations\WMI class MOF representations\WMI qualifier retrieval operations failed
  • Some critical WMI ENUMERATION operations\WMI EXECQUERY\WMI GET operations failed
  • Some WRITE operations in the WMI repository\PUT\DELETE operations failed
  • One of the queries of the event log entries for DCOM, WMI and WMIADAPTER failed
  • Some critical registry key configurations for DCOM and/or WMI were reported

2 = WARNING

  • System32 or WBEM folders are further in the PATH string than the maximum system length
  • System drive and/or Drive type reporting are skipped
  • DCOM has an incorrect default authentication level (other than ‘Connect’)
  • DCOM has an incorrect default impersonation level (other than ‘Identify’)
  • WMI service has an invalid host setup
  • WMI service (SCM configuration) has an invalid registry configuration
  • Some WMI components have a DCOM registration issue
  • WMI COM ProgID cannot be instantiated
  • Some WMI providers have a DCOM registration issue
  • Some dynamic WMI classes have a registration issue
  • Some WMI providers are registered in WMI but their registration lacks a CLSID
  • Some WMI providers have a correct CIM/DCOM registration but the corresponding binary file cannot be found
  • A new ACE or Trustee with a denied access has been modified to a default trustee of a DCOM or WMI security descriptor
  • An invalid ACE has been found for an actual DCOM or WMI security descriptor
  • WMI ADAP never ran on the examined system
  • Some WMI non-critical ENUMERATION operations failed\skipped
  • Some WMI non-critical EXECQUERY operations failed\skipped
  • Some non-critical WMI GET VALUE operations failed
  • Some WMI GET VALUE operations were skipped (because of an issue with the WMI provider)
  • The WRITE operations in the WMI repository were not completed
  • The information collection for the DCOM, WMI and WMIADAPTER event log entries was skipped
  • New event log entries for DCOM, WMI and WMIADAPTER were created during the WMI Diagnosis Tool execution
  • Some non-critical registry key configurations for DCOM and/or WMI were reported

3 = Command Line Parameter errors

4 = User Declined (Clicked the Cancel button when getting a consent prompt)

  • WMIDiag is started on an unsupported build or OS version
  • WMIDiag has no Administrative privileges
  • WMIDiag is started in Wow environment (64-bit systems only)

When you run the WMI Diagnosis Tool via command line:

C:\>CSCRIPT WMIDiag.vbs

clip_image003

The generated report “%TEMP%\WMIDIAG-V2.1_WIN7_.CLI.SP1.64_MYPC_2012.02.02_12.53.07-REPORT.TXT“ contains two types of figures:

  • WARNING – Information that is useful if certain actions are executed
  • ERROR – Problems that need to be solved to avoid errors reported by WMI

WMI DIAG 2.1 FAQ:

1. Where can I get the WMI Diagnosis Tool?

The WMI Diagnosis Tool can be downloaded from the Microsoft Download Center at http://www.microsoft.com/download/en/details.aspx?id=7684. More information about the WMI Diagnosis Tool usage can be found in the document (WMIDiag.doc) which comes along with the download.

2. Is it possible to “officially” engage Microsoft for feedback on this tool?

There is no official support for WMI Diagnosis Tool. However, feedback for the tool is welcome and can be sent to WMIDiag@microsoft.com.

3. Can the WMI Diagnosis Tool diagnose a remote computer?

The WMI Diagnosis Tool is not designed to diagnose remote computers. This is due to the fact that WMI remote access is mainly based on the WMI infrastructure. Because the aim of WMI Diagnosis Tool is to diagnose WMI, the WMI Diagnosis Tool does not use WMI to perform its core operations. That’s why the WMI Diagnosis Tool must be run locally. However, the WMI Diagnosis Tool can be deployed remotely using Group Policy, Systems Management Server (SMS), or Microsoft Operations Manager (MOM) via a Management Pack. With Windows Vista, the WMI Diagnosis Tool can also be remotely executed through WinRM/WinRS, provided you configure and enable these features (WinRM/WinRS are not enabled by default). Microsoft SysInternals tool PSEXEC.EXE can also be used.

4. Does the WMI Diagnosis Tool fix problems it discovers?

No. The WMI Diagnosis Tool executes in read-only mode. Even though the WMI Diagnosis Tool diagnoses the situation and provides procedures to fix problems, at no time does the tool automatically fix a problem. This is by design, because the correct repair procedure depends on the context, the usage, and the list of applications installed on the computer.

I hope this new tool will help you identifying potential WMI issues in your environment. Don’t forget to read the support document (WMIDiag.doc) included in the WMIDIAG 2.1 download. Until my next post, take care!

WMI Diagnosis Tool FAQ
http://blogs.msdn.com/b/wmi/archive/2006/05/12/wmi-diagnosis-tool-general-questions.aspx

References:
http://blogs.technet.com/b/askperf/archive/2012/02/03/wmidiag-2-1-is-here.aspx
http://joes-tech-blog.blogspot.com.es/2011/01/fixing-wmidiag-to-run-on-windows-7-and.html

Posted in Herramientas | Etiquetado: , , | Leave a Comment »

Using PowerShell to Manage Network Interfaces and Windows Services

Posted by kiquenet en 28 julio 2014

PowerShell is a new scripting language that allows you to interact with applications, services and objects as objects. It is a .NET application which shells commands out on your behalf. This is very powerful, because it allows you to leverage the strengths of an object oriented model within your scripting tasks with a very terse, yet simple scripting language. Because it is written in .NET, you can access .NET types, objects and WMI objects from a command prompt.

My current workstation runs Windows Server 2008 Standard Edition with Hyper-V. I use the host/parent partition as my office, and have a number of child partitions that are integrated into a Windows Server 2008 Domain. Needless to say, this configuration gives me everything I need to develop, test and integrate multiple Server OS’, platforms and technologies, and is my environment of choice for developing production code. It still amazes me how far we’ve come in such a short period of time. Not too long ago, I remember setting up similar lab environments at home running Windows NT 4 and Windows Server 2000 on dedicated physical machines.

Anyway, I have to say that I am absolutely delighted with my environment, but it took me some time and effort to learn how to tune Server 2008, and this is all well documented in previous posts. One of the the things that I do to keep performance high is that I only have the 3 services required for Hyper-V running when I need them. In other words, if I am only working with email and writing documents or design drawings, I don’t need to have the Hyper-V services running because they are resource intensive. In addition, I only want my loopback adapter (that provides me with a virtual LAN for all of the child partitions on my domain to communicate) enabled when I need it to be. One reason for this, is that if I leave my loopback on and reboot, boot times can take up to 10 minutes because the loopback is configured to use my domain controller as the primary DNS server, which is a VM. Because the DNS Server only runs when my Domain Controller VM  is up and running, the VM will only come up when I start it. As a result, Windows tries and tries to reach the DNS server for the Loopback adapter until it finally gives up (If anyone knows how to change this timeout, please shoot me a note or post a comment).

So, I only want Hyper-V services running when I need to work in my development environment, and I don’t want my loopback enabled unless it needs to be. For a while, I was managing this as follows…

First, I set the following services to "Manual", so that they do not start automatically:

  • vmms: Hyper-V Virtual Machine Management
  • vhdsvc: Hyper-V Image Management Service
  • nvspwmi: Hyper-V Networking Management Service

The service names are a bit obscure, but the "friendly" names are pretty self explanatory. When I need to start my development environment, I would go into Server Manager, and start each service one by one.

Next, I would enable my loopback adapter so that my child partitions can communicate with each other.

All together, this resulted in a number of clicks, which was somewhat mundane to do every time. Worse, once I enabled the loopback, I often would forget to disable it before shutting down (remember, servers running Hyper-V do not support hibernation). For a while, I thought about writing myself a sticky note and posting it to my forehead so that I would not forget to disable the loopback, and finally, I decided to create an easy button for starting and stopping my development environment.

This is where Powershell comes in.

Using PowerShell to Query and Manage Network Adapters

The first thing I did was figure out how to talk to my network adapters so that I could enable and disable my loopback as needed. It turns out that Microsoft provides a WMI object called Win32_NetworkAdapter. The object exposes a bunch of properties for working with an instance of a Win32_NetworkAdapter:

image

In addition, there are 4 public methods that are exposed, and well documented as shown below:

image

To enumerate all network adapters on my host/parent partition, I issued the following command:

   1: Get-wmiobject win32_NetworkAdapter | format-table 

PowerShell lists each adapter and certain properties in a tabular format because I added a pipe and format-table parameter:

image

To identify the instance that corresponds to my loopback, I simply need to find the "Internal VLAN" instance above, which has a DeviceID of 17:

image

Next, I want to retrieve an instance of the adapter with a DeviceId of 17, so I issue the following statement:

   1: Get-WmiObject win32_networkadapter | where {$_.DeviceId -eq 17}

The where keyword uses a bracketed expression to evaluate the condition. The "$" is a temporary variable, which is similar to the "this" keyword in C#, which provides context for the current instance. The "-eq" operator is the equality operator in PowerShell. So, we are querying all adapters for the adapter with a DeviceID equal to 17. The above command returns the following:

image

Notice that each property is an actual documented property of the WIN32_NetworkAdapter object. If we have access to properties, it would be helpful to determine if the adapter is enabled or disabled. To do this, I assign the adapter to a variable called $adapter as shown below, and then I get the value of the Availability property:

image

The value of the Availability property is 3. Referring to the WIN32_NetworkAdapter documentation, I can see that a status of 3 indicates that adapter is on, and running on full power.

image

Are you getting the hang of it yet? Hopefully, the interaction with PowerShell should feel object-oriented because it is! We are getting a reference to the WMI shell of the adapter and then using it’s get accessors to get the value of the public properties. So, if we can get a reference to the adapter, get properties, we should be able to call methods on it, right?

To disable the adapter, I simply call the Disable() method on my $adapter variable:

image

Now, to confirm that the adapter is disabled, you can look at Network Connections and you will see that the Status is in fact Disabled. To do this programmatically via PowerShell, you can use the ConfigManagerErrorCode property which is also documented. Get a new instance of the adapter, and call the ConfigManagerErrorCode property on it as shown below:

image

A return code of 22 can be matched to the table in the MSDN documentation:

image

Now, enable the adapter by calling the Enable() method:

image

A return code of 0 indicates that the adapter is enabled, and working properly:

image

As you can see, PowerShell is a very easy to use, yet powerful tool for managing system objects in an object-oriented manner. You don’t need to worry about writing VBScript or C# to accomplish simple administrative tasks such as enabling and disabling a network adapter. As you might imagine, the real power comes in being able to run a series of PowerShell commands in a batch, perhaps at the click of the button. This is exactly what I’ll cover next.

Using PowerShell to Query and Manage Windows Services

You’ll recall that I only want the 3 Hyper-V services to run when I need them, so what I want to do is create an "easy button" to toeggle my development environment on and off.

The "On" should:

  • Enable my Internal VLAN Adapter
  • Start the Hyper-V Virtual Machine Management
  • Start the Hyper-V Image Management Service
  • Start the Hyper-V Networking Management Service
  • Get me a cup of Starbucks coffee

The "Off" Button should:

  • Disable my Internal VLAN Adapter
  • Disable the Hyper-V Virtual Machine Management
  • Disable the Hyper-V Image Management Service
  • Disable the Hyper-V Networking Management Service


    I’ve already covered how to manage network adapters using PowerShell as a primer, so I’ll jump right into working with Windows Services. As with any program, sometimes it is helpful to group commands into a subroutine. In PowerShell, these functions are referred to as cmdlets (prounounced "commandlets"). You may not realize this, but you’ve already been working with cmdlets if you’ve tried the commands I covered above on your own machine. The get-wmiobject command is actually a cmdlet that provides a reference to the WMI object specified as the parameter. You could accomplish this without the cmdlet, but why would you want to?

  • Fortunately, a cmdlet is also available for working with Windows Services: get-service.

    To get information about a particular service, simply call get-service with the service name. The actual service name of the Hyper-V Virtual Machine Management service is "vmms", so issuing the get-service vmms command returns a few properties including the Name, DisplayName and Status of the service.

    image

    Starting and stopping the Hyper-V Virtual Machine Management service is as simple as calling the appropriate method: Stop() to stop the service and Start() to start it. While you could use a variable called $service to store the reference to the service object, an abbreviated way to accomplish this is shown below:

       1: (get-service vmms).Stop()

    Now, when you issue the get-service vmms command, you can see that the Status property is "Stopped":

    image

    Starting the service back up is as simple as calling Start() on the cmdlet expression:

    image

    Building the "Easy Buttons"

    There may very well be a more sophisticated way to do this, but I created two batch files, one called "Start.bat" and the other called "Stop.bat" and placed them in my documents folder. Each file contains the appropriate PowerShell syntax as shown below:

    image

    Note, to re-use variables across PowerShell sessions, you must first configure a PowerShell profile: http://msdn.microsoft.com/en-us/library/bb613488(VS.85).aspx

    Next I created two desktop shortcuts, appropriately named "Start" and "Stop" and set the target to each corresponding file.

    Now, I have two "Easy Buttons" for toggling my development environment on and off. While I can’t guarantee that I won’t forget to press the "off  button" before shutting down, it is a heck of a lot easier than going through the contortions manually.


  • References:

    http://rickgaribay.net/archive/2008/09/26/using-powershell-to-manage-network-interfaces-and-windows-services.aspx

    Posted in PowerShell, Scripts, Soporte | Etiquetado: , , | Leave a Comment »

    Powershell–Troubleshooting Group Policy – Privileges

    Posted by kiquenet en 28 julio 2014

    Useful when troubleshooting things like group policy, scripts or any other sources that may change privileges from what they should be. May generate a hash from this and automate a quick hash difference to monitor changes to privileges on systems.

    Command
    "secedit.exe", "/export /areas USER_RIGHTS /cfg $file"

    #Variables
    $computername= $env:COMPUTERNAME
    $tempdir = "c:\temp"
    $file = "$tempdir\privs.txt"
    [string] $readableNames
    $outHash = @{}

    ##### Generate report with just USER_RIGHTS ######
    $process = [diagnostics.process]::Start("secedit.exe", "/export /areas USER_RIGHTS /cfg $file")
    $process.WaitForExit()

    $in = get-content $file
    # start check of local userrights
    foreach ($line in $in) {
    if ($line.StartsWith("Se")) {
    $privilege = $line.substring(0,$line.IndexOf("=") – 1)
    $sids = $line.substring($line.IndexOf("=") + 1,$line.Length – ($line.IndexOf("=") + 1))
    $sids =  $sids.Trim() -split ","
    $readableNames = ""
    foreach ($str in $sids){
        Write-Host $str
        if ($str.StartsWith("*S-")) {
            $str = $str.substring(1) # For some reason, secedit appends a * to the SID like *S-1-5-32-544, this just strips the first character
            $sid = new-object System.Security.Principal.SecurityIdentifier($str)
            $readableName = $sid.Translate([System.Security.Principal.NTAccount])
            $readableNames = $readableNames + $readableName.Value + ","
        } else {
            $readableName = $str
            $readableNames = $readableNames + $readableName + ","
        }
      }
    $outHash.Add($privilege,$readableNames.substring(0,($readableNames.Length – 1))) #output edited version
    }
    }
    $outHash

    References:
    http://rcampi.blogspot.com.es/2011/08/powershell-ghetto-way-to-output.html

    Posted in PowerShell, Scripts | Etiquetado: , , | Leave a Comment »

    Sharepoint, Powershell, BDC Model

    Posted by kiquenet en 28 julio 2014

     

    SharePoint: Removing a BDC model via PowerShell

       In one of the previous posts I showed how to import a BDC model; the current one is about removing. The following script allows to remove a bdc model by its name:

    $model = Get-SPBusinessDataCatalogMetadataObject

    -Name "yourModelName" -BDCObjectType Model -ServiceContext "http://yourWebAppUrl"

    Remove-SPBusinessDataCatalogModel -identity $model -Confirm:$false

    Note: here command line parameters are wrapped to the next lines for readability only. In SharePoint 2010 Management Shell, each command and its parameters should be in the same line.

    The Get-SPBusinessDataCatalogMetadataObject command gets a Model object by its name and saves reference to it in the $model variable. The Model object is relevant to your web application accessible through the url http://yourWebAppUrl. As its name implies, the Remove-SPBusinessDataCatalogModelmethod removes the received model using the $model variable. -Confirm:$false allows to skip an YES/NO confirmation arising right before a model is deleted indeed. Remember that the operation isn’t reversible, use the -Confirm:$false with precaution.

    If you need to remove all bdc models, you can use the script as follows:

    $metaStore = Get-SPBusinessDataCatalogMetadataObject

    -BdcObjectType Catalog -ServiceContext "http://yourWebAppUrl"

    foreach ($model in $metaStore.GetModels("*")) {

    Remove-SPBusinessDataCatalogModel –Identity $model -Confirm:$false

    }

    Note: here command line parameters are wrapped to the next lines for readability only. In SharePoint 2010 Management Shell, each command and its parameters should be in the same line.

     

    SharePoint: Deploying a BDC model via PowerShell

        In SharePoint 2010 a BDC model can be easily deployed using PowerShell. Launch SharePoint 2010 Management Shell (click on Start, then All Programs -> Microsoft SharePoint 2010 Products ->SharePoint 2010 Management Shell) and execute the following script:

     

    $metaStore = Get-SPBusinessDataCatalogMetadataObject

    -BdcObjectType "Catalog" -ServiceContext "http://yourWebAppUrl"

    Import-SPBusinessDataCatalogModel

    -Path "c:\folder\subfolder\yourfile.bdcm" -Identity $metaStore -Force

    Note: here command line parameters are wrapped to the next lines for readability only. In SharePoint 2010 Management Shell, each command and its parameters should be in the same line.

    The first command, Get-SPBusinessDataCatalogMetadataObject, returns and saves in the $metaStorevariable a Catalog metadata object relevant to your web application accessible through the url http://yourWebAppUrl. The second command, Import-SPBusinessDataCatalogModel, imports a Business Data Connectivity Model defined in a file, path of which is indicated by the -Path key. The model is to be added to the Catalog referenced by the $metaStore and overwrites the existent version (if any) due to the -Force key.

    Despite the -Force key you can get the following error:

    Error: Cannot merge contents of LobSystem (External System) with Name 'Products'
    as it appears to be different from a preexisting LobSystem in the current load context.
    


    What you need to do in this case is remove the previous version of the model.


    References:

    http://dotnetfollower.com/wordpress/tag/business-data-connectivity/

    http://sharepoint.stackexchange.com/questions/109706/removing-a-bdc-catalog-using-powershell

    http://tmarchisio.wordpress.com/tag/business-data-catalog/

    Posted in PowerShell, Scripts, Sharepoint | Etiquetado: , , , | Leave a Comment »

    Powershell Remoting TroubleShooting

    Posted by kiquenet en 25 julio 2014

    To make sure Windows PowerShell is running with Admin rights, right-click the Windows PowerShell icon, and select Run as Administrator,

    Use the Enable-PSRemoting Windows PowerShell cmdlet to automatically configure WinRM, the firewall, and the WinRM service to enable Windows PowerShell remoting to work. If you want to be prompted before each change, do not use any switches when you run the Windows PowerShell cmdlet. If you do not want to be prompted use the force parameter as seen here.

    Enable-PSRemoting -Force

    psexec \\server -s powershell Enable-PSRemoting -Force

    Use Ping to make sure that my computer can resolve the remote host

    Invoke-Command -computername [COMPUTER} -ScriptBlock { COMMAND }

    I use the Get-Credential Windows PowerShell cmdlet to retrieve my alternative credentials

    If you are working in a networked setting and you want to enable Windows PowerShell remoting on all computers in a forest, domain, or organizational unit, you can use Group Policy to make the configuration changes. Unfortunately, there is no Enable-PSRemoting Group Policy object. The WinRM service is configurable through Group Policy and is well documented on MSDN. The Group Policy settings are seen in the following figure, Windows PowerShell remoting relies on more than just WinRM.

    One way to get the advantage of Group Policy and the advantage of using the Enable-PSRemoting cmdlet is to use Group Policy to specify a startup script. This is seen in the following figure.

    The script is a single line, saved in a .ps1 file.

    Enable-PSRemoting -Force

    Another useful commands:

    PS C:\> Enable-PSRemoting -SkipNetworkProfileCheck -Force

    PS C:\>Set-NetFirewallRule –Name "WINRM-HTTP-In-TCP-PUBLIC" –RemoteAddress Any

    About WinRM (Windows Remote Management) Troubleshooting

    WinRM uses HTTP (TCP 80) or HTTPS (TCP 443).

    http://blogs.technet.com/b/jonjor/archive/2009/01/09/winrm-windows-remote-management-troubleshooting.aspx


    Trusted Host

    On the local machine, allow connection to the remote machine without authentication:

    Set-Item WSMan:\localhost\Client\TrustedHosts -Value $remoteMachine -Force


    Solution about Error number: -2147024894 0x80070002



    D:\>winRm quickConfig

    WinRM service is already running on this machine.

    WSManFault

        Message

             ProviderFault

                 WSManFault

                         Message = Unable to check the status of the firewall.

    Error number: -2147024894 0x80070002

    The system cannot find the file specified.


    Disabled SmartScreen and Firewall and UAC, and stop MPSSVC service (Windows Firewall Service). Maybe disabled Antivirus (like Symantec Endpoint Protection u others)

    Disabled UAC

    http://superuser.com/questions/83677/disabling-uac-on-windows-7/83678#83678


    Advanced:

    http://webcache.googleusercontent.com/search?q=cache:1njaGobD9V8J:dustinhatch.tumblr.com/post/24589312635/enable-powershell-remoting-with-credssp-using-group+&cd=1&hl=es&ct=clnk&gl=es

    Manual Configuration

    Enable PowerShell Remoting Manually

    Enabling PowerShell 2.0 Remoting is simple, just run the following command from an elevated PowerShell session:

    Enable-PSRemoting -Force
    

    Once that’s done, you can start using it to execute PowerShell commands from a remote host:

    Invoke-Command -ComputerName $remotehost -Command { Write-Host "Hello, world!" }
    

    Or, you can open an interactive session on the remote computer:

    Enter-PSSession -ComputerName $remotehost
    

    Enable CredSSP Manually

    CredSSP is a Security Support Provider introduced with Windows Vista that enables credential delegation. In other words, it allows the remote host to access the credentials that were used to authenticate the user, and pass them on to a third host. For example, when using either basic or Kerberos authentication (the default) when connecting to a remote PowerShell session, the user would not have access to a separate file server. When using CredSSP, however, the session credentials can be passed through to the file server.

    To enable CredSSP, both the client and the server must be configured to allow CredSSP. To enable CredSSP on the client side, run the following PowerShell command from an elevated session:

    Enable-WSManCredSSP -Role Client -DelegateComputer $remotehost
    

    Note: The DelegateComputer parameter specifies a list of remote hosts to which the client should be allowed to connect. It can accept wildcards, such as * for all hosts, or*.mydomain.local for any host on the mydomain.local DNS domain. If you specify a domain, however, you must always use the server’s FQDN when connecting to it.

    To enable CredSSP on the server side, run the following PowerShell 2.0 command from an elevated session:

    Enable-WSManCredSSP -Role Server
    

    To connect to a remote host with PowerShell Remoting using CredSSP authentication, you need to specify the Credential and Authentication parameters:

    Enter-PSSession -ComputerName $remotehost -Credential (Get-Credential) -Authentication CredSSP
    

    Note: You must specify a fully-qualified username (such as username@domain.tld or DOMAIN\username) when prompted for credentials.

    The unfortunate drawback of using CredSSP is that the current implementation of the CredSSP provider for WinRM does not support delegating default credentials (i.e. the current user’s credentials). Go vote for Microsoft Connect Suggestion #498377 if this bothers you; hopefully Microsoft will fix it in a future release. As such, it is best to get a PSCredential object once and store it in a variable for reuse:

    $cred = Get-Credential $env:USERNAME@$env:USERDNSDOMAIN
    

    Group Policy Configuration

    Enabling PowerShell Remoting and CredSSP manually is fine for only one or two hosts, but what if it needs to be done for every machine on a network? Luckily, Group Policy is able to make all the same configuration changes the Enable-PSRemoting and Enable-WSManCredSSP cmdlets do.

    There are several configuration pieces that must be set in order for everything to work correctly:

    • The Windows Remote Management service
    • Windows Firewall exceptions
    • Credential delegation
    • WinRM Client parameters
    • WinRM Service parameters

    In addition, some Active Directory objects may need to have permissions changed.

    It is probably best to group these settings into one or two separate GPOs, one for servers and one for clients, to keep them separate from the rest of the Group Policy settings that may already exist on the network.

    Server Settings

    To enable PowerShell Remoting on the server side, create a new GPO and link it an organizational unit containing the computer objects for the server machines. Open the GPO with the Group Policy editor and set the following options:

    Windows Remote Management Service
    1. Navigate to Computer Configuration > Windows Settings > Security Settings > System Services
    2. Locate the Windows Remote Management (WS-Management) service and double-click it
    3. Tick the check box nexte to Define this policy setting and select Automatic. Click “OK”
    Windows Firewall Exceptions
    1. Navigate to Computer Configuration > Windows Settings > Security Settings> Windows Firewall with Advanced Security > Windows Firewall with Advanced Security – LDAP://{GPO-DistinguishedName} > Inbound Rules
    2. Right-click the pane at the right and choose New Rule…
    3. Select Predefined and choose Windows Remote Management from the drop-down list. Click “Next”
    4. Remove the tick next to Windows Remote Management - Compatibility Mode (HTTP-In), but leave the one for Windows Remote Management (HTTP-In). The “Compatibility Mode” rule provides an upgrade path for systems using WinRM prior to version 2.0 and should not be enabled unless there is a specific need for it. Click “Next”
    5. Select Allow the connection and click “Finish”
    WinRM Service Parameters
    1. Navigate to Computer Settings > Administrative Templates > Windows Components > Windows Remote Management (WinRM) > WinRM Service
    2. Double-click Allow automatic configuration of listeners
    3. Select Enabled
    4. In the box labeled IPv4 filter, enter a comma-separated list of IP address ranges to specify to which IP addresses the WinRM service should bind on the server. For example,192.168.1.0-192.168.1.255 would allow the WinRM service to bind to network adapters with an IP address in that range, but no other adapter.
    5. Do the same for IPv6 filter, using IPv6 addresses instead, or leave it blank to disable WinRM over IPv6
    6. Click “OK”
    7. Double-click Allow CredSSP authentication
    8. Select Enabled
    9. Click “OK”

    Client Settings

    To enable PowerShell remoting on the client side, create a new GPO and link it to an organizational unit containing the computer objects for the client machines. Open the GPO with the Group Policy editor and set the following options:

    Credential Delegation
    1. Navigate to Computer Settings > Administrative Templates > System > Credentials Delegation
    2. Double-click Allow Delegating Fresh Credentials
    3. Select Enabled
    4. Click “Show…”
    5. Enter a list of service principal names representing hosts to which clients should be allowed to delegate credentials. Wildcards are allowed in the host name portion of the SPN. For example:
      • WSMAN/Server01 — Allows delegation only to the server named Server01, and only using its single-label name
      • WSMAN/Server01.mydomain.local — Allows delegation only to the server namedServer01, and only using its fully-qualified domain name
      • WSMAN/*.mydomain.local — Allows delegation to any host on themydomain.local DNS domain, using their fully-qualified domain names only
      • WSMAN/* — Allows delegation to any host by any name
    6. Click “OK”
    7. Click “OK”
    WinRM Client Parameters
    1. Navigate to Computer Settings > Administrative Templates > Windows Components > Windows Remote Management (WinRM) > WinRM Client
    2. Double-click Allow CredSSP authentication
    3. Select Enabled
    4. Click “OK”
    5. Double-click Trusted Hosts
    6. Select Enabled
    7. In the box labeled TrustedHostList, enter a comma-separated list of hosts the client should trust. Wildcards are allowed, and there is a special <local> value meaning trust all single-label names. For example:
      • Server01 — Trust only the server named Server01, and only using its single-label name
      • server01.mydomain.local — Trust only the server named Server01, and only using its fully-qualified domain name
      • *.mydomain.local — Trust any host on the mydomain.local DNS domain, using their fully-qualified domain names only
      • <local> — Trust any host by single-label name
      • * — Trust any host by any name
    8. Click “OK”

    Troubleshooting

    Here are some common error messages and some troubleshooting tips for each:

    Operation timed out

    Enter-PSSession : Connecting to remote server failed with the following error me
    ssage : The WinRM client cannot complete the operation within the time specified
    . Check if the machine name is valid and is reachable over the network and firew
    all exception for Windows Remote Management service is enabled. For more informa
    tion, see the about_Remote_Troubleshooting Help topic.
    
    • Can you ping the machine using the same name you used for the ComputerNameparameter?
    • If the settings are defined in Group Policy, has the machine performed a policy refresh? Force one by running gpupdate /target:computer with elevated privileges
    • Does the machine have the Windows Remote Management (HTTP-In) rules enabled in Windows Firewall?
    • Is the Windows Remote Management (WS-Management) service running on the machine?

    Policy does not allow delegation of user credentials

    Enter-PSSession : Connecting to remote server failed with the following error me
    ssage : The WinRM client cannot process the request. A computer policy does not 
    allow the delegation of the user credentials to the target computer. Use gpedit.
    msc and look at the following policy: Computer Configuration -> Administrative T
    emplates -> System -> Credentials Delegation -> Allow Delegating Fresh Credentia
    ls.  Verify that it is enabled and configured with an SPN appropriate for the ta
    rget computer. For example, for a target computer name "myserver.domain.com", th
    e SPN can be one of the following: WSMAN/myserver.domain.com or WSMAN/*.domain.c
    om. For more information, see the about_Remote_Troubleshooting Help topic.
    
    • Make sure the name specified in the ComputerName parameter matches the SPN specified in the GPO. If the policy specifies a wildcard with a domain name, for example, make sure the ComputerName parameter is the fully-qualified domain name of the remote host, not just its single-label name

    The target computer is not trusted

    Enter-PSSession : Connecting to remote server failed with the following error me
    ssage : The WinRM client cannot process the request. A computer policy does not 
    allow the delegation of the user credentials to the target computer because the 
    computer is not trusted. The identity of the target computer can be verified if 
    you configure the WSMAN service to use a valid certificate using the following co
    mmand: winrm set winrm/config/service '@{CertificateThumbprint="<thumbprint>"}' 
     Or you can check the Event Viewer for an event that specifies that the followin
    g SPN could not be created: WSMAN/<computerFQDN>. If you find this event, you ca
    n manually create the SPN using setspn.exe .  If the SPN exists, but CredSSP can
    not use Kerberos to validate the identity of the target computer and you still w
    ant to allow the delegation of the user credentials to the target computer, use 
    gpedit.msc and look at the following policy: Computer Configuration -> Administr
    ative Templates -> System -> Credentials Delegation -> Allow Fresh Credentials w
    ith NTLM-only Server Authentication.  Verify that it is enabled and configured w
    ith an SPN appropriate for the target computer. For example, for a target comput
    er name "myserver.domain.com", the SPN can be one of the following: WSMAN/myserv
    er.domain.com or WSMAN/*.domain.com. Try the request again after these changes. 
    For more information, see the about_Remote_Troubleshooting Help topic.
    
    • Make sure the remote host has a Service Principal Name starting with WSMAN and matching the value specified in the ComputerName parameter. To list a host’s service principal names, run setspn -l <computername> with elevated privileges on a domain controller. If a proper SPN does not exist, try restarting the Windows Remote Management (WS-Management) service, and check the System event log for event ID 10154. If that event exists, you will need to modify permissions in Active Directory in order for hosts to be able to register their SPNs correctly (see below)
    • Make sure you are specifying a fully-qualified user name in the PSCredential object passed to the Credential parameter (i.e. DOMAIN\username orusername@domain.local)

    Modifying Active Directory Permissions

    Note: Perform these steps ONLY if you receive the “target computer is not trusted” error, Windows Remote Managment logs event ID 10154 in the System event log, and setspn -l does not list anyWSMAN/... SPNs for the remote host!

    1. Open ADSI Edit
    2. Click Action > Connect to…
    3. Under Connection Point, select Select a well known Naming Context and choose Default naming context
    4. Under Computer, select Default (Domain or server that you logged in to)
    5. If your domain controllers support it (i.e. you are running Active Directory Certificate Services), tick Use SSL-based Encryption
    6. Expand the objects in the tree at the left until you find the container containing the computer object for the server exhibiting the issue, such as CN=Computers
    7. Right-click on the container object and choose Properties
    8. Click the Security tab
    9. Click “Advanced”
    10. Click “Add…”
    11. In the box labeled Enter the name of the object to select, enter NETWORK SERVICE
    12. In the drop-down list labeled Apply to, select Descendant Computer objects
    13. Scroll all the way to the bottom of the Permissions list and tick the box in the Allow column for Validated write to service principal name
    14. Tick Apply these permissions to objects and/or containers within this container only
    15. Click “OK”
    16. Click “OK”
    17. Click “OK”
    18. Repeat steps 6-17 for any container with computer objects for hosts on which PowerShell Remoting is enabled
    19. Restart the Windows Remote Management (WS-Management) service on the affected hosts
    20. Run setspn -l <computername> with elevated privileges on a domain controller to verify that the SPN was correctly created

    winrm quickconfig 0x80070002 -2147024894

    1) We understand that you don’t have a firewall running.  Considering this, please be sure that the Windows Firewall service is started.  The Windows Firewall doesn’t need to actually be on but the service should be started.  Issues may be presented if this service can’t be checked.

    2) Enable the Analytic log for WinRM in Event Viewer.  Repro the error when running “winrm quickconfig” and look for clues in the log.

    Operational channel is enabled by default. Analytic needs to be enabled

    Use the following to show and enable Analytic log:

    •         Menu>View>Show Analytic and Debug Logs

    •         Rightclick on Analytic log and Enable Log

    3) If no clues are found in the Analytic or Operational logs, collect a WPP trace.  This trace will need to be submitted to CSS for analysis.

    WinRM WPP Traces:

    Launch a PowerShell console with the elevated admin credentials and run the following commands:

    •         Import-Module psdiagnostics

    (if you get an error that the script cant be run because of a restriction, run “set-executionpolicy unrestricted” in powershell and try again.  When finished, consider running “set-executionpolicy restricted” to restore the default setting.

    •         Enable-WSManTrace

    •         Now reproduce the problem by sending the subscription packets from the client. Continue with the next step after the problem stops.

    •         Disable-wsmantrace

    •         Send us the file %windir%\system32\wsmtraces.log

    sc config "WinRM" start= auto

    net start WinRM

    winrm create winrm/config/listener?Address=*+Transport=HTTP

    netsh firewall add portopening TCP 80 "Windows Remote Management


    Configuration Management: Powershell and XML

    https://www.simple-talk.com/dotnet/.net-framework/configuration-management-with-powershell-and-xml/?utm_source=simpletalk&utm_medium=email-main&utm_content=configurationmgmt-20140609&utm_campaign=net

    References:

    http://blogs.technet.com/b/heyscriptingguy/archive/2010/11/16/enable-powershell-remoting-to-enable-running-commands.aspx

    http://www.experts-exchange.com/OS/Microsoft_Operating_Systems/Windows/Windows_7/Q_28227386.html

    http://stackoverflow.com/questions/22908738/error-psremoting-using-session-and-credssp

    http://superuser.com/questions/646566/how-to-make-a-remote-computer-run-powershell-script-on-the-remote-computer-itsel

    http://webcache.googleusercontent.com/search?q=cache:1njaGobD9V8J:dustinhatch.tumblr.com/post/24589312635/enable-powershell-remoting-with-credssp-using-group+&cd=1&hl=es&ct=clnk&gl=es

    http://social.technet.microsoft.com/Forums/en-US/542785cb-1191-4fd0-bb7d-b248c06e2533/winrm-quickconfig-doesnt-work

    Posted in PowerShell, Scripts, Soporte | Etiquetado: , , | Leave a Comment »

    TroubleShooting Visual Studio

    Posted by kiquenet en 22 julio 2014

    For Version 10.0, 11.0, 12.0.

    Open cmd and navigate to

    C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE
    


    or

    C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE
    


    and try to type the following commands:

    1. devenv.exe /log

    2. devenv.exe /safemode

    3. devenv.exe /resetskippkgs

    4. devenv.exe /installvstemplates

    5. devenv.exe /resetsettings

    6. devenv.exe /resetuserdata

    Source : MSDN

    Posted in Soporte, VisualStudio | Etiquetado: , , | Leave a Comment »

    Sharepoint Projects and Crash VS 2012

    Posted by kiquenet en 22 julio 2014

    I get this error in my Sharepoint 2013 Project when I try Publish it (for generate WSP file)

    Problem signature:
      Problem Event Name:   CLR20r3
      Problem Signature 01: devenv.exe
      Problem Signature 02: 11.0.50727.1
      Problem Signature 03: 5011ecaa
      Problem Signature 04: Microsoft.VisualStudio.SharePoint.Project
      Problem Signature 05: 11.0.60226.0
      Problem Signature 06: 512c2dba
      Problem Signature 07: 18a8
      Problem Signature 08: 1d
      Problem Signature 09: System.NullReferenceException
      OS Version:   6.1.7601.2.1.0.274.10
      Locale ID:    2057
      Additional Information 1: 0a9e
      Additional Information 2: 0a9e372d3b4ad19135b953a78882e789
      Additional Information 3: 0a9e
      Additional Information 4: 0a9e372d3b4ad19135b953a78882e789
    1. Exe File Name
    2. Exe File assembly version number
    3. Exe File Stamp
    4. Exe file full assembly name
    5. Faulting assembly version
    6. Faulting assembly timestamp
    7. Faulting assembly method def
    8. Faulting method IL Offset within the faulting method
    9. Exception type

    And also here is a MSDN article on the same.

    Finally, I get a solution. In my csproj file, it was dissapeared Package Folder.

    Only I do this steps:

    • Edit csproj file
    • Add this nodes (for include Package folder and files)
    • Reload csproj Project
    • Publish again
    <None Include="Package\Package.package">
      <PackageId>{1c40a17c-1af5-4fce-b7ed-702badd23db3}</PackageId>
    </None>
    <None Include="Package\Package.Template.xml">
      <DependentUpon>Package.package</DependentUpon>
    </None>

    http://www.sharepointstuffs.com/fix-for-visual-studio-2012-crash-on-publish-of-sharepoint-wsp/

    Basically you need to make sure that the "site url" is not blank.

    http://stackoverflow.com/a/24858405/206730

    Posted in .NET, Sharepoint, Soporte | Etiquetado: , , , , , | Leave a Comment »

    XmlSerializer Performance issues and assembly leaks

    Posted by kiquenet en 14 julio 2014

    The problem is not new: it is well documented (section Dynamically Generated Assemblies) and there are numerous forum and blog posts about it; but still, I bumped on it again a few days ago. Some of .NET’s XmlSerializer constructors may lead to memory leaks and serious performance issues.

    public static class XmlSerializerCache
    {
        private static readonly Dictionary<string, XmlSerializer> cache =
                                new Dictionary<string, XmlSerializer>();

        public static XmlSerializer Create(Type type, XmlRootAttribute root)
        {
            var key = String.Format(
                      CultureInfo.InvariantCulture,
                      "{0}:{1}",
                      type,
                      root.ElementName);

            if (!cache.ContainsKey(key))
            {
                cache.Add(key, new XmlSerializer(type, root));
            }

            return cache[key];
        }
    }

    the XmlSerializer class documentation discusses a workaround:

    If you use any of the other constructors, multiple versions of the same assembly are generated and never unloaded, which results in a memory leak and poor performance. The easiest solution is to use one of the previously mentioned two constructors. Otherwise, you must cache the assemblies in a Hashtable,as shown in the following example.

    http://dotnetcodebox.blogspot.com.es/2013/01/xmlserializer-class-may-result-in.html
    http://luisfsgoncalves.wordpress.com/2013/04/07/nets-xmlserializer-performance-issues-and-memory-leaks/
    http://stackoverflow.com/questions/1534810/xmlserializer-performance-issue-when-specifying-xmlrootattribute
    http://mvpxml.codeplex.com/SourceControl/changeset/view/64156#258382

    Workaround for XmlSerializer assembly leaks
    http://weblogs.asp.net/cschittko/353435

    Posted in Performance | Etiquetado: , , | Leave a Comment »