Windows Vista Forums
Vista Forums Home Join Vista Forums Donate Vista Tutorials Tags

Welcome to Vista Forums we are your forum to discuss Windows Vista x64 and x86 systems. Whether you need help or just want to post an idea you have on Vista, this is the forum for you.
Register at Vista forums...the world biggest Windows Vista resource Join Vista Forums Now

Go Back   Vista Forums > Microsoft Technical Newsgroups > PowerShell

Invoking an object reference to a command?

Update your Vista Drivers Update Your Drivers Now!!
Closed Thread
 
Thread Tools Display Modes
Old 09-11-2006   #1 (permalink)
Alex K. Angelopoulos [MVP]
Guest


 

Invoking an object reference to a command?

I decided to explore directly filling cmdlet parameters as a way to
construct pipeline elements, but it doesn't appear to work. Is there a way
to do what I'm trying below, or is this A Very Bad Idea?

# First, we load the assembly containing the standard cmdlet
definitions:
[reflection.assembly]::LoadWithPartialName("System.Management.Automation")
# Get a reference to GetCommand...
$GetCommandCommand = New-Object
Microsoft.PowerShell.Commands.GetCommandCommand
# Set a parameter value:
$GetCommandCommand.Verb = "Remove"
# now invoke it:
$GetCommandCommand.Invoke()

Exception calling "Invoke" with "0" argument(s): "Late bound operations
cannot be performed on types or methods for which
ContainsGenericParameters is true."
At line:1 char:26
+ $GetCommandCommand.Invoke( <<<< )

Is there a way to 'construct' pipeline elements like this?




My System SpecsSystem Spec
Old 09-12-2006   #2 (permalink)
Lee Holmes [MSFT]
Guest


 

Re: Invoking an object reference to a command?

The Invoke() syntax is meant to be used from C# or other .Net languages.

--
Lee Holmes [MSFT]
Windows PowerShell Development
Microsoft Corporation
This posting is provided "AS IS" with no warranties, and confers no rights.


"Alex K. Angelopoulos [MVP]" <aka@online.mvps.org> wrote in message
news:e%236uc%23g1GHA.4388@TK2MSFTNGP03.phx.gbl...
>I decided to explore directly filling cmdlet parameters as a way to
>construct pipeline elements, but it doesn't appear to work. Is there a way
>to do what I'm trying below, or is this A Very Bad Idea?
>
> # First, we load the assembly containing the standard cmdlet
> definitions:
>
> [reflection.assembly]::LoadWithPartialName("System.Management.Automation")
> # Get a reference to GetCommand...
> $GetCommandCommand = New-Object
> Microsoft.PowerShell.Commands.GetCommandCommand
> # Set a parameter value:
> $GetCommandCommand.Verb = "Remove"
> # now invoke it:
> $GetCommandCommand.Invoke()
>
> Exception calling "Invoke" with "0" argument(s): "Late bound operations
> cannot be performed on types or methods for which
> ContainsGenericParameters is true."
> At line:1 char:26
> + $GetCommandCommand.Invoke( <<<< )
>
> Is there a way to 'construct' pipeline elements like this?
>
>
>



My System SpecsSystem Spec
Old 09-12-2006   #3 (permalink)
Alex K. Angelopoulos [MVP]
Guest


 

Re: Invoking an object reference to a command?

So? PowerShell is a .NET language.
Oh, you mean _compiled_ languages... :|

Is the non-exposure intentional, and if so, why? Is this is a location where
attempting "late binding" could open a significant security/stability hole?


"Lee Holmes [MSFT]" <lee.holmes@online.microsoft.com> wrote in message
news:eyl8kKo1GHA.4648@TK2MSFTNGP04.phx.gbl...
> The Invoke() syntax is meant to be used from C# or other .Net languages.
>
> --
> Lee Holmes [MSFT]
> Windows PowerShell Development
> Microsoft Corporation
> This posting is provided "AS IS" with no warranties, and confers no
> rights.
>
>
> "Alex K. Angelopoulos [MVP]" <aka@online.mvps.org> wrote in message
> news:e%236uc%23g1GHA.4388@TK2MSFTNGP03.phx.gbl...
>>I decided to explore directly filling cmdlet parameters as a way to
>>construct pipeline elements, but it doesn't appear to work. Is there a way
>>to do what I'm trying below, or is this A Very Bad Idea?
>>
>> # First, we load the assembly containing the standard cmdlet
>> definitions:
>>
>> [reflection.assembly]::LoadWithPartialName("System.Management.Automation")
>> # Get a reference to GetCommand...
>> $GetCommandCommand = New-Object
>> Microsoft.PowerShell.Commands.GetCommandCommand
>> # Set a parameter value:
>> $GetCommandCommand.Verb = "Remove"
>> # now invoke it:
>> $GetCommandCommand.Invoke()
>>
>> Exception calling "Invoke" with "0" argument(s): "Late bound
>> operations cannot be performed on types or methods for which
>> ContainsGenericParameters is true."
>> At line:1 char:26
>> + $GetCommandCommand.Invoke( <<<< )
>>
>> Is there a way to 'construct' pipeline elements like this?
>>
>>
>>

>
>



My System SpecsSystem Spec
Old 09-12-2006   #4 (permalink)
Jeffrey Snover [MSFT]
Guest


 

Re: Invoking an object reference to a command?

The issues is that you need to set COMMANDRUNTIME to an instance of a
runspace before you can call Invoke().

--
Jeffrey Snover [MSFT]
Windows PowerShell Architect
Microsoft Corporation
This posting is provided "AS IS" with no warranties, and confers no rights.


"Alex K. Angelopoulos [MVP]" <aka@online.mvps.org> wrote in message
news:e%236uc%23g1GHA.4388@TK2MSFTNGP03.phx.gbl...
>I decided to explore directly filling cmdlet parameters as a way to
>construct pipeline elements, but it doesn't appear to work. Is there a way
>to do what I'm trying below, or is this A Very Bad Idea?
>
> # First, we load the assembly containing the standard cmdlet
> definitions:
>
> [reflection.assembly]::LoadWithPartialName("System.Management.Automation")
> # Get a reference to GetCommand...
> $GetCommandCommand = New-Object
> Microsoft.PowerShell.Commands.GetCommandCommand
> # Set a parameter value:
> $GetCommandCommand.Verb = "Remove"
> # now invoke it:
> $GetCommandCommand.Invoke()
>
> Exception calling "Invoke" with "0" argument(s): "Late bound operations
> cannot be performed on types or methods for which
> ContainsGenericParameters is true."
> At line:1 char:26
> + $GetCommandCommand.Invoke( <<<< )
>
> Is there a way to 'construct' pipeline elements like this?
>
>
>



My System SpecsSystem Spec
Old 09-13-2006   #5 (permalink)
Alex K. Angelopoulos [MVP]
Guest


 

Re: Invoking an object reference to a command?

That kind of makes sense, but the _new_ error I get trying this indicates
that CommandRuntime should be an implementation of ICommandRuntime:

PS> $GetCommandCommand.CommandRuntime =
[System.Management.Automation.Runspaces.
RunspaceFactory]::CreateRunspace()
Exception setting "CommandRuntime": "Cannot convert
"System.Management.Automation.Runspaces.LocalRunspace" to
"System.Management.Automation.ICommandRuntime"."
At line:1 char:20
+ $GetCommandCommand.C <<<< ommandRuntime =
[System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace()


"Jeffrey Snover [MSFT]" <jsnover@microsoft.com> wrote in message
news:u5BQ7Wq1GHA.4388@TK2MSFTNGP03.phx.gbl...
> The issues is that you need to set COMMANDRUNTIME to an instance of a
> runspace before you can call Invoke().
>
> --
> Jeffrey Snover [MSFT]
> Windows PowerShell Architect
> Microsoft Corporation
> This posting is provided "AS IS" with no warranties, and confers no
> rights.
>
>
> "Alex K. Angelopoulos [MVP]" <aka@online.mvps.org> wrote in message
> news:e%236uc%23g1GHA.4388@TK2MSFTNGP03.phx.gbl...
>>I decided to explore directly filling cmdlet parameters as a way to
>>construct pipeline elements, but it doesn't appear to work. Is there a way
>>to do what I'm trying below, or is this A Very Bad Idea?
>>
>> # First, we load the assembly containing the standard cmdlet
>> definitions:
>>
>> [reflection.assembly]::LoadWithPartialName("System.Management.Automation")
>> # Get a reference to GetCommand...
>> $GetCommandCommand = New-Object
>> Microsoft.PowerShell.Commands.GetCommandCommand
>> # Set a parameter value:
>> $GetCommandCommand.Verb = "Remove"
>> # now invoke it:
>> $GetCommandCommand.Invoke()
>>
>> Exception calling "Invoke" with "0" argument(s): "Late bound
>> operations cannot be performed on types or methods for which
>> ContainsGenericParameters is true."
>> At line:1 char:26
>> + $GetCommandCommand.Invoke( <<<< )
>>
>> Is there a way to 'construct' pipeline elements like this?
>>
>>
>>

>
>



My System SpecsSystem Spec
Old 09-19-2006   #6 (permalink)
Bruce Payette [MSFT]
Guest


 

Re: Invoking an object reference to a command?

The problem is that there are actually two Invoke() methods - one that takes
a type parameter and one that doesn't. Unfortunately reflection is returning
the generic method as the default when what you want is the non-generic
version. Here's a workaround that will allow this to work. We'll use the
get-process cmdlet in our example. First we create object and then set one
of its parameters

PS (1) > $gps = new-object Microsoft.PowerShell.Commands.GetProcessCommand
PS (2) > $gps.Name="s*"

Now we need to get the method we want to call. First look at the methods

PS (3) > $gps.GetType().GetMethods() |?{$_.name -match "invoke" } | %{"$_"}
System.Collections.Generic.IEnumerable`1[T] Invoke[T]()
System.Collections.IEnumerable Invoke()

We want to call the last one so get that into $m

PS (4) > $m = ($gps.GetType().GetMethods() |?{$_.name -match "invoke" })[-1]

And finally invoke it.

PS (5) > $m.invoke($gps,@())

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
76 3 908 2568 27 0.03 1568 scardsvr
386 9 2324 4468 36 94.72 688 services
21 1 168 400 4 0.05 568 smss
146 5 4024 5960 46 0.13 1520 spoolsv
311 9 37220 1852 1495 1.03 1140 sqlservr
259 6 3572 5264 37 0.23 1460 SRUserService
253 7 3080 5848 65 2.39 880 svchost
504 14 2052 4752 37 4.77 932 svchost
1952 65 15388 25208 138 11.69 1116 svchost
91 5 1352 3288 30 0.17 1192 svchost
122 4 2476 4124 35 0.23 1220 svchost
185 5 2192 4956 36 0.09 1312 svchost
149 5 1424 3748 33 0.03 1640 svchost
96 7 1608 3420 36 0.06 3940 svchost
854 0 0 236 2 121.83 4 System

This works only for cmdlets that derive from Cmdlet however. These cmdlets
that don't require an instance of the engine in order to execute. Ones that
derive from PSCmdlet (and do require the engine instance) will still fail:

PS (9) > $gcc = new-object Microsoft.PowerShell.Commands.GetCommandCommand
PS (10) > $gcc.Verb = "get"
PS (11) > $m = @($gcc.GetType().GetMethods() |?{$_.name -match
"invoke" })[-1]
PS (12) > $m.Invoke($gcc, @())
An error occurred while enumerating through a collection: Cmdlets derived
from PSCmdlet cannot be i
nvoked directly. .
At line:1 char:10
+ $m.Invoke( <<<< $gcc, @())
PS (13) >

Simple cmdlets like get-process can be run stand-alone because they don't
require an active engine instance. Cmdlets like get-command do require an
instance of the engine (in this case, to find all of the other commands)
cannot be run standalone.

As Lee said, this mechanism isn't really intended to be used this way from a
dynamic language since

get-process s*

is much easier than

$gps = new-object Microsoft.PowerShell.Commands.GetProcessCommand
$gps.Name="s*"
$m = @($gps.GetType().GetMethods() |?{$_.name -match "invoke" })[-1]
$m.invoke($gps,@())

or even

$gps = new-object Microsoft.PowerShell.Commands.GetProcessCommand
$gps.Name="s*"
$gps.invoke()

if that worked.

Now - the original problem - incrementally building up a command line from
within a script - we haven't properly fixed that but we have a pretty good
idea of what we want to do (but not for v1 I'm afraid...)

-bruce

--
Bruce Payette [MSFT]
Windows PowerShell Technical Lead
Microsoft Corporation
This posting is provided "AS IS" with no warranties, and confers no rights.
Visit the Windows PowerShell Team blog at:
http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:
http://www.microsoft.com/technet/scr.../hubs/msh.mspx


"Alex K. Angelopoulos [MVP]" <aka@online.mvps.org> wrote in message
news:eD0F$do1GHA.4796@TK2MSFTNGP06.phx.gbl...
> So? PowerShell is a .NET language.
> Oh, you mean _compiled_ languages... :|
>
> Is the non-exposure intentional, and if so, why? Is this is a location
> where attempting "late binding" could open a significant
> security/stability hole?
>
>
> "Lee Holmes [MSFT]" <lee.holmes@online.microsoft.com> wrote in message
> news:eyl8kKo1GHA.4648@TK2MSFTNGP04.phx.gbl...
>> The Invoke() syntax is meant to be used from C# or other .Net languages.
>>
>> --
>> Lee Holmes [MSFT]
>> Windows PowerShell Development
>> Microsoft Corporation
>> This posting is provided "AS IS" with no warranties, and confers no
>> rights.
>>
>>
>> "Alex K. Angelopoulos [MVP]" <aka@online.mvps.org> wrote in message
>> news:e%236uc%23g1GHA.4388@TK2MSFTNGP03.phx.gbl...
>>>I decided to explore directly filling cmdlet parameters as a way to
>>>construct pipeline elements, but it doesn't appear to work. Is there a
>>>way to do what I'm trying below, or is this A Very Bad Idea?
>>>
>>> # First, we load the assembly containing the standard cmdlet
>>> definitions:
>>>
>>> [reflection.assembly]::LoadWithPartialName("System.Management.Automation")
>>> # Get a reference to GetCommand...
>>> $GetCommandCommand = New-Object
>>> Microsoft.PowerShell.Commands.GetCommandCommand
>>> # Set a parameter value:
>>> $GetCommandCommand.Verb = "Remove"
>>> # now invoke it:
>>> $GetCommandCommand.Invoke()
>>>
>>> Exception calling "Invoke" with "0" argument(s): "Late bound
>>> operations cannot be performed on types or methods for which
>>> ContainsGenericParameters is true."
>>> At line:1 char:26
>>> + $GetCommandCommand.Invoke( <<<< )
>>>
>>> Is there a way to 'construct' pipeline elements like this?
>>>
>>>
>>>

>>
>>

>
>



My System SpecsSystem Spec
Old 09-19-2006   #7 (permalink)
Alex K. Angelopoulos [MVP]
Guest


 

Re: Invoking an object reference to a command?

"Bruce Payette [MSFT]" <brucepay@microsoft.com> wrote in message
news:OuyeSC82GHA.4648@TK2MSFTNGP04.phx.gbl...

> Now - the original problem - incrementally building up a command line from
> within a script - we haven't properly fixed that but we have a pretty good
> idea of what we want to do (but not for v1 I'm afraid...)


Good enough; it's on the list.


My System SpecsSystem Spec
Closed Thread

Thread Tools
Display Modes



Similar Threads
Thread Thread Starter Forum Replies Last Post
datalist -- Object reference not set to an instance of an object. Deere .NET General 0 08-31-2008 09:09 AM
Variable within Object Reference Line tReg VB Script 7 08-08-2008 12:32 AM
Powershell Object Reference LCC Admin PowerShell 0 07-16-2008 01:22 PM
How TO: Reference an Object Property in a String Brandon Shell PowerShell 2 08-17-2006 03:38 PM
False IE doc body error - "Object reference not set to an instance of an object" Alex K. Angelopoulos [MVP] PowerShell 7 07-15-2006 09:46 PM


Update your Vista Drivers Update Your Drivers Now!!

Vistax64.com is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
© Designer Media 2005-2008