示例#1
0
        public OpenImportConnectionResults OpenImportConnection(System.Collections.ObjectModel.KeyedCollection <string, ConfigParameter> configParameters, Schema types, OpenImportConnectionRunStep openImportRunStep)
        {
            Tracer.Enter("openimportconnection");
            try
            {
                Tracer.TraceInformation("getting-schema");
                try
                {
                    foreach (SchemaType type in types.Types)
                    {
                        foreach (SchemaAttribute attr in type.AnchorAttributes)
                        {
                            //Tracer.TraceInformation("{0}-anchor-attribute {1} [{2}]", type.Name, attr.Name, attr.DataType);
                            objectTypeAnchorAttributeNames.Add(type.Name, attr.Name);
                        }
                        foreach (SchemaAttribute attr in type.Attributes)
                        {
                            //Tracer.TraceInformation("{0}-attribute {1} [{2}]", type.Name, attr.Name, attr.DataType);
                        }
                    }
                    InitializeSchemaVariables(types);
                }
                catch (Exception ex)
                {
                    Tracer.TraceError("getting-schema", ex);
                }
                finally
                {
                    Tracer.TraceInformation("got-schema");
                }

                InitializeConfigParameters(configParameters);

                //SetupImpersonationToken();

                OpenRunspace();

                Tracer.TraceInformation("resetting-pipeline-results-and-counters");
                importResults = new List <PSObject>();
                pageToken     = "";

                OpenImportConnectionResults oicr = new OpenImportConnectionResults();
                ImportRunStepPageSize = openImportRunStep.PageSize;
                Tracer.TraceInformation("openimportrunstep-pagesize '{0}'", ImportRunStepPageSize);

                oicr.CustomData = openImportRunStep.ImportType == OperationType.Full ? "" : openImportRunStep.CustomData;
                Tracer.TraceInformation("openimportrunstep-customdata '{0}'", oicr.CustomData);

                importOperationType = openImportRunStep.ImportType;
                Tracer.TraceInformation("openimportrunstep-importtype '{0}'", importOperationType);

                return(oicr);
            }
            catch (Exception ex)
            {
                Tracer.TraceError("openimportconnection", ex);
                throw;
            }
            finally
            {
                Tracer.Exit("openimportconnection");
            }
        }
示例#2
0
        public GetImportEntriesResults GetImportEntries(GetImportEntriesRunStep importRunStep)
        {
            Tracer.Enter("getimportentries");
            try
            {
                #region call import script

                // if results is null, then this is the first time that we're called,
                // so call script and get pipeline object and custom data
                Tracer.TraceInformation("more-to-import '{0}'", MoreToImport);

                if (MoreToImport)
                {
                    MoreToImport = false; // make sure we set more-to-import to false; could be overwritten further down if pagedimports is true, though

                    // on first call, we set customdata to value from last successful run
                    returnedCustomData = importRunStep.CustomData;

                    Command cmd = new Command(Path.GetFullPath(ImportScript));
                    cmd.Parameters.Add(new CommandParameter("User", Username));
                    cmd.Parameters.Add(new CommandParameter("Password", Password));
                    cmd.Parameters.Add(new CommandParameter("Credentials", GetSecureCredentials()));
                    cmd.Parameters.Add(new CommandParameter("OperationType", importOperationType.ToString()));
                    cmd.Parameters.Add(new CommandParameter("UsePagedImport", UsePagedImport));
                    cmd.Parameters.Add(new CommandParameter("PageSize", ImportRunStepPageSize));
                    cmd.Parameters.Add(new CommandParameter("Schema", schemaPSObject));

                    Tracer.TraceInformation("setting-custom-data '{0}'", importRunStep.CustomData);
                    powershell.Runspace.SessionStateProxy.SetVariable("RunStepCustomData", importRunStep.CustomData);
                    Tracer.TraceInformation("setting-page-token '{0}'", pageToken);
                    powershell.Runspace.SessionStateProxy.SetVariable("PageToken", pageToken);

                    importResults = InvokePowerShellScript(cmd, null).ToList <PSObject>();

                    returnedCustomData = powershell.Runspace.SessionStateProxy.GetVariable("RunStepCustomData");
                    pageToken          = powershell.Runspace.SessionStateProxy.GetVariable("PageToken");

                    Tracer.TraceInformation("page-token-returned '{0}'", pageToken == null ? "(null)" : pageToken);
                    Tracer.TraceInformation("custom-data returned '{0}'", returnedCustomData);
                    Tracer.TraceInformation("number-of-object(s)-in-pipeline {0:n0}", importResults.Count);

                    if (UsePagedImport)
                    {
                        // Tracer.TraceError("paged-import-not-supported-currently");
                        object moreToImportObject = powershell.Runspace.SessionStateProxy.GetVariable("MoreToImport");
                        if (moreToImportObject == null)
                        {
                            Tracer.TraceError("For paged imports, the global variable 'MoreToImport' must be set to 'true' or 'false'");
                        }
                        else
                        {
                            Tracer.TraceInformation("MoreToImport-value-returned '{0}'", moreToImportObject);
                            if (bool.TryParse(moreToImportObject == null ? bool.FalseString : moreToImportObject.ToString(), out MoreToImport))
                            {
                                Tracer.TraceInformation("paged-import-setting-MoreToImport-to '{0}'", MoreToImport);
                            }
                            else
                            {
                                Tracer.TraceError("Value returned in MoreToImport must be a boolean with value of 'true' or 'false'");
                            }
                        }
                    }
                    else
                    {
                        MoreToImport = false;
                        Tracer.TraceInformation("non-paged-import-setting-MoreToImport-to '{0}'", MoreToImport);
                    }
                }
                #endregion

                #region parse returned objects
                if (importResults != null && importResults.Count > 0)
                {
                    List <PSObject> importResultsBatch = importResults.Take(ImportRunStepPageSize).ToList();
                    if (importResults.Count > ImportRunStepPageSize)
                    {
                        importResults.RemoveRange(0, importResultsBatch.Count);
                    }
                    else
                    {
                        importResults.Clear();
                    }
                    Tracer.TraceInformation("converting-objects-to-csentrychange {0:n0}", importResultsBatch.Count);
                    foreach (PSObject obj in importResultsBatch)
                    {
                        HashSet <AttributeDefinition> attrs = new HashSet <AttributeDefinition>();

                        Tracer.TraceInformation("start-connector-space-object");
                        try
                        {
                            CSEntryChange csobject = CSEntryChange.Create();

                            if (obj.BaseObject.GetType() != typeof(System.Collections.Hashtable))
                            {
                                Tracer.TraceWarning("invalid-object-in-pipeline '{0}'", 1, obj.BaseObject.GetType());
                                continue;
                            }

                            object        AnchorValue         = null;
                            string        AnchorAttributeName = null;
                            string        objectDN            = null;
                            string        objectClass         = ""; // should be string to prevent null exceptions
                            string        changeType          = null;
                            string        ErrorName           = null;
                            string        ErrorDetail         = null;
                            MAImportError ImportErrorType     = MAImportError.Success; // assume no error
                            Hashtable     hashTable           = (Hashtable)obj.BaseObject;

                            #region get control values
                            Tracer.TraceInformation("start-getting-control-values");
                            foreach (string key in hashTable.Keys)
                            {
                                if (key.Equals(Constants.ControlValues.ObjectClass, StringComparison.OrdinalIgnoreCase) || key.Equals(Constants.ControlValues.ObjectClassEx, StringComparison.OrdinalIgnoreCase))
                                {
                                    objectClass = (string)hashTable[key];
                                    Tracer.TraceInformation("got-objectclass {0}, {1}", objectClass, key);
                                    continue;
                                }
                                if (key.Equals(Constants.ControlValues.DN, StringComparison.OrdinalIgnoreCase))
                                {
                                    objectDN = (string)hashTable[key];
                                    Tracer.TraceInformation("got-dn {0}, {1}", objectDN, key);
                                    continue;
                                }
                                if (key.Equals(Constants.ControlValues.ChangeType, StringComparison.OrdinalIgnoreCase) || key.Equals(Constants.ControlValues.ChangeTypeEx, StringComparison.OrdinalIgnoreCase))
                                {
                                    changeType = (string)hashTable[key];
                                    Tracer.TraceInformation("got-changetype {0}, {1}", changeType, key);
                                    continue;
                                }
                                if (key.Equals(Constants.ControlValues.ErrorName, StringComparison.OrdinalIgnoreCase))
                                {
                                    ErrorName = (string)hashTable[key];
                                    Tracer.TraceInformation("got-errorname {0}, {1}", ErrorName, key);
                                    continue;
                                }
                                if (key.Equals(Constants.ControlValues.ErrorDetail, StringComparison.OrdinalIgnoreCase))
                                {
                                    ErrorDetail = (string)hashTable[key];
                                    Tracer.TraceInformation("got-errordetail {0}, {1}", ErrorDetail, key);
                                    continue;
                                }
                            }

                            if (string.IsNullOrEmpty(objectClass))
                            {
                                Tracer.TraceError("missing-objectclass");
                                ImportErrorType = MAImportError.ImportErrorCustomContinueRun;
                                ErrorName       = "missing-objectclass-value";
                                ErrorDetail     = "No value provided for objectclass attribute";
                            }
                            else
                            {
                                AnchorAttributeName = objectTypeAnchorAttributeNames[objectClass] == null ? "" : (string)objectTypeAnchorAttributeNames[objectClass];
                                if (string.IsNullOrEmpty(AnchorAttributeName))
                                {
                                    ImportErrorType = MAImportError.ImportErrorInvalidAttributeValue;
                                    ErrorName       = "invalid-objecttype";
                                    ErrorDetail     = "Objecttype not defined in schema";
                                }

                                foreach (string key in hashTable.Keys)
                                {
                                    if (key.Equals(AnchorAttributeName, StringComparison.OrdinalIgnoreCase))
                                    {
                                        AnchorValue = hashTable[key];
                                        Tracer.TraceInformation("got-anchor {0}, {1}", AnchorValue, key);
                                        break;
                                    }
                                }
                            }
                            Tracer.TraceInformation("end-getting-control-values");

                            if (AnchorValue == null)
                            {
                                Tracer.TraceError("missing-anchor");
                                ImportErrorType = MAImportError.ImportErrorCustomContinueRun;
                                ErrorName       = "missing-anchor-value";
                                ErrorDetail     = "No value provided for anchor attribute";
                            }

                            if (AnchorValue != null && string.IsNullOrEmpty(objectDN))
                            {
                                Tracer.TraceInformation("setting-anchor-as-dn {0}", AnchorValue);
                                objectDN = AnchorValue.ToString();
                            }

                            if (!string.IsNullOrEmpty(ErrorName))
                            {
                                ImportErrorType = MAImportError.ImportErrorCustomContinueRun;
                                if (string.IsNullOrEmpty(ErrorDetail))
                                {
                                    ErrorDetail = "No error details provided";
                                }
                            }
                            #endregion control values

                            #region return invalid object
                            if (ImportErrorType != MAImportError.Success)
                            {
                                Tracer.TraceInformation("returning-invalid-object");
                                if (AnchorValue != null)
                                {
                                    csobject.AnchorAttributes.Add(AnchorAttribute.Create(AnchorAttributeName, AnchorValue));
                                }
                                csobject.ObjectModificationType = ObjectModificationType.Add;
                                if (!string.IsNullOrEmpty(objectClass))
                                {
                                    try
                                    {
                                        csobject.ObjectType = objectClass;
                                    }
                                    catch (NoSuchObjectTypeException otEx)
                                    {
                                        Tracer.TraceError("no-such-object '{0}'", otEx);
                                    }
                                }
                                if (!string.IsNullOrEmpty(objectClass))
                                {
                                    csobject.DN = objectDN;
                                }
                                Tracer.TraceError("invalid-object dn: {0}, type: {1}, name: {2}, details: {3} ", objectDN, ImportErrorType, ErrorName, ErrorDetail);
                                csobject.ErrorCodeImport = ImportErrorType;
                                csobject.ErrorName       = ErrorName;
                                csobject.ErrorDetail     = ErrorDetail;
                                csentryqueue.Add(csobject);
                                continue;
                            }
                            #endregion

                            #region return deleted object
                            // we must set ObjectModificationType before any other attributes; otherwise it will default to 'Add'
                            if (!string.IsNullOrEmpty(changeType) && changeType.Equals("delete", StringComparison.OrdinalIgnoreCase))
                            {
                                Tracer.TraceInformation("returning-deleted-object");
                                Tracer.TraceInformation("change-type {0}", changeType);
                                csobject.ObjectModificationType = ObjectModificationType.Delete;
                                csobject.ObjectType             = objectClass;
                                csobject.DN = objectDN;

                                // we need to get the object anchor value for the deletion
                                csobject.AnchorAttributes.Add(AnchorAttribute.Create(AnchorAttributeName, AnchorValue));
                                csentryqueue.Add(csobject);
                                continue;
                            }
                            #endregion

                            #region returned live object
                            Tracer.TraceInformation("returning-valid-object");
                            csobject.ObjectModificationType = ObjectModificationType.Add;
                            csobject.ObjectType             = objectClass;
                            csobject.DN = objectDN;
                            csobject.AnchorAttributes.Add(AnchorAttribute.Create(AnchorAttributeName, AnchorValue));
                            foreach (string key in hashTable.Keys)
                            {
                                try
                                {
                                    if (Regex.IsMatch(key, string.Format(@"^(objectClass|\[objectclass\]|changeType|\[changetype\]|\[DN\]|\[ErrorName\]|\[ErrorDetail\]|{0})$", AnchorAttributeName), RegexOptions.Compiled | RegexOptions.IgnoreCase))
                                    {
                                        Tracer.TraceInformation("skip-control-value {0}", key);
                                        continue;
                                    }
                                    if (hashTable[key] == null)
                                    {
                                        Tracer.TraceInformation("skip-null-value-for '{0}'", key);
                                        continue;
                                    }
                                    SchemaAttribute sa = schema.Types[objectClass].Attributes[key];
                                    Tracer.TraceInformation("attribute: {0} (type {1}, {2}): '{3}'", key, sa.DataType, sa.IsMultiValued ? "multi-value" : "single-value", hashTable[key]);
                                    if (sa.IsMultiValued)
                                    {
                                        //Tracer.TraceInformation("add-multivalue '{0}' [{1}]", key, hashTable[key].GetType());
                                        List <object> mvs = new List <object>();
                                        if (hashTable[key].ToString().EndsWith("[]"))
                                        {
                                            mvs.AddRange((object[])hashTable[key]);
                                        }
                                        else
                                        {
                                            mvs.Add(hashTable[key]);
                                        }
                                        csobject.AttributeChanges.Add(AttributeChange.CreateAttributeAdd(key, mvs));
                                    }
                                    else
                                    {
                                        csobject.AttributeChanges.Add(AttributeChange.CreateAttributeAdd(key, hashTable[key]));
                                    }
                                }
                                catch (KeyNotFoundException keyexception)
                                {
                                    Tracer.TraceError("attribute-is-not-defined-for '{0}' / '{1}' ({2})", key, objectClass, keyexception.ToString());
                                }
                            }
                            #endregion

                            if (csobject.ErrorCodeImport != MAImportError.Success)
                            {
                                Tracer.TraceError("defective-csentrychange id: {0}, dn: {1}, errorcode: {2}, error: {3}, details: {4}", csobject.Identifier, csobject.DN, csobject.ErrorCodeImport, csobject.ErrorName, csobject.ErrorDetail);
                            }
                            Tracer.TraceInformation("returning-csentry dn: {0}, id: {1}", csobject.DN, csobject.Identifier);
                            csentryqueue.Add(csobject);
                        }
                        catch (Exception ex)
                        {
                            Tracer.TraceError("creating-csentrychange", ex);
                        }
                        finally
                        {
                            Tracer.TraceInformation("end-connector-space-object");
                        }
                    }
                    // clearing results for next loop
                    importResultsBatch.Clear();
                }
                #endregion

                #region dequeue csentries

                GetImportEntriesResults importReturnInfo = null;

                Tracer.TraceInformation("total-import-object(s)-left {0:n0}", importResults.Count);
                Tracer.TraceInformation("total-connector-space-object(s)-left {0:n0}", csentryqueue.Count);

                List <CSEntryChange> batch = csentryqueue.Take(ImportRunStepPageSize).ToList();
                if (csentryqueue.Count > ImportRunStepPageSize)
                {
                    csentryqueue.RemoveRange(0, batch.Count);
                }
                else
                {
                    csentryqueue.Clear();
                }
                importReturnInfo = new GetImportEntriesResults();
                importReturnInfo.MoreToImport = MoreToImport || importResults.Count > 0 || (csentryqueue.Count > 0);
                importReturnInfo.CustomData   = returnedCustomData == null ? "" : returnedCustomData.ToString();
                importReturnInfo.CSEntries    = batch;

                Tracer.TraceInformation("should-return-for-more {0}", importReturnInfo.MoreToImport);
                Tracer.TraceInformation("custom-data '{0}'", importReturnInfo.CustomData);
                Tracer.TraceInformation("connector-space-object(s)-returned {0:n0}", importReturnInfo.CSEntries.Count);

                return(importReturnInfo);

                #endregion
            }
            catch (Exception ex)
            {
                Tracer.TraceError("getimportentries", ex);
                throw;
            }
            finally
            {
                Tracer.Exit("getimportentries");
            }
        }
示例#3
0
        Schema IMAExtensible2GetSchema.GetSchema(KeyedCollection <string, ConfigParameter> configParameters)
        {
            Tracer.Enter("getschema");
            try
            {
                Schema schema = Schema.Create();
                InitializeConfigParameters(configParameters);

                OpenRunspace();
                Command cmd = new Command(Path.GetFullPath(SchemaScript));
                cmd.Parameters.Add(new CommandParameter("Username", Username));
                cmd.Parameters.Add(new CommandParameter("Password", Password));
                cmd.Parameters.Add(new CommandParameter("ClientId", ClientId));
                cmd.Parameters.Add(new CommandParameter("Secret", Secret));
                cmd.Parameters.Add(new CommandParameter("Credentials", GetSecureCredentials()));
                cmd.Parameters.Add(new CommandParameter("ClientCredentials", GetSecureClientCredentials()));
                schemaResults = InvokePowerShellScript(cmd, null);
                CloseRunspace();

                if (schemaResults != null)
                {
                    foreach (PSObject obj in schemaResults)
                    {
                        string objectTypeName = null;
                        HashSet <AttributeDefinition> attrs = new HashSet <AttributeDefinition>();

                        foreach (PSPropertyInfo p in obj.Properties)
                        {
                            string[] elements = p.Name.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
                            string   attrName = elements[0].Trim();
                            string   attrType = elements[1].Trim();

                            if (string.Equals(attrName, Constants.ControlValues.ObjectClass, StringComparison.OrdinalIgnoreCase))
                            {
                                objectTypeName = p.Value.ToString();
                                Tracer.TraceInformation("object-class '{0}'", objectTypeName);
                            }
                            else
                            {
                                AttributeDefinition ad = new AttributeDefinition();
                                ad.Name         = Regex.Replace(attrName, "^Anchor-", "", RegexOptions.IgnoreCase);
                                ad.IsAnchor     = p.Name.StartsWith("anchor-", StringComparison.OrdinalIgnoreCase);
                                ad.IsMultiValue = p.Name.EndsWith("[]", StringComparison.OrdinalIgnoreCase);
                                switch (attrType.Replace("[]", "").ToLower())
                                {
                                case "boolean":
                                    ad.Type = AttributeType.Boolean;
                                    break;

                                case "binary":
                                    ad.Type = AttributeType.Binary;
                                    break;

                                case "integer":
                                    ad.Type = AttributeType.Integer;
                                    break;

                                case "reference":
                                    ad.Type = AttributeType.Reference;
                                    break;

                                case "string":
                                    ad.Type = AttributeType.String;
                                    break;

                                default:
                                    ad.Type = AttributeType.String;
                                    break;
                                }
                                Tracer.TraceInformation("name '{0}', isanchor: {1}, ismultivalue: {2}, type: {3}", ad.Name, ad.IsAnchor, ad.IsMultiValue, ad.Type.ToString());
                                attrs.Add(ad);
                            }
                        }
                        if (string.IsNullOrEmpty(objectTypeName))
                        {
                            Tracer.TraceError("missing-object-class");
                            throw new Microsoft.MetadirectoryServices.NoSuchObjectTypeException();
                        }

                        SchemaType objectClass = SchemaType.Create(objectTypeName, true);
                        foreach (AttributeDefinition def in attrs)
                        {
                            if (def.IsAnchor)
                            {
                                objectClass.Attributes.Add(SchemaAttribute.CreateAnchorAttribute(def.Name, def.Type));
                            }
                            else
                            {
                                if (def.IsMultiValue)
                                {
                                    objectClass.Attributes.Add(SchemaAttribute.CreateMultiValuedAttribute(def.Name, def.Type));
                                }
                                else
                                {
                                    objectClass.Attributes.Add(SchemaAttribute.CreateSingleValuedAttribute(def.Name, def.Type));
                                }
                            }
                        }
                        if (objectClass.AnchorAttributes.Count == 1)
                        {
                            schema.Types.Add(objectClass);
                        }
                        else
                        {
                            Tracer.TraceError("missing-anchor-definition-on-object");
                            throw new Microsoft.MetadirectoryServices.AttributeNotPresentException();
                        }
                    }
                }
                schemaResults.Clear();
                return(schema);
            }
            catch (Exception ex)
            {
                Tracer.TraceError("getschema", ex);
                throw;
            }
            finally
            {
                Tracer.Exit("getschema");
            }
        }
示例#4
0
        Collection <PSObject> InvokePowerShellScript(Command command, PSDataCollection <PSObject> pipelineInput)
        {
            Tracer.Enter("invokepowershellscript");
            SetupImpersonationToken();

            Collection <PSObject> results = new Collection <PSObject>();

            try
            {
                try
                {
                    powershell.Streams.ClearStreams();
                    powershell.Commands.Clear();
                    powershell.Commands.AddCommand(command);

                    if (pipelineInput != null)
                    {
                        Tracer.TraceInformation("pipeline-object-count {0:n0}", pipelineInput.Count);
                    }
                    //if (ShouldImpersonate())
                    //{
                    //	using (WindowsIdentity.Impersonate(impersonationToken))
                    //	{
                    //		Tracer.TraceInformation("start-invoke-script {0}", command.CommandText);
                    //		if (pipelineInput != null)
                    //		{
                    //			powershell.Invoke(pipelineInput, results);
                    //		}
                    //		else
                    //		{
                    //			powershell.Invoke(null, results);
                    //		}
                    //	}
                    //}
                    //else
                    //{

                    Tracer.TraceInformation("start-invoke-script {0}", command.CommandText);
                    if (pipelineInput != null)
                    {
                        powershell.Invoke(pipelineInput, results);
                    }
                    else
                    {
                        powershell.Invoke(null, results);
                    }
                    //}
                    Tracer.TraceInformation("end-invoke-script {0}", command.CommandText);
                }
                catch (RuntimeException e)
                {
                    Tracer.TraceError("script-invocation-error", e);
                    Tracer.TraceError("script-invocation-inner-exception", e.InnerException != null ? e.InnerException : e);
                    Tracer.TraceError("script-invocation-inner-exception-message", e.InnerException != null ? e.InnerException.Message : "n/a");
                    Tracer.TraceError("script-invocation-error-stacktrace", e.StackTrace);
                    throw;
                }
                finally
                {
                    Tracer.TraceInformation("script-had-errors {0}", powershell.HadErrors);
                }
            }
            catch (Exception ex)
            {
                Tracer.TraceError("invokepowershellscript", ex);
                throw;
            }
            finally
            {
                RevertImpersonation();
                Tracer.Exit("invokepowershellscript");
            }
            return(results);
        }
示例#5
0
        static void Error_DataAdded(object sender, DataAddedEventArgs e)
        {
            PSDataCollection <ErrorRecord> err = (PSDataCollection <ErrorRecord>)sender;

            Tracer.TraceError("error id: {0}, message: {1}", err[e.Index].Exception == null ? -1 : err[e.Index].Exception.HResult, err[e.Index].FullyQualifiedErrorId, err[e.Index].ToString());
        }
示例#6
0
        void OpenRunspace()
        {
            Tracer.Enter("openrunspace");
            try
            {
                if (runspace == null)
                {
                    Tracer.TraceInformation("creating-runspace");
                    runspace = RunspaceFactory.CreateRunspace();
                    runspace.ApartmentState       = System.Threading.ApartmentState.STA;
                    runspace.ThreadOptions        = PSThreadOptions.Default;
                    runspace.StateChanged        += Runspace_StateChanged;
                    runspace.AvailabilityChanged += Runspace_AvailabilityChanged;
                    Tracer.TraceInformation("created-runspace");
                }
                else
                {
                    Tracer.TraceInformation("existing-runspace-state '{0}'", runspace.RunspaceStateInfo.State);
                }
                if (runspace.RunspaceStateInfo.State == RunspaceState.BeforeOpen)
                {
                    Tracer.TraceInformation("opening-runspace");
                    runspace.Open();
                }
                else
                {
                    Tracer.TraceInformation("runspace-already-open");
                }
                Tracer.TraceInformation("runspace-state '{0}'", runspace.RunspaceStateInfo.State);
                if (runspace.RunspaceStateInfo.State == RunspaceState.Opened)
                {
                    Tracer.TraceInformation("runspace-powershell-version {0}.{1}", runspace.Version.Major, runspace.Version.Minor);
                }

                if (powershell == null)
                {
                    Tracer.TraceInformation("creating-powershell");
                    powershell          = PowerShell.Create();
                    powershell.Runspace = runspace;

                    Tracer.TraceInformation("powershell instanceid: {0}, runspace-id: {1}", powershell.InstanceId, powershell.Runspace.InstanceId);
                    Tracer.TraceInformation("powershell apartmentstate: {0}, version: {1}", powershell.Runspace.ApartmentState, powershell.Runspace.Version);

                    // the streams (Error, Debug, Progress, etc) are available on the PowerShell instance.
                    // we can review them during or after execution.
                    // we can also be notified when a new item is written to the stream (like this):
                    powershell.Streams.ClearStreams();
                    powershell.Streams.Error.DataAdded    += new EventHandler <DataAddedEventArgs>(Error_DataAdded);
                    powershell.Streams.Verbose.DataAdded  += new EventHandler <DataAddedEventArgs>(Verbose_DataAdded);
                    powershell.Streams.Warning.DataAdded  += new EventHandler <DataAddedEventArgs>(Warning_DataAdded);
                    powershell.Streams.Debug.DataAdded    += new EventHandler <DataAddedEventArgs>(Debug_DataAdded);
                    powershell.Streams.Progress.DataAdded += new EventHandler <DataAddedEventArgs>(Progress_DataAdded);

                    Tracer.TraceInformation("created-powershell");
                }
            }
            catch (Exception ex)
            {
                Tracer.TraceError("openrunspace", ex);
                throw;
            }
            finally
            {
                Tracer.Exit("openrunspace");
            }
        }