Some slight tweaks on my powershell instance

I'm running the following inside my visual studio project and I'm looking to obtain two things:

1) I have to import a pssession to utilize some exchange cmdlets.  I do this with $session = path to server, etc... and then
import-pssession $session -allowclobber -disablenamechecking -verbose:$false |out-null
But yet, in my capture of verbose output, it's continually displaying the typical verbose output for this:
VERBOSE: Importing function 'Get-...', etc, etc...

How can I supress these messages?

2) The other component of this is that when my powershell script completes, I'm using
exit $exitCode
I'd like to grab that exit code, but it doesn't seem that my current code picks it up.

Here's the relevant snippet:
     PowerShellInstance.AddScript(CommandString)
            Dim outputCollection As New PSDataCollection(Of PSObject)()
            'outputCollection.DataAdded += outputCollection_DataAdded  <<< Not sure if this is part of my problem.  It was in the source, but I couldn't get it working in vb.net (converted from c#)

            ' 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):
            'PowerShellInstance.Streams.[Error].DataAdded += Error_DataAdded
'changed above to:
            AddHandler PowerShellInstance.Streams.Error.DataAdded, AddressOf Error_DataAdded
            AddHandler PowerShellInstance.Streams.Verbose.DataAdded, AddressOf Verbose_DataAdded

            Try
                Dim result As IAsyncResult = PowerShellInstance.BeginInvoke(Of PSObject, PSObject)(Nothing, outputCollection)
                Console.Write(vbTab & "Waiting for pipeline to finish")
                While result.IsCompleted = False
                    Threading.Thread.Sleep(2500)
                End While
                Console.Write("Execution is: )
                Console.WriteLine(PowerShellInstance.InvocationStateInfo.State.ToString())
            Catch ex As Exception
                Console.WriteLine("Execution failed.  Exception is " & ex.Message)
            End Try
        End Using

Open in new window



Output that I don't want looks like this: ('Waiting for pipeline to finish', is expected)

        Waiting for pipeline to finishVERBOSE: Loading module from path 'C:\Users\xxxxxx
\AppData\Local\Temp\2\tmp_zrnqd2ou.xwd\tmp_zxnrd2ou.xwd.psd1'.
VERBOSE: Importing function 'Add-ADPermission'.
VERBOSE: Importing function 'Add-AvailabilityAddressSpace'.
VERBOSE: Importing function 'Add-ContentFilterPhrase'.
VERBOSE: Importing function 'Add-DatabaseAvailabilityGroupServer'.
VERBOSE: Importing function 'Add-DistributionGroupMember'.
VERBOSE: Importing function 'Add-FederatedDomain'.
VERBOSE: Importing function 'Add-IPAllowListEntry'.
VERBOSE: Importing function 'Add-IPAllowListProvider'.
VERBOSE: Importing function 'Add-IPBlockListEntry'.
LVL 67
sirbountyAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Bob LearnedCommented:
1) Try importing the functions that you need explicitly:

Example:

      Import-PSSession $Session -CommandName Get-MailboxDatabase, Get-MailboxDatabaseCopyStatus

2) outputCollection.DataAdded += outputCollection_DataAdded

   AddHandler outputCollection.DataAdded, AddressOf outputCollection_DataAdded

    Create a event handler method to handle the DataAdded event:

  Private Sub outputCollection_DataAdded(ByVal sender As Object, ByVal e As DataAddedEventArgs)
  End Sub

PSDataCollection.DataAdded Event
https://msdn.microsoft.com/en-us/library/dd182208(v=vs.85).aspx

3) Another approach might be to store the result into a string:

$output = Import-PSSession $session
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
sirbountyAuthor Commented:
Assigning it to a variable didn't work. :(
Bugs me that I can't suppress that.  Trimming the commands helped, but I can feel it taunting me...

I've set the event handler - I thought correctly - I mirrored the others (didn't know what to cast it as, so I guessed).
Still not seeing the exit code - does this look correct?
Private Sub output_DataAdded(sender As Object, e As DataAddedEventArgs)
        Dim records = DirectCast(sender, PSDataCollection(Of IDataRecord))
        Console.WriteLine("DATA: " & records(e.Index).ToString())
    End Sub

    Private Sub Verbose_DataAdded(sender As Object, e As DataAddedEventArgs)
        Dim records = DirectCast(sender, PSDataCollection(Of VerboseRecord))
        Console.WriteLine("VERBOSE: " & records(e.Index).ToString())
    End Sub

    Private Sub Error_DataAdded(sender As Object, e As DataAddedEventArgs)
        Dim records = DirectCast(sender, PSDataCollection(Of ErrorRecord))
        Console.WriteLine("ERROR: " & records(e.Index).ToString())
    End Sub

Open in new window

0
sirbountyAuthor Commented:
Tried this too - only other thing that seemed somewhat logical by comparison:

Dim records = DirectCast(sender, PSDataCollection(Of InformationalRecord))

Still no dice
0
Simplify Active Directory Administration

Administration of Active Directory does not have to be hard.  Too often what should be a simple task is made more difficult than it needs to be.The solution?  Hyena from SystemTools Software.  With ease-of-use as well as powerful importing and bulk updating capabilities.

Bob LearnedCommented:
I believe that exit $exitCode will only return the value, not output it.

I wonder if you need a Write-Host call:

        Write-Host "From PowerShell: Exit.ps1 exited with exit code $LastExitCode"
0
Bob LearnedCommented:
Is the Output_DataAdded event being raised.  If so, should be able to find out the type of object that the collection holds?
0
Bob LearnedCommented:
Also, you are attaching an event handler to the Error_DataAdded event.  Is that event raised?
0
sirbountyAuthor Commented:
I tried a write-host yesterday - complained about host something or nother and sounded like I needed some adjustments to allow that.

Is the Output_DataAdded event being raised.  If so, should be able to find out the type of object that the collection holds?
Checking that now...
0
sirbountyAuthor Commented:
No, I haven't added an error_dataadded handler, but I will..
0
sirbountyAuthor Commented:
I don't see 'data' streams available, but I wonder if I shouldn't be grabbing something from the instance here?

AddHandler PowerShellInstance.Streams.Error.DataAdded, AddressOf Error_DataAdded
AddHandler PowerShellInstance.Streams.Verbose.DataAdded, AddressOf Verbose_DataAdded
AddHandler outputCollection.DataAdded, AddressOf outputCollection_DataAdded
0
Bob LearnedCommented:
I see this code:

Private Sub Error_DataAdded(sender As Object, e As DataAddedEventArgs)
        Dim records = DirectCast(sender, PSDataCollection(Of ErrorRecord))
        Console.WriteLine("ERROR: " & records(e.Index).ToString())
    End Sub

Open in new window

0
sirbountyAuthor Commented:
output_dataadded is not being raised...yet
0
sirbountyAuthor Commented:
Bah - you're correct.  I completely forgot I added that.
The error has been raised a couple of times while testing, so that seems to be working....
0
Bob LearnedCommented:
Reference question:

http://www.experts-exchange.com/Programming/Languages/Scripting/Powershell/Q_28672280.html

The code had this, which doesn't reference any stream:

 
          // prepare a new collection to store output stream objects
            PSDataCollection<PSObject> outputCollection = new PSDataCollection<PSObject>();
            outputCollection.DataAdded += outputCollection_DataAdded;

Open in new window

and it is used here:

IAsyncResult result = PowerShellInstance.BeginInvoke<PSObject, PSObject>(null, outputCollection);

Open in new window


I am thinking that this whole output data collection event handling is useless, since you already have the output collection to inspect.
0
Bob LearnedCommented:
There is a note from the posted link:

if your scripts utilize write-error, write-debug, write-progress, etc. (all thread-safe collections), you can review these during or after execution to check for items logged there.
0
sirbountyAuthor Commented:
You may be right (usually are :^) - My problem is I'm having to deploy the exe to the server to test, so it's taking a little longer than I'd like, and I can't simply step through it to find out how I might be able to use that result...
But, still plugging away...thanks.
0
Bob LearnedCommented:
0
Bob LearnedCommented:
This might also be helpful:

HOW TO: Call .PS1 script from Managed code using Remote Powershell(Exchange 2010)
http://blogs.msdn.com/b/akashb/archive/2010/03/26/how-to-call-ps1-script-from-managed-code-using-remote-powershell-exchange-2010.aspx
0
Bob LearnedCommented:
0
sirbountyAuthor Commented:
I'll have a look at that later - have to head out now (should have two hours ago!)

I did check the outputCollection.Count (it was 0)
and tried iterating any items therein
                    For i As Int16 = 0 To outputCollection.Count - 1
                        Console.WriteLine(outputCollection.Item(i))
                    Next
but that didn't give me anything when I had no errors, and when I forced an error.

I did get a couple of raised Error events from it, but I'll have to dive into that later.
Thanks - I'll post an update when I can, either this evening or first thing tomorrow.
0
Bob LearnedCommented:
function Resolve-Error ($ErrorRecord=$Error[0])
{
   $ErrorRecord | Format-List * -Force
   $ErrorRecord.InvocationInfo |Format-List *
   $Exception = $ErrorRecord.Exception
   for ($i = 0; $Exception; $i++, ($Exception = $Exception.InnerException))
   {   "$i" * 80
       $Exception |Format-List * -Force
   }
}
0
sirbountyAuthor Commented:
So far, I've tried:

For Each p As PSObject In outputCollection
  Console.WriteLine(p.BaseObject.ToString)
Next
(nothing)
For Each final As PSObject In PowerShellInstance.EndInvoke(result)
  Console.WriteLine(final.BaseObject.GetType().FullName)
  Console.WriteLine(final.BaseObject.ToString)
 Next
That throws an object ref error.

That last function you posted - that's supposed to do what?
My error codes come from an internal table in an xml file - still applicable?
0
sirbountyAuthor Commented:
Hate to say it, but I'm going to give up on this one...
I just wanted to retrieve the exit code from the script so that I could pass it back to the vs project for reporting to the engineer staff.  I can accomplish it with much less work within the powershell script.

Thanks for the guidance and support!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
.NET Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.