I created a few applications doing the last 2 years that facilitate PowerShell. I really had a hard time getting around to look at PowerShell, I honestly though VB scripts where so more powerful and easier to write, but looking back now I really don’t see why. I love it. I love it so much, that I create several applications that have a built-in PowerShell engine.
And how does that work then, you might ask ? well, there's tons of examples out there, but do a Google search on “Runspaces” or “Management.Automation.Runspaces” and your well on your way. There is how ever a few things, you want to keep in mind.
A plain PowerShell will often not be enough so you need some modules or snap ins. Let get down to basics here. Create a new application, go to My Project –> References –> Add –> Browse –> C:\Windows\assembly\GAC_MSIL\System.Management.Automation and find System.Management.Automation.dll
Imports System.Management.Automation.Runspaces
Module Module1
Sub Main()
Dim output As ICollection(Of PSObject) = Nothing
Dim ps As PowerShell = PowerShell.Create()
ps.AddScript("get-help")
ps.Commands.Commands.Item(ps.Commands.Commands.Count - 1).MergeUnclaimedPreviousCommandResults = _
PipelineResultTypes.Error + PipelineResultTypes.Output
Try
output = ps.Invoke()
Catch ex As Exception
Throw ex
End Try
For Each o As PSObject In output
If Not o Is Nothing Then
Console.WriteLine(o.ToString)
End If
Next
Console.ReadLine()
End Sub
End Module
See, that wasn’t so bad was it ? Here's with some Snap ins loaded from start. ( you can also just call invoke “Add-PSSnapin Name” .. use Get-PSSnapin –Registered to see what is available to you.
Here's another “gotcha” … Many snap ins only works on x86 and some only on x64. If you see something in your PowerShell and get The Windows PowerShell snap-in 'SqlServerCmdletSnapin100' is not installed on this machine.
It means you compiling for the wrong version. Go to My Project –> Advanced Compiler Options…” and choose the correct version. NEVER choose anyCPU.
Dim rc As RunspaceConfiguration = RunspaceConfiguration.Create
Dim SnapInList As String() = {"SqlServerCmdletSnapin100", "SqlServerProviderSnapin100"}
For Each snapin As String In SnapInList
Dim snapEx As PSSnapInException = Nothing
Dim info As PSSnapInInfo = rc.AddPSSnapIn(snapin, snapEx)
If (Not snapEx Is Nothing) Then Throw New Exception(snapEx.Message, snapEx)
Next
Dim r As Runspace = RunspaceFactory.CreateRunspace(rc)
r.Open()
Dim output As ICollection(Of PSObject) = Nothing
Dim ps As PowerShell = PowerShell.Create()
ps.Runspace = rps.AddScript("Get-ChildItem SQLSERVER:\SQL\SQL01\DEFAULT\Databases")
ps.Commands.Commands.Item(ps.Commands.Commands.Count - 1).MergeUnclaimedPreviousCommandResults = _
PipelineResultTypes.Error + PipelineResultTypes.Output
Try
output = ps.Invoke()
Catch ex As Exception
Throw ex
End Try
For Each o As PSObject In output
If Not o Is Nothing Then
Console.WriteLine(o.ToString)
End If
Next
Console.WriteLine("done.")
Console.ReadLine()
End Sub
Ok, all seems ok, now try this.
Dim output As ICollection(Of PSObject) = Nothing
Dim ps As PowerShell = PowerShell.Create()
ps.AddScript("Write-Host 'Hello world.'")
ps.Commands.Commands.Item(ps.Commands.Commands.Count - 1).MergeUnclaimedPreviousCommandResults = _
PipelineResultTypes.Error + PipelineResultTypes.Output
Try
output = ps.Invoke()
Catch ex As Exception
Throw ex
End Try
For Each o As PSObject In output
If Not o Is Nothing Then
Console.WriteLine(o.ToString)
End If
Next
Console.WriteLine("done.")
Console.ReadLine()
End Sub
It’s blank … the reason is PowerShell commands return objects, not text. Write-Host is sending the text to the Host holding the runespace. the handy little wrapper class PowerShell implements a simple Host and HostUI, but this doesn’t support neat things like Read, Write, Prompt etc..
So, lets make one, that does. ( Remember to add a reference to “System.Drawing” )
Add the following 3 classes
myPSHost.vb
myPSHostRawUI.vb
myPSHostUI.vb
Now, you can auto accept warnings that is making your life miserably and avoid getting weird errors when enabling Exchange 2010 PowerShell add-on and initializing it.
Dim host As New myPSHost
Dim rc As RunspaceConfiguration = RunspaceConfiguration.Create
Dim r As Runspace = RunspaceFactory.CreateRunspace(host, rc)
r.Open()
Dim output As ICollection(Of PSObject) = Nothing
Dim ps As PowerShell = PowerShell.Create()
ps.Runspace = r
ps.AddScript("Write-Host 'Hello world.'")
ps.Commands.Commands.Item(ps.Commands.Commands.Count - 1).MergeUnclaimedPreviousCommandResults = _
PipelineResultTypes.Error + PipelineResultTypes.Output
Try
output = ps.Invoke()
Catch ex As Exception
Throw ex
End Try
For Each o As PSObject In output
If Not o Is Nothing Then
Console.WriteLine(o.ToString)
End If
Next
For Each e As myPSHost.UIAction In host.UIEvents
If e.ActionType = "Write" Then
Console.WriteLine(e.Message)
End If
Next
Console.WriteLine("done.")
Console.ReadLine()
End Sub
Ingen kommentarer:
Send en kommentar