Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[MSH] Get-Member doesn't distinguish between array and scalar values

3 views
Skip to first unread message

DontBotherMeWithSpam

unread,
Dec 11, 2005, 1:19:03 PM12/11/05
to
When I do "get-member" for ((get-help get-childitem)."#comment")
command seem to return a string separated by a newline character so I
did the following

**********************
MSH>((get-help get-childitem)."#comment")
Cmdlet syntax section
Cmdlet parameter section
Input - Output section
Error section
Notes section
Example section

MSH>((get-help get-childitem)."#comment") | gm

TypeName: System.String

Name MemberType Definition
---- ---------- ----------
... ... ...
Chars ParameterizedProperty System.Char Chars(Int32 index)
{get;}
Length Property System.Int32 Length {get;}

MSH>((get-help get-childitem)."#comment").Split("`n")
Method invocation failed because
[System.Management.Automation.MshObject[]] doesn't contain a metho
d named 'Split'.
At line:1 char:44
+ ((get-help get-childitem)."#comment").Split( <<<< "`n")

MSH>((get-help get-childitem)."#comment").Length
6

MSH>((get-help get-childitem)."#comment") | foreach { $_ }
Cmdlet syntax section
Cmdlet parameter section
Input - Output section
Error section
Notes section
Example section
**********************

So basically from the output for "get-member", i can't tell if the
returned value is of an array type or of a string type since "gm"
returned "String" for output of ((get-help get-childitem)."#comment").
So I had to check for the length of the return value to see if it is of
an array type or not.

So is there a way to display

**********************
MSH>((get-help get-childitem)."#comment")
TYPE: ArrayList # this line is added by Me

Cmdlet syntax section
Cmdlet parameter section
Input - Output section
Error section
Notes section
Example section
**********************

that "TYPE" information by chance? or any other way to see if the
returned output is of an array or an scalar type.

/\/\o\/\/

unread,
Dec 11, 2005, 1:35:04 PM12/11/05
to
you mean this ?

MSH>(get-help get-childitem)."#comment".getType().isarray
True

gr /\/\o\/\/

DontBotherMeWithSpam wrote:
> When I do "get-member" for ((get-help get-childitem)."#comment")
> command seem to return a string separated by a newline character so I
> did the following
>
> **********************
> MSH>((get-help get-childitem)."#comment")
> Cmdlet syntax section
> Cmdlet parameter section
> Input - Output section
> Error section
> Notes section
> Example section
>
> MSH>((get-help get-childitem)."#comment") | gm
>
> TypeName: System.String
>
> Name MemberType Definition
> ---- ---------- ----------

> .... ... ...

/\/\o\/\/

unread,
Dec 11, 2005, 1:39:33 PM12/11/05
to
if it's array, you need to prefix it with a comma for GM otherwise you
get the types of the array members.

MSH>,((get-help get-childitem)."#comment") | gm


TypeName: System.Management.Automation.MshObject[]


gr /\/\o\/\/

DontBotherMeWithSpam

unread,
Dec 11, 2005, 2:39:07 PM12/11/05
to
Hey, that's exactly what I needed... and the previous comment was
helpful as well :) thanks mow.

But what is the use of "," though? Is there any other usage for that
","?

/\/\o\/\/

unread,
Dec 11, 2005, 3:20:56 PM12/11/05
to

It makes it a list, it is handy with declaring arrays,
but still think it's strange with get-member,
I did run into it here,

http://mow001.blogspot.com/2005/10/strange-behavour-of-get-member-on.html

got an answer from Jefrey Snover I posted here :

http://mow001.blogspot.com/2005/11/create-system-variable-from-msh-part2.html

by now I'm used to it but still think GM's behavour with arrays is a bit
clumsy, as with types.
with .NET collections it's just the opposite, they are to much scalar in
MSH (imho).

maybe somebody of the team could give an better explanation on why.

/\/\o\/\/

unread,
Dec 11, 2005, 4:22:17 PM12/11/05
to

as I think again (and did read the answer of JS again) excualy the
behavour of GM is not strange,
as we use the pipeline to feed it.

this will also work :

gm -i (get-help get-childitem)."#comment"

why the comma works is, that you make a list of 1 element
that then get's enumerated in the pipeline.

so the "strange" thing would be system.collection namespace behavour ;-)

MSH>$ht = @{}
MSH>$ht.add(2,"two")
MSH>$ht.add(1,"one")
MSH>$ht | gm


TypeName: System.Collections.Hashtable

/\/\o\/\/

unread,
Dec 11, 2005, 4:33:50 PM12/11/05
to

>
> so the "strange" thing would be system.collection namespace behavour ;-)
>
> MSH>$ht = @{}
> MSH>$ht.add(2,"two")
> MSH>$ht.add(1,"one")
> MSH>$ht | gm
>
>
> TypeName: System.Collections.Hashtable
>
> gr /\/\o\/\/

but than again ..... maybe not (c) LSL.

or the GM is strange, above is normal

and this IS stange :

MSH>$ht | foreach {$_} | gm


TypeName: System.Collections.Hashtable

gr /\/\o\/\/

sory about the multiple posting, but it got me in a loop a bit.(again)
should the pipeline enum or only foreach.

James Truher [MSFT]

unread,
Dec 11, 2005, 11:28:46 PM12/11/05
to
This is one of those things that sometimes catches folks off guard. One of
the things we tried to do with monad was to provide a streaming behavior for
commands; it would be no good as a shell if you typed:

MSH> get-childitem -recurse c:\windows

and had to wait until all of the data was collected before you started
showing results. So with this need firmly in hand, we made a number of
decisions about how we deal with collections, e.g., when we pipe a
collection, we shred it into it's component elements and pass those elements
to the next member of the pipeline. This way we ensure streaming behavior,
a good example of this is:

MSH> get-process | where { $_.handlecount -gt 400 } | where {
$_.VirtualMemorySize -gt 40M } | table name,handlecount,virtualmemorysize

because we shred the process collection into it's individual process
objects, we can do our filtering and even our output in stages, which means
you get to see output sooner rather than later (very important for a shell
user).

With this in mind, when you type:

MSH> 1,2,3,4 | gm

what's really happening is that the array is shreded and the _elements_ are
being passed to get-member. (very early on, get-member returned something
for _each_ object, but we saw that this wasn't particular useful, so now we
return something for each unique type)

Now, the reason that

MSH> ,(1,2,3,4)|gm

works is that we're now shreding an array; the first element being null and
the second element is the collection that we want to use with get-member.

We looked at all sorts of heuristics to determine whether we should or
should not shred, each resulting in worse behavior (or worst, precluding
behavior that you might want) and in the end, we thought that it would be
better solved as an education problem rather than an attempt at
mind-reading.

I hope knowing our thinking helps...

--
James W. Truher [MSFT]
Monad Program Management
Microsoft Corporation
This posting is provided "AS IS" with no warranties, and confers no rights.

"/\/\o\/\/" <n...@Spam.mow> wrote in message
news:%23RZPTKo$FHA....@TK2MSFTNGP14.phx.gbl...

Keith Hill

unread,
Dec 12, 2005, 3:50:56 PM12/12/05
to
> We looked at all sorts of heuristics to determine whether we should or
> should not shred, each resulting in worse behavior (or worst, precluding
> behavior that you might want) and in the end, we thought that it would be
> better solved as an education problem rather than an attempt at
> mind-reading.
 
In general I really like that MSH shreds collections.  However rather than creating a data structure to "work around" MSH's "shred the collection" behavior it would be nice if there were a way to tell MSH not to shred a particular collection.  This kind of reminds me of Lisp's ability to tell the evaluator to not evaluate an expression in place.  I think you prepend the expressions with " #' " to indicate this.  I wonder if you could do something similar to tell MSH not to shred e.g.:
 
MSH> #{ (get-help get-childitem)."#comment" } | gm
 
or
 
MSH> (get-help get-childitem)."#comment" -NoShredI | gm
 
or
 
MSH> (get-help get-childitem)."#comment" -| gm
 
From a total characters typed metric these aren't much (if any) better but at least they don't create unecessarys object to work around the "shred collections" by default behavior.  The last example above (using -|) is somewhat interesting in that you could use variations of "|" to direct pipelining behavior like tee'ing e.g.:
 
MSH> dir c:\temp    |>  dir.log | sort LastWriteTime
MSH> dir c:\windows |>> dir.log | sort LastWriteTime
 
Just some thoughts.  Yeah, yeah I realize you guys are probably at a stage where the last thing you need is more "design change" ideas.  :-)
 
--
Keith

 

Jeffrey Snover [MSFT]

unread,
Dec 14, 2005, 8:45:33 AM12/14/05
to
> Just some thoughts.  Yeah, yeah I realize you guys are probably at a stage where the last thing you
> need is more "design change" ideas.  :-)
There's always version 2.

--
Jeffrey Snover [MSFT]
Monad Architect
Microsoft Corporation
This posting is provided "AS IS" with no warranties, no confers rights.
 
0 new messages