Author Posts

September 18, 2013 at 7:59 am

Code below do not work over remoting but works fine on console. No errors are thrown but nothing being on remote server. I suspect it has something to do with pipeline not working correctly on remote session and not passing "name" parameter to Restart-WebApppool

PS C:\Users\gsuvalian\desktop> Invoke-Command server {import-module WebAdministration; gci IIS:\\apppools | % Restart-WebAppPool } -cred $cred

Code below works though

PS C:\Users\gsuvalian\desktop> Invoke-Command server {import-module WebAdministration; gci IIS:\\apppools | % {Restart-WebAppPool $_.name} } -cred $cred

Directly on remote console code below works as well

$gci IIS:\\apppools | % Restart-WebAppPool

On a separate note why code above works but not code below

$gci IIS:\\apppools | % {Restart-WebAppPool}

September 18, 2013 at 8:36 am

% is an alias for ForEach-Object. I haven't used these IIS-related commands before, but you may not need ForEach-Object at all. Try this (both in remoting and locally):


gci IIS:\apppools | Restart-WebAppPool

Invoke-Command server {import-module WebAdministration; gci IIS:\apppools | Restart-WebAppPool } -cred $cred

If you do use ForEach-Object, then you need to do something with "$_" inside your script block, such as the gci IIS:\\apppools | % {Restart-WebAppPool $_.name} part of your second example.

September 18, 2013 at 8:41 am

Interesting, removing "%,Foreach-object" does work in both cases (remotely and on console).
Wondering what is going on in background. So powershell when piping any collection to another cmdlet automatically assumes that you want to iterate through collection? It might be good that Powershell is dumbed down to this level but that's really not very intuitive (at least for me).
Why "Foreach-object" refuses to work also a mistery.

September 18, 2013 at 8:56 am

You really only need ForEach-Object if you're doing something more complex, or if the command you want to pipe input to does not support pipeline input. Restart-WebAppPool does support piping the -Name argument by property name, and the objects output by your Get-ChildItem command have a Name property that is exactly what you needed. The end result of these two commands are identical (though the ForEach-Object version will not execute as fast):


gci IIS:\apppools | Restart-WebAppPool

gci IIS:\apppools | ForEach-Object { Restart-WebAppPool -Name $_.Name }

There's technically no "collection" in either of those commands. The pipeline works by streaming one object at a time, and at no point are the entire results of Get-ChildItem saved in a collection. However, PowerShell does do some behind the scenes work when it comes to actual collections and the pipeline. For example:

# set up our array
$directories = @('C:\', 'C:\Windows','C:\Program Files')

# Pipe the array to a command
$directories | Get-ChildItem

In this case, PowerShell isn't sending the array object itself to Get-ChildItem; it automatically sends the objects contained in the array, one at a time.

There's a lot of information on this topic in the about_Pipelines help file.