Src/ManagementPack.cs

using System;
using System.IO;
using System.Xml;
using System.Text;
using System.Security;
using System.Threading;
using System.Resources;
using System.Xml.XPath;
using Microsoft.CSharp;
using System.Xml.Schema;
using System.Reflection;
using System.Collections;
using System.Globalization;
using System.IO.Compression;
using System.CodeDom.Compiler;
using System.Xml.Serialization;
using System.Collections.Generic;
using System.Security.Permissions;
using System.Management.Automation;
using System.Collections.ObjectModel;
using System.Text.RegularExpressions;
using Microsoft.EnterpriseManagement;
using Microsoft.EnterpriseManagement.Common;
using Microsoft.EnterpriseManagement.Packaging;
using Microsoft.EnterpriseManagement.Configuration;
using Microsoft.EnterpriseManagement.Configuration.IO;
 
namespace SMLets
{
    #region GetSCManagementPackElement
    [Cmdlet("Get","SCManagementPackElement")]
    public class GetManagementPackElementCommand : SMCmdletBase
    {
        // Parameters
 
        private Guid _id;
        [Parameter(Position=0,Mandatory=true,ValueFromPipelineByPropertyName=true)]
        public Guid Id
        {
            get {return _id; }
            set { _id = value; }
        }
 
        protected override void ProcessRecord()
        {
            Type t = Type.GetType("Microsoft.EnterpriseManagement.Configuration.ManagementPackElementReference`1, Microsoft.EnterpriseManagement.Core, Version=7.0.5000.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
            Type [] Targs = { _mg.GetType(), typeof(Guid) };
            Type t2 = t.MakeGenericType(typeof(ManagementPackElement));
            ConstructorInfo ci = t2.GetConstructor(BindingFlags.NonPublic|BindingFlags.Instance,null,Targs,null);
            object[] myargs = { _mg, Id };
            ManagementPackElement r = ((ManagementPackElementReference<ManagementPackElement>)ci.Invoke(myargs)).GetElement();
            WriteObject(r);
        }
    }
    #endregion
 
    #region GetSCManagementPack
    // Get-ManagementPack Cmdlet
    [Cmdlet("Get","SCManagementPack",DefaultParameterSetName="Name")]
    public class GetManagementPackCommand : SMCmdletBase
    {
        // Parameters
 
        private string _name = ".*";
        [Parameter(Position=0,ValueFromPipeline=true,ParameterSetName="Name")]
        public string Name
        {
            get {return _name; }
            set { _name = value; }
        }
         
        private Guid[] _id;
        [Parameter(Position=0,ValueFromPipeline=true,ParameterSetName="ID")]
        public Guid[] Id
        {
            get { return _id; }
            set { _id = value; }
        }
 
        protected override void ProcessRecord()
        {
            if ( ParameterSetName == "Name" )
            {
                Regex r = new Regex(Name, RegexOptions.IgnoreCase);
                foreach(ManagementPack mp in _mg.ManagementPacks.GetManagementPacks())
                {
                    if ( r.Match(mp.Name).Success )
                    {
                        WriteObject(mp);
                    }
                }
            }
            if ( ParameterSetName == "ID")
            {
                foreach(Guid g in Id)
                {
                    WriteVerbose("Looking for id: " + g.ToString());
                    try
                    {
                        WriteObject(_mg.ManagementPacks.GetManagementPack(g));
                    }
                    catch ( ObjectNotFoundException e )
                    {
                        WriteError( new ErrorRecord(e, "ManagementPack id '" + g + "' does not exist", ErrorCategory.ObjectNotFound, g.ToString()) );
                    }
                    catch ( Exception e )
                    {
                        WriteError( new ErrorRecord(e, "ManagementPack id '" + g + "' does not exist", ErrorCategory.ObjectNotFound, g.ToString()) );
                    }
                }
            }
        }
    }
    #endregion
 
    #region RemoveSCManagementPack
    // Implementation of Remove-ManagementPack
    // This removes a managementpack from the system
    [Cmdlet("Remove","SCManagementPack",SupportsShouldProcess = true)]
    public class RemoveManagementPackCommand : SMCmdletBase
    {
        // Private data
        private ManagementPack _mp;
        [Parameter(Position=0,Mandatory=true,ValueFromPipeline=true)]
        public ManagementPack ManagementPack
        {
            get { return _mp; }
            set { _mp = value; }
        }
 
        protected override void ProcessRecord()
        {
            string mpInfo = _mp.Name;
            if(_mp.DisplayName != null)
            {
                mpInfo = _mp.DisplayName;
            }
            if(ShouldProcess(mpInfo))
            {
                _mg.ManagementPacks.UninstallManagementPack(ManagementPack);
            }
         
        }
    }
    #endregion
 
    #region NewSCManagementPack
    // Implementation of New-ManagementPack
    // This does not import an MP, just creates an MP object based on a file
    // which can then be used by Export-ManagementPack
    [Cmdlet(VerbsCommon.New,"SCManagementPack",DefaultParameterSetName="FromFile")]
    public class NewManagementPackCommand : SMCmdletBase
    {
        // Private data
        private FileInfo _mpFile;
        private ManagementPack _mp;
        // Parameters
        private string _fullname;
        [Parameter(Position=0,Mandatory=true,ValueFromPipelineByPropertyName=true,ParameterSetName="FromFile")]
        public string FullName
        {
            get { return _fullname; }
            set { _fullname = value; }
        }
 
        private string _managementPackName;
        [Parameter(Mandatory=true,ParameterSetName="NoFile")]
        [Alias("Name")]
        public string ManagementPackName
        {
            get { return _managementPackName; }
            set { _managementPackName = value; }
        }
 
        private string _friendlyName;
        [Parameter(ParameterSetName = "NoFile")]
        public string FriendlyName
        {
            get { return _friendlyName; }
            set { _friendlyName = value; }
        }
 
        private string _displayName;
        [Parameter(ParameterSetName = "NoFile")]
        public string DisplayName
        {
            get { return _displayName; }
            set { _displayName = value; }
        }
        /*
        private EnterpriseManagementGroup _emg;
        [Parameter(ParameterSetName = "NoFile", Mandatory = true)]
        public EnterpriseManagementGroup EMG
        {
            get { return _emg; }
            set { _emg = value; }
        }
         * */
        private Version _version;
        [Parameter(ParameterSetName = "NoFile")]
        public Version Version
        {
            get { return _version; }
            set { _version = value; }
        }
 
        private SwitchParameter _verify;
        [Parameter]
        public SwitchParameter Verify
        {
            get { return _verify; }
            set { _verify = value; }
        }
 
        private SwitchParameter _passThru;
        [Parameter]
        public SwitchParameter PassThru
        {
            get { return _passThru; }
            set { _passThru = value; }
        }
 
        private List<String> _dependencyDirectory;
        [Parameter]
        private List<String> DependencyDirectory
        {
            get { return _dependencyDirectory; }
            set { _dependencyDirectory = value; }
        }
        protected override void BeginProcessing()
        {
            base.BeginProcessing();
            if (Version == null)
            {
                Version = new Version("1.0.0.0");
            }
            DependencyDirectory = new List<String>();
        }
 
        private List<ManagementPack> ImportMPFromFile()
        {
            List<ManagementPack> mpList = new List<ManagementPack>();
            ProviderInfo providerInfo;
            foreach(string file in GetResolvedProviderPathFromPSPath(FullName,out providerInfo))
            {
                // TODO: Ensure FullName
                // Be sure to bail before the MG is created, if the FileInfo
                // can't be created, there's no reason to continue
                _mpFile = new FileInfo(file);
                if ( _mpFile.Exists )
                {
                    // Build the MP
                    try
                    {
                        ManagementPackFileStore mpStore = new ManagementPackFileStore();
                        mpStore.AddDirectory(_mpFile.Directory);
                        if ( DependencyDirectory != null )
                        {
                            foreach(string dir in DependencyDirectory ) { mpStore.AddDirectory(dir); }
                        }
                        _mp = new ManagementPack(_mpFile.FullName, mpStore);
                        mpList.Add(_mp);
                    }
                    catch (Exception e)
                    {
                        WriteError( new ErrorRecord(e, "ManagementPack creation failed", ErrorCategory.NotSpecified, _mpFile.FullName) );
                    }
                    // OK, we have an MP, call verify if needed
                    if ( Verify )
                    {
                        try
                        {
                            _mp.Verify();
                        }
                        catch (Exception e)
                        {
                            WriteError( new ErrorRecord(e, "Verification of management pack failed", ErrorCategory.NotSpecified, _mpFile.FullName));
                        }
                    }
                }
                else
                {
                    WriteError( new ErrorRecord(new FileNotFoundException(file), "Failed to create management pack", ErrorCategory.ObjectNotFound, FullName));
                }
            }
            return mpList;
        }
 
        private ManagementPack ImportMPFromName()
        {
            if (FriendlyName == null)
            {
                FriendlyName = "Friendly name for " + ManagementPackName;
            }
            _mp = new ManagementPack(ManagementPackName, FriendlyName, Version, _mg);
            ManagementPack p;
            p = _mg.ManagementPacks.GetManagementPack(SystemManagementPack.System);
            _mp.References.Add(p.Name.Replace('.', '_'), p);
            p = _mg.ManagementPacks.GetManagementPack(SystemManagementPack.Windows);
            _mp.References.Add(p.Name.Replace('.', '_'), p);
            p = _mg.ManagementPacks.GetManagementPack(SystemManagementPack.SystemCenter);
            _mp.References.Add(p.Name.Replace('.', '_'), p);
            if ( DisplayName != null )
            {
                _mp.DisplayName = DisplayName;
            }
            else
            {
                _mp.DisplayName = ManagementPackName;
            }
            _mp.AcceptChanges();
            _mg.ManagementPacks.ImportManagementPack(_mp);
            return _mp;
        }
 
        protected override void ProcessRecord()
        {
            if ( ParameterSetName == "FromFile")
            {
                foreach (ManagementPack m in ImportMPFromFile())
                {
                    if (PassThru)
                    {
                        WriteObject(m);
                    }
                }
            }
            else
            {
                ManagementPack m = ImportMPFromName();
                if (PassThru)
                {
                    WriteObject(m);
                }
            }
 
        }
    }
    #endregion
 
    #region ImportSCManagementPack
    // Implementation of Import-ManagementPack
    [Cmdlet("Import","SCManagementPack", SupportsShouldProcess=true)]
    public class ImportManagementPackCommand : SMCmdletBase
    {
        // Parameters
        private string _fullname;
        [Parameter(ParameterSetName="FullName",Position=0,Mandatory=true,ValueFromPipelineByPropertyName=true)]
        public string FullName
        {
            get { return _fullname; }
            set { _fullname = value; }
        }
 
        private ManagementPack _managementpack;
        [Parameter(ParameterSetName="MPInstance",Position=0,Mandatory=true,ValueFromPipeline=true)]
        public ManagementPack ManagementPack
        {
            get { return _managementpack; }
            set { _managementpack = value; }
        }
 
        private SwitchParameter _noTokenCheck;
        [Parameter()]
        public SwitchParameter NoTokenCheck
        {
            set { _noTokenCheck = value; }
            get { return _noTokenCheck; }
        }
 
        private SwitchParameter _noSealCheck;
        [Parameter()]
        public SwitchParameter NoSealCheck
        {
            set { _noSealCheck = value; }
            get { return _noSealCheck; }
        }
 
        private SwitchParameter _noVersionCheck;
        [Parameter()]
        public SwitchParameter NoVersionCheck
        {
            set { _noVersionCheck = value; }
            get { return _noVersionCheck; }
        }
 
        private List<ManagementPack> InstalledMPs;
        private List<ManagementPack> InstallationOrder;
        private List<ManagementPack> MPsToInstall;
        private Hashtable FailureHash = new Hashtable();
        private ManagementPackBundleReader mpbr;
         
        protected override void BeginProcessing()
        {
 
            base.BeginProcessing();
            WriteDebug("InstalledMPs");
            InstalledMPs = new List<ManagementPack>();
            foreach(ManagementPack p in _mg.ManagementPacks.GetManagementPacks())
            {
                InstalledMPs.Add(p);
            }
            WriteDebug("InstallationOrder");
            InstallationOrder = new List<ManagementPack>();
            WriteDebug("MPsToInstall");
            MPsToInstall = new List<ManagementPack>();
            // We may need this, just created it
            mpbr = ManagementPackBundleFactory.CreateBundleReader();
        }
 
        protected override void ProcessRecord()
        {
            if ( ManagementPack != null )
            {
                MPsToInstall.Add( ManagementPack );
            }
            if ( FullName != null )
            {
                ProviderInfo pi;
                foreach (string providerPath in GetResolvedProviderPathFromPSPath(FullName, out pi))
                {
                    FileInfo mpFile = ResolvePath(providerPath);
                    // FileInfo mpFile = new FileInfo(FullName);
                    if (mpFile.Exists)
                    {
                        if (mpFile.Extension.ToUpperInvariant() == ".MPB")
                        {
                            WriteVerbose("MPB: " + mpFile.FullName);
                            ManagementPackBundle mpb = mpbr.Read(mpFile.FullName, _mg);
                            if (ShouldProcess(mpFile.FullName))
                            {
                                _mg.ManagementPacks.ImportBundle(mpb);
                            }
                        }
                        else if (mpFile.Extension.ToUpperInvariant() == ".XML" || mpFile.Extension.ToUpperInvariant() == ".MP")
                        {
                            foreach (ManagementPack mp in MpFromFullName(mpFile.FullName))
                            {
                                MPsToInstall.Add(mp);
                            }
                        }
                        else
                        {
                            WriteError(new ErrorRecord(new FileLoadException(mpFile.Name),
                                "Cannot Import " + mpFile.Name + ". REASON: Bad extension",
                                ErrorCategory.InvalidType,
                                mpFile.Name));
                        }
                    }
                }
            }
        }
 
        protected override void EndProcessing()
        {
            GetInstallationOrder();
            if ( MPsToInstall.Count > 0 )
            {
                foreach ( ManagementPack mp in MPsToInstall)
                {
                    WriteError(new ErrorRecord(new FileLoadException(mp.Name),
                        "Cannot Import " + mp.Name + ". REASON: " + FailureHash[mp],
                        ErrorCategory.ObjectNotFound,
                        mp.Name));
                }
            }
            foreach(ManagementPack mp in InstallationOrder)
            {
                if(ShouldProcess("Import management pack " + mp.Name))
                {
                    _mg.ManagementPacks.ImportManagementPack(mp);
                }
            }
        }
        // TODO: REDO FOR COLLECTION
        private FileInfo ResolvePath(string potentialFile)
        {
            // this handles the case that we got a fullpath
            if ( File.Exists(potentialFile)) { return new FileInfo(potentialFile); }
            else
            {
                // go look for the file
                ProviderInfo pid;
                Collection<string> results = GetResolvedProviderPathFromPSPath(potentialFile, out pid);
                if ( results == null || results.Count == 0)
                {
                    // ok - return a fileinfo object,
                    // we know it's bad, but the code above will handle
                    return new FileInfo(potentialFile);
                }
                // BLECH!!!
                return new FileInfo(results[0]);
            }
        }
 
        private void GetInstallationOrder()
        {
            int offset = 0;
            string ReasonForFailure = "";
            while(offset < MPsToInstall.Count)
            {
                WriteDebug("OFFSET: " + offset + ", COUNT: " + MPsToInstall.Count);
                List<ManagementPackReference> mpr = new List<ManagementPackReference>();
                // List<string>keys = (List<string>)MPsToInstall[offset].References.Keys;
                // foreach(string key in keys) { mpr.Add(MPsToInstall[offset].References[key]); }
                foreach(string key in MPsToInstall[offset].References.Keys)
                {
                    mpr.Add(MPsToInstall[offset].References[key]);
                }
                bool OkToAdd = true;
                foreach(ManagementPackReference reference in mpr )
                {
                    if ( ! CheckReferenceIsInstalled(reference) )
                    {
                        ReasonForFailure = String.Format(CultureInfo.CurrentCulture, "Referenced ManagementPack '{0}' is not installed", reference.Name);
                        OkToAdd = false;
                        break;
                    }
                    else
                    {
                        if ( ! DoVersionCheck(reference) )
                        {
                            ReasonForFailure = String.Format(CultureInfo.CurrentCulture, "Version Mismatch '{0}' <> '{1}'",MPsToInstall[offset].Version,reference.Version);
                            OkToAdd = false;
                            break;
                        }
                        if ( ! CheckIsSealed(reference) )
                        {
                            ReasonForFailure = String.Format(CultureInfo.CurrentCulture, "Referenced ManagementPack '{0}' is unsealed", reference.Name);
                            OkToAdd = false;
                            break;
                        }
                        if ( ! DoKeyTokenCheck(reference) )
                        {
                            ReasonForFailure = String.Format(CultureInfo.CurrentCulture, "KeyToken Mismatch '{0}' <> '{1}'",MPsToInstall[offset].KeyToken,reference.KeyToken);
                            OkToAdd = false;
                            break;
                        }
                    }
                }
                if ( OkToAdd )
                {
                    InstallationOrder.Add(MPsToInstall[offset]);
                    InstalledMPs.Add(MPsToInstall[offset]);
                    MPsToInstall.Remove(MPsToInstall[offset]);
                    offset = 0;
                }
                else
                {
                    if ( FailureHash.ContainsKey(MPsToInstall[offset]))
                    {
                        FailureHash[MPsToInstall[offset]] = ReasonForFailure;
                    }
                    else
                    {
                        FailureHash.Add(MPsToInstall[offset], ReasonForFailure);
                    }
                    offset++;
                }
            }
        }
 
        private ManagementPack GetManagementPackByName(string name)
        {
            foreach(ManagementPack mp in InstalledMPs)
            {
                if ( mp.Name == name ) { return mp; }
            }
            return null;
        }
 
        private bool CheckReferenceIsInstalled(ManagementPackReference reference)
        {
            if ( GetManagementPackByName(reference.Name) != null) { return true; } else { return false; }
        }
        private bool DoVersionCheck(ManagementPackReference reference)
        {
            if ( NoVersionCheck ) { return true; }
            if ( (GetManagementPackByName(reference.Name).Version >= reference.Version) )
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        private bool CheckIsSealed(ManagementPackReference reference)
        {
            if ( NoSealCheck ) { return true; }
            if ( GetManagementPackByName(reference.Name).Sealed )
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        private bool DoKeyTokenCheck(ManagementPackReference reference)
        {
            if ( NoTokenCheck ) { return true; }
            if ( GetManagementPackByName(reference.Name).KeyToken == reference.KeyToken )
            {
            return true;
            }
            else
            {
            return false;
            }
        }
 
        private List<ManagementPack> MpFromFullName(string FullName)
        {
            ProviderInfo providerInfo;
            FileInfo _mpFile;
            ManagementPack _theMp;
            List<ManagementPack> mplist = new List<ManagementPack>();
            foreach(string file in GetResolvedProviderPathFromPSPath(FullName,out providerInfo))
            {
                // TODO: Ensure FullName
                // Be sure to bail before the MG is created, if the FileInfo
                // can't be created, there's no reason to continue
                _mpFile = new FileInfo(file);
                if ( _mpFile.Exists )
                {
                    // Build and import the MP
                    try
                    {
                        ManagementPackFileStore mpStore = new ManagementPackFileStore();
                        mpStore.AddDirectory(_mpFile.Directory);
                        _theMp = new ManagementPack(_mpFile.FullName, mpStore);
                        mplist.Add( _theMp );
                        // MPsToInstall.Add( _theMp );
                        // _mg.ManagementPacks.ImportManagementPack(_theMp);
                    }
                    catch (Exception e)
                    {
                        ThrowTerminatingError(
                                new ErrorRecord(e, "ManagementPack creation failed",
                                    ErrorCategory.NotSpecified, _mpFile.FullName)
                                );
                    }
                }
                else
                {
                    WriteError(
                            new ErrorRecord(new FileNotFoundException(file),
                                "Import Failed",
                                ErrorCategory.ObjectNotFound, FullName)
                            );
                }
            }
            return mplist;
        }
 
    }
    #endregion
 
    #region ExportSCManagementPack
    // Implementation of Export-ManagementPack
    [Cmdlet("Export","SCManagementPack",SupportsShouldProcess=true)]
    public class ExportManagementPackCommand : PSCmdlet
    {
        // Private data
        // Parameters
        private ManagementPack _mp;
        private string _outputFileName;
        [Parameter(Position=1,Mandatory=true,ValueFromPipeline=true)]
        public ManagementPack ManagementPack
        {
            get { return _mp; }
            set { _mp = value; }
        }
 
        private DirectoryInfo _target;
        [Parameter(Position=0,Mandatory=true)]
        public DirectoryInfo TargetDirectory
        {
            get { return _target; }
            set { _target = value; }
        }
        protected override void BeginProcessing()
        {
            if ( ! TargetDirectory.Exists )
            {
                ThrowTerminatingError(
                        new ErrorRecord((new ItemNotFoundException()), "Target Directory does not exist",
                            ErrorCategory.ObjectNotFound, TargetDirectory.FullName)
                        );
            }
        }
        protected override void ProcessRecord()
        {
            ExportPack();
        }
        private void ExportPack( )
        {
            if ( ShouldProcess("Export Management Pack " + ManagementPack.Name))
            {
                try
                {
                    WriteVerbose("exporting " + ManagementPack.Name);
                    _outputFileName = TargetDirectory + "/" + ManagementPack.Name + ".xml";
                    Stream mpStream = new FileStream(_outputFileName, FileMode.Create);
                    XmlWriter writer = XmlWriter.Create(mpStream);
                    ManagementPackXmlWriter mpWriter = new ManagementPackXmlWriter(writer);
                    mpWriter.WriteManagementPack(ManagementPack);
                    mpStream.Close();
                }
                catch ( Exception e)
                {
                    WriteError(
                            new ErrorRecord(e, "Failed to export",
                                ErrorCategory.WriteError, _outputFileName)
                            );
                }
            }
        }
    }
    #endregion
 
    #region NewSCSealedManagementPack
    /// <summary>
    /// This class is an exectuable wrapper to seal a ManagementPack
    /// </summary>
    [Cmdlet("New", "SCSealedManagementPack")]
    public class NewSealedManagementPackCommand : PSCmdlet
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        private string _fullName;
        private string _keyfilePath;
        private string _companyName;
        private string _copyright;
        private string _outputDirectory;
        private SwitchParameter _delaySign;
 
        [Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true)]
        public string FullName
        {
            get { return _fullName; }
            set { _fullName = value; }
        }
        [Parameter(Mandatory = true)]
        public string KeyFilePath
        {
            get { return _keyfilePath; }
            set { _keyfilePath = value; }
        }
        [Parameter(Mandatory = true)]
        public string CompanyName
        {
            get { return _companyName; }
            set { _companyName = value; }
        }
        [Parameter(Mandatory = true)]
        public string Copyright
        {
            get { return _copyright; }
            set { _copyright = value; }
        }
        [Parameter(Mandatory = true)]
        public string OutputDirectory
        {
            get { return _outputDirectory; }
            set { _outputDirectory = value; }
        }
        public SwitchParameter DelaySign
        {
            get { return _delaySign; }
            set { _delaySign = value; }
        }
 
        protected override void ProcessRecord()
        {
            try
            {
                if (string.IsNullOrEmpty(FullName))
                {
                    throw new ArgumentNullException("FullName");
                }
 
                //is this an Xml file?
                if (!(FullName.EndsWith(FastAssemblyWriter.XmlExtension, StringComparison.OrdinalIgnoreCase) ||
                        FullName.EndsWith(FastAssemblyWriter.MpbExtension, StringComparison.OrdinalIgnoreCase))
                    )
                {
                    ThrowTerminatingError(new ErrorRecord(null, "Invalid file extension", ErrorCategory.InvalidOperation, FullName));
                }
                if (FullName.EndsWith(FastAssemblyWriter.MpbExtension, StringComparison.OrdinalIgnoreCase))
                {
                    FastAssemblyWriter.isMpb = true;
                }
 
 
                //create the assembly writer settings object
                FastAssemblyWriterSettings settings = new FastAssemblyWriterSettings(CompanyName, KeyFilePath, DelaySign);
                settings.Copyright = Copyright;
                settings.OutputDirectory = OutputDirectory;
 
 
                //write assembly file
                FastAssemblyWriter assemblywriter = new FastAssemblyWriter(settings);
                if (FastAssemblyWriter.isMpb)
                {
                    string outfile = assemblywriter.WriteMPB(FullName);
                    WriteVerbose("ManagementPack name is " + outfile);
                }
                else
                {
                    string outfile = assemblywriter.WriteManagementPack(FullName);
                    WriteVerbose("MPB name is " + outfile);
                }
 
            }
            catch (Exception e)
            {
                ThrowTerminatingError(new ErrorRecord(e, "foo", ErrorCategory.InvalidOperation, FullName));
            }
 
        }
 
    }
    /// <summary>
    /// This class is used to create sealed ManagementPacks on disk(.DLL files)
    /// </summary>
    public class FastAssemblyWriter
    {
        #region Constructors
        public FastAssemblyWriter(FastAssemblyWriterSettings settings)
        {
            #region Validate Settings
            //validate settings
            if (settings == null)
            {
                throw new ArgumentNullException("settings");
            }
 
            //validate keyfile string
            if (string.IsNullOrEmpty(settings.KeyFilePath))
            {
                throw new ArgumentNullException("settings");
            }
 
            //validate that the specified keyfile exists
            FileInfo finfo = null;
            try
            {
                finfo = new FileInfo(settings.KeyFilePath);
            }
            catch (Exception)
            {
                throw new InvalidOperationException("settings");
            }
 
            if (finfo == null || (finfo.Exists == false))
            {
                throw new FileNotFoundException("Specified Keyfile does not exits. Cannot find file : " + settings.KeyFilePath);
            }
            #endregion
 
            this._settings = settings;
        }
        #endregion
 
 
        #region Private Members
        private FastAssemblyWriterSettings _settings = null;
        #endregion
 
        #region WriteMPB
        public string WriteMPB(string fileName)
        {
            //validate mp
            if (fileName == null)
            {
                throw new ArgumentNullException("fileName");
            }
 
            // since this is an MPB, just write it out
 
            #region Read and Compress ManagementPack Xml
            //get MP contents
            byte[] buffer = File.ReadAllBytes(fileName);
 
            //stream for compressed output
            MemoryStream msout = new MemoryStream();
 
            //compress the buffer copy
            using (MemoryStream msin = new MemoryStream(buffer))
            {
 
                //compress the management pack contents to memory
                Compress(msin, msout);
            }
            #endregion
 
            #region Write Assembly
            //write the assembly resource file
            WriteResource(msout.ToArray());
 
            //Create the Assembly
            string mpoutputfilename = String.Format("Sealed_{0}", fileName);
            return (CreateAssemblyFile(this._settings, mpoutputfilename));
            #endregion
        }
        #endregion
 
        #region WriteManagementPack Method
        /// <summary>
        /// This method creates a sealed ManagementPack (signed .NET Assembly with .DLL file extension)
        /// in the specified directory.
        ///
        /// The file name for the output file obtained from the Manifest section of ManagementPack (value of the <ID> tag)
        /// (and is not changeable)
        /// </summary>
        /// <param name="mp">The ManagementPack to write as an assembly</param>
        public string WriteManagementPack(string fileName)
        {
            //validate mp
            if (fileName == null)
            {
                throw new ArgumentNullException("fileName");
            }
 
            #region Get Information from MP
            //open document
            XPathDocument doc = null;
            doc = new XPathDocument(fileName);
            XPathNavigator nav = doc.CreateNavigator();
 
            string mpoutputfilename = string.Empty;
 
            //read Name name
            XPathNavigator namenav = nav.SelectSingleNode("/ManagementPack/Manifest/Identity/ID");
            if (namenav != null)
            {
                //set the Version field
                mpoutputfilename = namenav.Value;
            }
            else
            {
                throw new ItemNotFoundException("Cannot read ManagementPack Name from the file specified");
            }
 
            //read version
            XPathNavigator versionnav = nav.SelectSingleNode("/ManagementPack/Manifest/Identity/Version");
            if (versionnav != null)
            {
                //set the Version field
                this._settings.AssemblyVersion = new Version(versionnav.Value);
            }
            else
            {
                throw new ItemNotFoundException("Cannot read Management Pack Version from the file specified");
            }
 
            //read product name
            XPathNavigator productnav = nav.SelectSingleNode("/ManagementPack/Manifest/Name");
            if (productnav != null)
            {
                //set the Version field
                this._settings.ProductName = productnav.Value;
            }
            else
            {
                throw new ItemNotFoundException("Cannot read ManagementPack Name from the file specified");
            }
            #endregion
 
            #region Read and Compress ManagementPack Xml
            //get MP contents
            string mpcontents = nav.OuterXml;
 
            //store in a byte buffer
            byte[] buffer = Encoding.Unicode.GetBytes(mpcontents);
 
            //stream for compressed output
            MemoryStream msout = new MemoryStream();
 
            //compress the buffer copy
            using (MemoryStream msin = new MemoryStream(buffer))
            {
 
                //compress the management pack contents to memory
                Compress(msin, msout);
            }
            #endregion
 
            #region Write Assembly
            //write the assembly resource file
            WriteResource(msout.ToArray());
 
            //Create the Assembly
            return (CreateAssemblyFile(this._settings, mpoutputfilename));
            #endregion
        }
        #endregion
 
        #region Helper Methods
        private static void Compress(Stream inputstream, Stream outputstream)
        {
            //compress in 4k chunks
            byte[] buffer = new byte[ChunkSize];
            int n;
            using (GZipStream gzipCompressionStream = new GZipStream(outputstream, CompressionMode.Compress))
            {
                //read in chunks from the inputstream
                while ((n = inputstream.Read(buffer, 0, ChunkSize)) != 0)
                {
                    gzipCompressionStream.Write(buffer, 0, n);
                }
            }
        }
 
        //write out the resource file
        private static void WriteResource(byte[] mpbytes)
        {
            //write out the resource
            using (ResourceWriter resourcewriter = new ResourceWriter(FastAssemblyWriter.AssemblyManagementPackResourcePackageName))
            {
                resourcewriter.AddResource(FastAssemblyWriter.AssemblyManagementPackResourceName, mpbytes);
            }
        }
 
        //create assembly
        // [SerializableAttribute]
        // [PermissionSetAttribute(SecurityAction.InheritanceDemand, Name = "FullTrust")]
        // [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
        [PermissionSetAttribute(SecurityAction.Assert, Name = "LinkDemand")]
        private static string CreateAssemblyFile(FastAssemblyWriterSettings settings, string mpoutputname)
        {
            #region Compiler options
            //set options for assembly creation
            CompilerParameters options = new CompilerParameters();
            options.GenerateExecutable = false;
            options.GenerateInMemory = false;
            options.TreatWarningsAsErrors = false;
            options.EmbeddedResources.Add(AssemblyManagementPackResourcePackageName);
            if (isMpb)
            {
                options.OutputAssembly = Path.Combine(settings.OutputDirectory, mpoutputname + FastAssemblyWriter.MpbExtension);
            }
            else
            {
                options.OutputAssembly = Path.Combine(settings.OutputDirectory, mpoutputname + AssemblyExtension);
            }
 
            StringBuilder compilerOptions = new StringBuilder();
 
            if (settings.DelaySign)
            {
                compilerOptions.Append("/DelaySign+ ");
            }
            compilerOptions.AppendFormat("/keyfile:{0}", settings.KeyFilePath);
            options.CompilerOptions = compilerOptions.ToString();
            #endregion
 
            #region Assembly Attributes
            string[] sources = new string[1];
            //create the formatted csharp code string that sets all assembly attributes
            string AssemblyDescriptionSubstitutedSourceCode =
                String.Format(CultureInfo.CurrentCulture, AssemblyAttributesCodeTemplate, settings.AssemblyVersion.ToString(),
                settings.CompanyName,
                settings.ProductName,
                settings.Copyright);
 
            //set source csharp code to this formatted string
            sources[0] = AssemblyDescriptionSubstitutedSourceCode;
            #endregion
 
            #region Build Assembly
            //create a new code provider
            CSharpCodeProvider codeProvider = new CSharpCodeProvider();
 
            //run build
            CompilerResults cr = codeProvider.CompileAssemblyFromSource(options, sources);
 
            //any errors during compilation?
            if (cr.Errors.Count > 0)
            {
                // Display compilation errors
                StringBuilder fullErrorText = new StringBuilder();
 
                foreach (CompilerError error in cr.Errors)
                {
                    fullErrorText.AppendLine(error.ToString());
                }
 
                // throw new InvalidOperationException("ManagementPack sealing failed with error :" + fullErrorText.ToString());
                throw new InvalidOperationException(mpoutputname);
            }
 
            codeProvider.Dispose();
            return (options.OutputAssembly);
            #endregion
        }
 
        internal const int ChunkSize = 4096;
        internal const string AssemblyManagementPackResourceName = "ManagementPack";
        internal const string AssemblyManagementPackResourcePackageName = "MPResources.resources";
 
        private static string AssemblyAttributesCodeTemplate =
                @"using System.Reflection;
                  using System.Runtime.CompilerServices;
                  [assembly: AssemblyVersion(""{0}"")]
                  [assembly: AssemblyCompany(""{1}"")]
                  [assembly: AssemblyProduct(""{2}"")]
                  [assembly: AssemblyCopyright(""{3}"")]";
 
        #endregion
 
        #region File Extension constants
        internal static string XmlExtension = ".xml";
        internal static string MpbExtension = ".mpb";
        internal static string AssemblyExtension = ".mp";
        internal static bool isMpb = false;
        #endregion
 
    }
 
    /// <summary>
    /// This class is used as input to ManagementPackAssemblyWriter - to seal ManagementPacks
    /// Settings that can be specified for the ManagementPackAssemblyWriter
    /// </summary>
    public class FastAssemblyWriterSettings
    {
        /// <summary>
        /// Constructor to create a ManagementPackAssemblyWriterSettings
        /// </summary>
        /// <param name="companyName">Name of the company</param>
        /// <param name="keyFilePath">The Keypair file (.snk) that has a key pair for signing the ManagementPack assembly. Usually created with sn.exe utility from .NET Framework</param>
        /// <param name="productName">Name of the Product that this ManagementPack Monitors (including version of the product) Example: Microsoft SQL Server 2005 ManagementPack</param>
        /// <param name="delaySign">Should the assemlby be delay signed?</param>
        public FastAssemblyWriterSettings(string companyName, string keyFilePath, bool delaySign)
        {
            //validate company name
            if (string.IsNullOrEmpty(companyName))
            {
                throw new ArgumentNullException("companyName");
            }
            this.companyName = companyName;
 
            //validate keyfile path
            if (string.IsNullOrEmpty(keyFilePath))
            {
                throw new ArgumentNullException("keyFilePath");
            }
            this.keyFilePath = keyFilePath;
 
            //initalize the output directory to be the default (current) directory
            this.OutputDirectory = ".";
 
            this.delaySign = delaySign;
        }
 
 
        #region Properties
 
        /// <summary>
        /// A value of the CompanyName Assembly attribute - to set on the sealed ManagementPack Assembly
        /// </summary>
        public string CompanyName
        {
            get { return this.companyName; }
        }
 
        /// <summary>
        /// A value of the ProductName Assembly attribute - to set on the sealed ManagementPack Assembly
        /// </summary>
        public string ProductName
        {
            get { return this.productName; }
            internal set { this.productName = value; }
        }
        /// <summary>
        /// A value of the Copyright Assembly attribute - to set on the sealed ManagementPack Assembly
        /// </summary>
        public string Copyright
        {
            get { return copyright; }
            set { this.copyright = value; }
        }
 
        /// <summary>
        /// Path to the Key pair to sign the ManagementPack with
        /// </summary>
        public string KeyFilePath
        {
            get { return this.keyFilePath; }
        }
 
        /// <summary>
        /// DelaySign flag
        /// </summary>
        public bool DelaySign
        {
            get { return (this.delaySign); }
            set { this.delaySign = value; }
        }
 
        /// <summary>
        /// The directory to write the assembly out to
        /// </summary>
        public string OutputDirectory
        {
            get { return (this.outputDirectory); }
            set
            {
                this.outputDirectory = value;
 
                //validate that the specified output directory exists
                DirectoryInfo info = null;
                try
                {
                    info = new DirectoryInfo(this.outputDirectory);
                }
                catch (Exception e)
                {
                    throw new InvalidOperationException("Output directory" + this.OutputDirectory + " is not accessible", e);
                }
 
                if (info == null || (info.Exists == false))
                {
                    throw new DirectoryNotFoundException("Output directory " + this.outputDirectory + " does not exist");
                }
            }
        }
 
        /// <summary>
        /// The version of the Assembly being written
        /// </summary>
        internal Version AssemblyVersion
        {
            get { return (this.version); }
            set { this.version = value; }
        }
 
 
        #endregion
 
        #region Private Fields
        private string outputDirectory;
        private string companyName;
        private string productName;
        private string copyright;
        private string keyFilePath;
        private bool delaySign;
        private Version version;
        #endregion
 
    }
    #endregion
 
    [Cmdlet("New", "SCSMManagementPackReference")]
    public class NewSCSMManagementPackReference : SMCmdletBase
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        private string _alias;
        private ManagementPack _managementpack;
 
        [Parameter(Mandatory = true, ValueFromPipeline = false)]
        public string Alias
        {
            get { return _alias; }
            set { _alias = value; }
        }
        [Parameter(Mandatory = true, ValueFromPipeline = true)]
        public ManagementPack ManagementPack
        {
            get { return _managementpack; }
            set { _managementpack = value; }
        }
         
        protected override void ProcessRecord()
        {
            try
            {
                ManagementPackReference mpref = new ManagementPackReference(_managementpack);
                KeyValuePair<string, ManagementPackReference> kvp = new KeyValuePair<string, ManagementPackReference>(_alias, mpref);
                WriteObject(kvp);
            }
            catch (Exception e)
            {
                ThrowTerminatingError(new ErrorRecord(e, "Error", ErrorCategory.InvalidOperation, Alias));
            }
        }
    }
 
    [Cmdlet("Get", "SCSMManagementPackReference", DefaultParameterSetName="NAME")]
    public class GetSCSMManagementPackReference : SMCmdletBase
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
       
        private ManagementPack _managementpack;
 
        [Parameter(Mandatory = true, ValueFromPipeline = true)]
        public ManagementPack ManagementPack
        {
            get { return _managementpack; }
            set { _managementpack = value; }
        }
        private string [] _alias = { "*" };
        [Parameter(ParameterSetName="ALIAS")]
        [ValidateNotNullOrEmpty]
        public string [] Alias
        {
            get { return _alias; }
            set { _alias = value; }
        }
        private string [] _name = { "*" };
        [Parameter(ParameterSetName="NAME")]
        public string [] Name
        {
            get { return _name; }
            set { _name = value; }
        }
 
        protected override void ProcessRecord()
        {
            try
            {
                foreach (KeyValuePair<string,ManagementPackReference> mpref in _managementpack.References)
                {
                    if (ParameterSetName == "NAME")
                    {
                        foreach(string s in Name)
                        {
                            WildcardPattern wp = new WildcardPattern(s, WildcardOptions.CultureInvariant|WildcardOptions.IgnoreCase);
                            if ( wp.IsMatch(mpref.Value.Name) )
                            {
                                PSObject o = new PSObject(mpref.Value);
                                o.Members.Add(new PSNoteProperty("Alias", mpref.Key));
                                WriteObject(o);
                            }
                        }
                    }
                    else
                    {
                        foreach(string s in Alias)
                        {
                            WildcardPattern wp = new WildcardPattern(s, WildcardOptions.CultureInvariant|WildcardOptions.IgnoreCase);
                            if ( wp.IsMatch(mpref.Key) )
                            {
                                PSObject o = new PSObject(mpref.Value);
                                o.Members.Add(new PSNoteProperty("Alias", mpref.Key));
                                WriteObject(o);
                            }
                        }
                    }
                    // WriteObject(mpref);
                }
            }
            catch (Exception e)
            {
                ThrowTerminatingError(new ErrorRecord(e, "Error", ErrorCategory.InvalidOperation, _managementpack.Name));
            }
        }
    }
}