sirbounty
asked on
launching a powershell script from visual studio 2010
I have developed a service that simply watches for a file to be created, then executes a powershell script in an Exchange 2010 environment.
I have tried using a runspace, but find that in order to add the needed snap-in, I must use VS2012 (which I don't have in my lab) so that it will run the 64-bit version of powershell. I've also found a few other hiccups with this approach, seeming that it's difficult to troubleshoot where it breaks down in the script (which works fine outside of the visual studio project). I've also read that Exchange 2010 has to launch a remote session, because local snap-ins are no longer supported? (Found at http://stackoverflow.com/questions/7811754/powershell-snapin-issues-in-c-sharp)
I'm now attempting just to launch a process in visual studio - using powershell.exe as the filename and supplying the script name and its parameters, but apparently that's causing issues too. It seems that at least one of my parameters, enclosed in single quotes, is causing a problem.
Is there anyone familiar enough with running powershell scripts through visual studio that can help me get this working?
I have tried using a runspace, but find that in order to add the needed snap-in, I must use VS2012 (which I don't have in my lab) so that it will run the 64-bit version of powershell. I've also found a few other hiccups with this approach, seeming that it's difficult to troubleshoot where it breaks down in the script (which works fine outside of the visual studio project). I've also read that Exchange 2010 has to launch a remote session, because local snap-ins are no longer supported? (Found at http://stackoverflow.com/questions/7811754/powershell-snapin-issues-in-c-sharp)
I'm now attempting just to launch a process in visual studio - using powershell.exe as the filename and supplying the script name and its parameters, but apparently that's causing issues too. It seems that at least one of my parameters, enclosed in single quotes, is causing a problem.
Is there anyone familiar enough with running powershell scripts through visual studio that can help me get this working?
ASKER
It's not so much getting my hands on a copy, it's just hard to get software into the lab...
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks for that Bob.
I hadn't seen that article, so I read through it and tried to devise something similar, but from other things I'd read I needed to add the snapin first - so I tried that as well and right away it comes back stating that 'no snap-ins' have been registered for Powershell version 3' - I'm not sure why or how to handle that error...any ideas? I've tried it within the script as well and it still fails.
I hadn't seen that article, so I read through it and tried to devise something similar, but from other things I'd read I needed to add the snapin first - so I tried that as well and right away it comes back stating that 'no snap-ins' have been registered for Powershell version 3' - I'm not sure why or how to handle that error...any ideas? I've tried it within the script as well and it still fails.
ASKER
By 'add that first', I meant via:
PowerShellInstance.AddScript("Add-pssnapin Microsoft.Exchange.Management.PowerShell.E2010")
PowerShellInstance.AddScript(ScriptName)
PowerShellInstance.AddParameter("....", "some value")
ASKER
Ok, I tried the version you posted above and I got many lines of
"waiting for pipeline to finish..."
but then it threw an invalid cast exception (from string "Execution has stopped. The pipl" to type 'Double' is not valid).
I did have to comment out
'outputCollection.DataAdde d += outputCollection_DataAdded
and
'PowerShellInstance.Stream s..DataAdded += Error_DataAdded
as they were causing errors.
"waiting for pipeline to finish..."
but then it threw an invalid cast exception (from string "Execution has stopped. The pipl" to type 'Double' is not valid).
I did have to comment out
'outputCollection.DataAdde
and
'PowerShellInstance.Stream
as they were causing errors.
ASKER
Found the exception in an output that I'd set in my script...file shows:
The term 'Get-DistributionGroup' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
So, it appears it's still not adding the snapin. :(
The term 'Get-DistributionGroup' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
So, it appears it's still not adding the snapin. :(
ASKER
And sorry for the spam...
It seems to have 'worked' as the output file did state that an internal error was thrown that I'm familiar with - that a list by the same name exists, but even removing that from AD, it doesn't seem to complete without throwing the unhandled exception outlined above (and so far, hasn't recreated the previous duplicate).
I'm confused and not sure how I can troubleshoot from here.
It seems to have 'worked' as the output file did state that an internal error was thrown that I'm familiar with - that a list by the same name exists, but even removing that from AD, it doesn't seem to complete without throwing the unhandled exception outlined above (and so far, hasn't recreated the previous duplicate).
I'm confused and not sure how I can troubleshoot from here.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Doesn't give me a line number - sometimes it happens after many 'waiting for pipeline to finish..." sometimes only a few. :\
I'll add the above...
I'll add the above...
ASKER
Error_DataAdded is not declared.
ASKER
Tried a conversion too...but couldn't get past this part either:
Dim outputCollection As New PSDataCollection(Of PSObject)()
outputCollection.DataAdded += outputCollection_DataAdded
outputCollection_DataAdded is not declared.
Dim outputCollection As New PSDataCollection(Of PSObject)()
outputCollection.DataAdded
outputCollection_DataAdded
ASKER
Even tried the comment at the bottom:
void Error_DataAdded(object sender, DataAddedEventArgs e) {
var records = (PSDataCollection<ErrorRec ord>)sende r;
// do something when an error is written to the error stream
Console.WriteLine(records[ e.Index].T oString()) ;
}
void Error_DataAdded(object sender, DataAddedEventArgs e) {
var records = (PSDataCollection<ErrorRec
// do something when an error is written to the error stream
Console.WriteLine(records[
}
ASKER
After doing that, I can get this working:
AddHandler PowerShellInstance.Streams .Error.Dat aAdded, AddressOf Error_DataAdded
But the outputCollection.DataAdded += outputCollection_DateAdded
still causes problems.
AddHandler PowerShellInstance.Streams
But the outputCollection.DataAdded
still causes problems.
ASKER
That looks 'a little' better though... I get this the errors on the screen, but then it still throws the exception at the end (invalidcastexception)
Waiting for pipeline to finish...
Waiting for pipeline to finish...
No snap-ins have been registered for Windows PowerShell version 3.
Waiting for pipeline to finish...
Waiting for pipeline to finish...
Waiting for pipeline to finish...
Waiting for pipeline to finish...
Waiting for pipeline to finish...
Waiting for pipeline to finish...
Waiting for pipeline to finish...
The term 'Get-DistributionGroup' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
Waiting for pipeline to finish...
Waiting for pipeline to finish...
Waiting for pipeline to finish...
Waiting for pipeline to finish...
Waiting for pipeline to finish...
Waiting for pipeline to finish...
Waiting for pipeline to finish...
Waiting for pipeline to finish...
No snap-ins have been registered for Windows PowerShell version 3.
Waiting for pipeline to finish...
Waiting for pipeline to finish...
Waiting for pipeline to finish...
Waiting for pipeline to finish...
Waiting for pipeline to finish...
Waiting for pipeline to finish...
Waiting for pipeline to finish...
The term 'Get-DistributionGroup' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
Waiting for pipeline to finish...
Waiting for pipeline to finish...
Waiting for pipeline to finish...
Waiting for pipeline to finish...
Waiting for pipeline to finish...
Waiting for pipeline to finish...
ASKER
I suspect this goes back to the initial link about the snap-ins not being supported. :(
ASKER
I tried using import-module to the Exchange management.dll.
It still errors, could not load file or assembly <file> or one of its dependencies.
Then it complains aobut get-distribution not being recognized,
then gives the invalidcast exception, (wish I knew where that was coming from).
:\
I can get a copy of vs2012 in my lab now, if that might help?
It still errors, could not load file or assembly <file> or one of its dependencies.
Then it complains aobut get-distribution not being recognized,
then gives the invalidcast exception, (wish I knew where that was coming from).
:\
I can get a copy of vs2012 in my lab now, if that might help?
ASKER
Maybe getting closer... I used this mechanism for adding a session:
https://technet.microsoft.com/en-us/library/dd297932.aspx
I say maybe because it doesn't seem to error on the cmdlets, but it's still bbombing on the cast exception (where is that? ugh)
https://technet.microsoft.com/en-us/library/dd297932.aspx
I say maybe because it doesn't seem to error on the cmdlets, but it's still bbombing on the cast exception (where is that? ugh)
My friend, you remind me of a Stanley engine--with just a little input, you run perpetually.
Can you show me what you currently have, please?
Can you show me what you currently have, please?
ASKER
Heh heh - I dunno...I'm just trying to get this working. Haha!
And for the most part, it is now (finally!).
However, it's still throwing that exception, and I have no idea how to track it down, nor identify any portion of the code to show you.
I've placed a try/catch in both the vs project and the powershell script, but I don't seem to be catching it, wherever it is..
The project calls one script, which calls another, which reads an xml file, and feeds all that back to the parent script.
If you have an idea where to start, let me know, otherwise, I'll continue running perpetually until I find this darned needle. ;^)
And for the most part, it is now (finally!).
However, it's still throwing that exception, and I have no idea how to track it down, nor identify any portion of the code to show you.
I've placed a try/catch in both the vs project and the powershell script, but I don't seem to be catching it, wherever it is..
The project calls one script, which calls another, which reads an xml file, and feeds all that back to the parent script.
If you have an idea where to start, let me know, otherwise, I'll continue running perpetually until I find this darned needle. ;^)
ASKER
Thought it might have to do with this (https://www.experts-exchange.com/questions/28673119/Why-won't-powershell-believe-me.html), but I've sorted that and still not getting past this exception. That's more of a why did it work when I did this question, than 'give me an answer' question...
ASKER
This is what I have for the piece that runs it in VS.
Any concern that the outputCollection.DataAdded piece is still commented?
Any concern that the outputCollection.DataAdded
Using PowerShellInstance As PowerShell = PowerShell.Create()
PowerShellInstance.AddScript(CommandString)
Dim outputCollection As New PSDataCollection(Of PSObject)()
'outputCollection.DataAdded += outputCollection_DataAdded
' 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
AddHandler PowerShellInstance.Streams.Error.DataAdded, AddressOf Error_DataAdded
Try
Dim result As IAsyncResult = PowerShellInstance.BeginInvoke(Of PSObject, PSObject)(Nothing, outputCollection)
Console.Write("Waiting for pipeline to finish")
While result.IsCompleted = False
Console.Write(".")
Threading.Thread.Sleep(1000)
End While
Console.WriteLine(".")
Console.WriteLine("Execution has stopped. The pipeline state: " + PowerShellInstance.InvocationStateInfo.State)
For Each outputItem As PSObject In outputCollection
Console.WriteLine(outputItem.BaseObject.GetType().FullName)
Console.WriteLine(outputItem.BaseObject.ToString())
Next
Catch ex As Exception
Console.WriteLine("Exception is " & ex.Message)
End Try
End Using
Private Sub Error_DataAdded(sender As Object, e As DataAddedEventArgs)
Dim records = DirectCast(sender, PSDataCollection(Of ErrorRecord))
' do something when an error is written to the error stream
Console.WriteLine(records(e.Index).ToString())
End Sub
Did you take the code that I showed you, and change it beyond the capability for sharing?
ASKER
Oh no, that piece I think is working (other than perhaps my last comment).
That's what I have in the vs project. I suppose now though that this is something that's being thrown from my powershell script, so I'll close this out and try to track that down.
Thanks (as always!)
That's what I have in the vs project. I suppose now though that this is something that's being thrown from my powershell script, so I'll close this out and try to track that down.
Thanks (as always!)
I ran this sample code, which creates a script that generates an object, and then synchronously executes the script, to get back a collection of PSObject instances.
Here is the debug screen shot:
using System;
using System.Management.Automation;
namespace PowerShellExecutionSample
{
/// <summary>
/// Test class object to instantiate from inside PowerShell script.
/// </summary>
public class TestObject
{
/// <summary>
/// Gets or sets the Name property
/// </summary>
public string Name { get; set; }
}
/// <summary>
/// Test static class to invoke from inside PowerShell script.
/// </summary>
public static class TestStaticClass
{
/// <summary>
/// Sample static method to call from inside PowerShell script.
/// </summary>
/// <returns>String message</returns>
public static string TestStaticMethod()
{
return "Hello, you have called the test static method.";
}
}
/// <summary>
/// Provides PowerShell script execution examples
/// </summary>
public class PowerShellExecutor
{
/// <summary>
/// Sample execution scenario 3: Namespace test
/// </summary>
/// <remarks>
/// Executes a PowerShell script synchronously and utilizes classes in the callers namespace.
/// </remarks>
public void ExecuteSynchronouslyNamespaceTest()
{
using (var powerShellInstance = PowerShell.Create())
{
// add a script that creates a new instance of an object from the caller's namespace
powerShellInstance.AddScript("$t = new-object PowerShellExecutionSample.TestObject;" +
"$t.Name = 'created from inside PowerShell script'; $t;" +
"$message = [PowerShellExecutionSample.TestStaticClass]::TestStaticMethod(); $message");
// invoke execution on the pipeline (collecting output)
var psOutput = powerShellInstance.Invoke();
// loop through each output object item
foreach (var outputItem in psOutput)
{
if (outputItem != null)
{
if (outputItem.BaseObject is TestObject)
{
var testObj = outputItem.BaseObject as TestObject;
Console.WriteLine(testObj.Name);
}
}
}
}
}
}
}
Here is the debug screen shot:
You can run the script synchronously with Invoke, instead of asychronously with BeginInvoke.
If you are adding a cmdlet, there is the PowerShell.AddCommand, instead of AddScript.
If you have parameters, that would be PowerShell.AddParameter.
If you want to see if there are errors, there is the PowerShell.HadErrors property
If you are adding a cmdlet, there is the PowerShell.AddCommand, instead of AddScript.
If you have parameters, that would be PowerShell.AddParameter.
If you want to see if there are errors, there is the PowerShell.HadErrors property
ASKER
Hmm - I was using addscript, but including the script and all it's parameters at once.
I'll investigate the haderrors property - thanks!
I'll investigate the haderrors property - thanks!
ASKER
I never did find that issue with the cast exception, but it 'disappeared' nonetheless (arg, I hate things like that).
But, I've asked a related question here - two minor tweaks I'm looking to add/correct, if you have time.
https://www.experts-exchange.com/questions/28673954/Some-slight-tweaks-on-my-powershell-instance.html
Thanks!
But, I've asked a related question here - two minor tweaks I'm looking to add/correct, if you have time.
https://www.experts-exchange.com/questions/28673954/Some-slight-tweaks-on-my-powershell-instance.html
Thanks!
Why not get Visual Studio Community Edition (free)