|
Tuesday, July 18, 2006
Runspace Remoting
Scott Hanselman is one of the early users and supporters of my PowerShell Remoting. He did an interesting post about Runspace Remoting. Briefly, he used export-clixml to serialize objects at server and used import-clixml to reconstruct PSObject at client. I have tried similar mechanism and failed. Actually Karl Prosser and I have been talking about using export-clixml/import-clixml a while ago . Great job, Scott!
Despite of my failure on serialization/de-serialization of PSObject, there is other reasons made me choose user interface remoting:
PS: To Monad Team, a public helper API to serialize PSObject to string will be really helpful.
Have Fun
Despite of my failure on serialization/de-serialization of PSObject, there is other reasons made me choose user interface remoting:
- Monad was designed to capable of user interface remoting. Monad engine will manage to display and format (out-default) remote objects. Monad engine can even truncate objects collection for you if there are too many objects in the pipline.
- Not all tasks require local objects exactly matching remote objects. For most remote scripting tasks, user interface remoting is good enough. User interface remoting deliver similar user experience as local shell. SSHD already proved itself successful story by similar mechanism.
- User can manipulate "Real" remote objects via user interface remoting (No "Heisenberg Uncertainly Principle of PowerShell").
- Serialization/de-serialization method has its own limitations.
- It can use a lot of resources and band-width. Consider the situation when multiple runspace ouput huge collection of objects at the same time, even with proper threading management server could still be overloaded.
- What if you just need one simple property of an object with hundreds or thounds of properties, you would have to serialize all public properties of that object and transfer it to client.
- It can loose some property associate with original objects.
- It can use a lot of resources and band-width. Consider the situation when multiple runspace ouput huge collection of objects at the same time, even with proper threading management server could still be overloaded.
- "Clustering" multiple servers is possible with user interface remoting. I am trying to "fork" single client input to multiple servers by simply add current client component to server component. (There are still some problems with this model)
PS: To Monad Team, a public helper API to serialize PSObject to string will be really helpful.
Have Fun
Tags: msh monad PowerShell
Thursday, July 13, 2006
How to: Using PowerShell through SSH
the story from The Hive Archive.
But there are certain limitations:
1. You have to install cygwin, sshd and ssh client like putty (Well I can certainly live with that. Actually they are always on my hard drive).
2. No prompt
3. some Raw UI might not work
I am really looking forward to the new version of PowerShell with buildin Remoting function. According to Jeffrey Snover : Our plans for remoting are to leverage WS-MGMT the remoting protocol recently standardized through the DMTF.
Have Fun
It is possible to use PowerShell through SSH. Read But there are certain limitations:
1. You have to install cygwin, sshd and ssh client like putty (Well I can certainly live with that. Actually they are always on my hard drive).
2. No prompt
3. some Raw UI might not work
I am really looking forward to the new version of PowerShell with buildin Remoting function. According to Jeffrey Snover : Our plans for remoting are to leverage WS-MGMT the remoting protocol recently standardized through the DMTF.
Have Fun
Tags: msh monad PowerShell
Wednesday, July 12, 2006
Why There Is an Out-Default Cmdlet
> gcm out-*Out-Default cmdlet is one of the most mysterious one.
CommandType Name Definition
----------- ---- ----------
Cmdlet Out-Default Out-Default [-InputObject <P...
Cmdlet Out-File Out-File [-FilePath] <String...
Cmdlet Out-Host Out-Host [-Paging] [-InputOb...
Cmdlet Out-Null Out-Null [-InputObject <PSOb...
Cmdlet Out-Printer Out-Printer [[-Name] <String...
Cmdlet Out-String Out-String [-Stream] [-Width...
> help out-defaultThe help message does not help at all. Luckily enough, Jeffrey Snover has a blog entry talking about this cmdlet. In summary, It will "figure out how to format and output the object stream" and send them to host via Out-host cmdlet.
NAME
Out-Default
SYNOPSIS
The default controller of output.
DETAILED DESCRIPTION
The standard treatment at the end of a pipeline is to send all objects to o
ut-default. Out-default then sends them all to format-default. It takes th
e objects that return and sends them to the default destination. For this
reason, it is functionally equivalent to out-host but is not called from th
e console.
Here is my two cents:
1. Out-Default cmdlet is NOT for interactive console User.
Every interactive command from console will have Out-Default appended automatically by Monad engine. Add Out-Default in the middle of pipline could even cause unexpected output.
> gps | format-table2. Out-Default cmdlet is for Monad hosting application.
> gps | out-default | format-table # format-table will not work.
To have a full-blown Monad hosting application, you have to create your own "Host" (System.Management.Automation.Host.PSHost) which implement interface to process output (If you don't have your PSHost output interface implemented, your will get an exception when Out-default finally called out-host.). Every interactive command from user input should have Out-Default appended. Then the output of user command were assessed by out-default, formatted by format-* cmdlet, and eventually sent to user interface by out-host cmdlet.
using System.Management.Automation;Although you don't have to (and probably should not) type "Out-Default" at the end of your command, it is always there working for you. Given this reason, Out-Default cmdlet is registered and loaded as default cmdlets.
using System.Management.Automation.Host;
using System.Management.Automation.Runspaces;
namespace HostingExample
{
class TestHost
{
static void Main(string[] args)
{
string command = "gps";
PSHost myhost = new MyHost();
Runspace myRunspace = RunspaceFactory.CreateRunspace(myhost);
myRunspace.Open();
Pipeline pipeline1 = myRunspace.CreatePipeline(command, true);
pipeline1.Commands[0].MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output);
pipeline1.Commands.Add("out-default");
Pipeline1.Invoke();
}
}
Class MyHost : PSHost
{
// MyHost class should be derived from PSHost abstract class.
}
}
You see it is there, you do not use it, but it is definitely important.
Tags: msh monad PowerShell
Sunday, July 02, 2006
Naive and Generic Object Collections in Powershell
>$a = 1,2,3 #comma were interpreted as object[]For naive object ArrayList/stack/Queue, you have to use new-object cmdlet
>$a.gettype().AssemblyQualifiedName
System.Object[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
>$a= 1..10 # .. were interpreted as continuous filled object[]
>$a.gettype().AssemblyQualifiedName
System.Object[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
> $a = new-object System.Collections.StackMost of time, you are fine with naive object model because PowerShell will do the type conversion for you.
> $a.GetType().AssemblyQualifiedName
System.Collections.Stack, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKey
Token=b77a5c561934e089
> $a.Push($([System.Net.IPAddress] "192.168.0.1"))
>$a= 1..10But sometimes it is not good enough. You probably want to use generic object model.
>$a |gm
TypeName: System.Int32
Name MemberType Definition
---- ---------- ----------
CompareTo Method System.Int32 CompareTo(Int32 value), System.Int32 Com...
Equals Method System.Boolean Equals(Object obj), System.Boolean Equ...
GetHashCode Method System.Int32 GetHashCode()
GetType Method System.Type GetType()
GetTypeCode Method System.TypeCode GetTypeCode()
ToString Method System.String ToString(), System.String ToString(IFor...
For generic array (like System.Net.IPAddress[]), it requires a conversion:
>$a = ($([System.Net.IPAddress] "192.168.0.1"),$([System.Net.IPAddress] "127.0.0.1") )For generic collection (like System.Collections.ObjectModel.Collection<System.Net.IPAddress>), it becomes a little nasty (it requires Assembly Qualified Name) :
>$a.gettype().AssemblyQualifiedName
System.Object[], mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
>$b= [System.Net.IPAddress[]] $a
> $b.GetType().AssemblyQualifiedName
System.Net.IPAddress[], System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
>$a = New-Object System.Collections.ObjectModel.Collection"`1[[System.Net.IPAddress, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"What about generic Stack?
> $a.GetType().AssemblyQualifiedName
System.Collections.ObjectModel.Collection`1[[System.Net.IPAddress, System, Vers
ion=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Vers
ion=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
> $a.Add($([System.Net.IPAddress] "192.168.0.1"))
> $a = New-Object System.Collections.Generic.Stack"`1[[System.Net.IPAddres
s, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"
> $a.GetType().AssemblyQualifiedName
System.Collections.Generic.Stack`1[[System.Net.IPAddress, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
> $a.Push($([System.Net.IPAddress] "192.168.0.1"))
> $a.pop()
IPAddressToString : 192.168.0.1
Address : 16820416
AddressFamily : InterNetwork
ScopeId :
IsIPv6Multicast : False
IsIPv6LinkLocal : False
IsIPv6SiteLocal : False
Have Fun
Tags: msh monad PowerShell