/// <summary>
 /// Event handler for when Data is added to the a stream.
 /// </summary>
 /// <param name="sender">Contains the complete PSDataCollection of all error output items.</param>
 /// <param name="e">Contains the index ID of the added collection item and the ID of the PowerShell instance this event belongs to.</param>
 void Output_DataAdded(object sender, DataAddedEventArgs e)
 {
     if (sender is PSDataCollection <ErrorRecord> )
     {
         PSDataCollection <ErrorRecord> data = sender as PSDataCollection <ErrorRecord>;
         Console.WriteLine("Error: " + data.Last <ErrorRecord>().ToString());
     }
     else if (sender is PSDataCollection <WarningRecord> )
     {
         PSDataCollection <WarningRecord> data = sender as PSDataCollection <WarningRecord>;
         Console.WriteLine("Warning: " + data.Last <WarningRecord>().Message);
     }
     else if (sender is PSDataCollection <InformationRecord> )
     {
         PSDataCollection <InformationRecord> data = sender as PSDataCollection <InformationRecord>;
         Console.WriteLine("Info: " + data.Last <InformationRecord>().ToString());
     }
     else if (sender is PSDataCollection <DebugRecord> )
     {
         PSDataCollection <DebugRecord> data = sender as PSDataCollection <DebugRecord>;
         Console.WriteLine("Debug: " + data.Last <DebugRecord>().Message);
     }
     else if (sender is PSDataCollection <VerboseRecord> )
     {
         PSDataCollection <VerboseRecord> data = sender as PSDataCollection <VerboseRecord>;
         Console.WriteLine("Verbose: " + data.Last <VerboseRecord>().Message);
     }
     else if (sender is PSDataCollection <ProgressRecord> )
     {
         PSDataCollection <ProgressRecord> data = sender as PSDataCollection <ProgressRecord>;
         ProgressRecord lastRecord = data.Last <ProgressRecord>();
         Console.WriteLine("Progress: " + lastRecord.Activity + ": " + lastRecord.StatusDescription);
     }
 }
        /// <summary>
        /// Event handler for when data is added to the output stream.
        /// </summary>
        /// <param name="sender">Contains the complete PSDataCollection of all output items.</param>
        /// <param name="e">Contains the index ID of the added collection item and the ID of the PowerShell instance this event belongs to.</param>
        void outputCollection_DataAdded(object sender, DataAddedEventArgs e)
        {
            PSDataCollection <PSObject> data = sender as PSDataCollection <PSObject>;
            PSObject last = data.Last <PSObject>();

            // do something when an object is written to the output stream
            Console.WriteLine(last.ToString());
        }
        /// <summary>
        /// Return the last output to the user. This will be null if the operation did not succeed.
        /// outputAction is the action that will be performed whenever an object is outputted to the powershell pipeline
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="powershell"></param>
        /// <param name="command"></param>
        /// <param name="outputAction"></param>
        /// <param name="errorAction"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        internal static T InvokeFunction <T>(this PowerShell powershell, string command,
                                             EventHandler <DataAddedEventArgs> outputAction, EventHandler <DataAddedEventArgs> errorAction, params object[] args)
        {
            if (powershell != null)
            {
                powershell.Clear().AddCommand(command);
                foreach (var arg in args)
                {
                    powershell.AddArgument(arg);
                }
#if DEBUG
                NativeMethods.OutputDebugString("[Cmdlet:debugging] -- InvokeFunction ({0}, {1})".format(command, args.Select(each => (each ?? "<NULL>").ToString()).JoinWithComma(), powershell.InvocationStateInfo.Reason));
#endif

                var input = new PSDataCollection <PSObject>();
                input.Complete();

                var output = new PSDataCollection <PSObject>();

                if (outputAction != null)
                {
                    output.DataAdded += outputAction;
                }

                if (errorAction != null)
                {
                    powershell.Streams.Error.DataAdded += errorAction;
                }

                powershell.Invoke(null, output, new PSInvocationSettings());

                if (output.Count == 0)
                {
                    return(default(T));
                }

                // return the last output to the user
                PSObject last = output.Last();

                if (last != null)
                {
                    // convert last to T
                    return((T)last.ImmediateBaseObject);
                }
            }

            return(default(T));
        }