Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I'm learning PowerShell, so I'm doing stuff like this a lot:

Get-Command | Out-String -Stream | ss child 

(ss is an alias for select-string).

I'm getting tired of typing Out-string -Stream all the time, so in Unix I'd just create an alias for it. However this doesn't work in Powershell.

  • I created it as an alias, and it errored out (I think I understand that).
  • I created it as a function, but it swallows all my output
  • I created it as a filter, and that also produced no output.

How can I do this?


Using *child* as the argument is probably the best way to do this particular task, but I'm really using this as an example to learn how to write PS functions.

I just want the function to replace the 'Out-string -Stream' part, so that instead of:

Get-Command | Out-String -Stream | ss child   

I'll be able to write:

Get-Command | oss | ss child 

I'm guessing I need to use ValueFromPipeline, or the $input variable, like Matt shows.


Okay, I got it. I guess I need to explicitly say to read from the pipeline. Instead of:

function oss { Out-String -Stream } 

I need to say:

function oss { $input | Out-String -Stream } 

I wonder how I missed that in the documentation?

share|improve this question
1  
I will poke around and see if I can find an answer to your question. In the meantime however, I suspect that there is a better way to get the same result: Get-Command *child* – EBGreen Jul 23 '11 at 7:39
1  
In PowerShell 3, oss is pre-defined for you. – jeatsy Mar 3 '13 at 1:05
up vote 1 down vote accepted

What do you mean a function swallows all your output?

I tried this and get the same outputs:

function MySS {
    [cmdletbinding()]
    param (
        [string] $SearchString
    )
    Process {
        Get-Command | Out-String -Stream | Select-String -Pattern $SearchString
    }
}

Running Get-Member and GetType on the output return the same form the function and piped command.

EDIT: If you wanted to us other originating functions

function MySS2 {
    [cmdletbinding()]
    param (
        [Parameter(
                    Mandatory = $True,
                    ValueFromPipeline = $true)]
        $input,
        [Parameter(
                    Mandatory = $True,
                    ValueFromPipeline = $false,
            Position = 0)]
        [string] $SearchString
    )
    Process {
        $input | Out-String -Stream | Select-String -Pattern $SearchString
    }
}

e.g.

Get-Command | MySS2 "Get"
get-help get-alias | MySS2 "Get"

EDIT: simplest form (select string commented out):

function MyOSS {
    param ($input)
    $input | Out-String -Stream #| Select-String "Get"
}

EDIT: final edit i think! :-)

I see you figured it out yourself Jonathan - glad to have helped and I didn't know you could use $input without declaring it as a parameter. That's cool.

share|improve this answer
    
'Swallow my output' means that when I run Get-Command I get screens of output written to my screen, but when I run Get-Command | oss, I get no output written to screen. (I'm using ISE, if that matters). – jonathan Jul 23 '11 at 13:53
    
I should add that my function looks like function oss { Out-String -Stream} and then filter oss { Out-String -Stream} – jonathan Jul 23 '11 at 13:55
    
Do I really need to resort to cmdletbinding just to read from and write to the pipeline? – jonathan Jul 23 '11 at 14:07
    
No, it'll work without - I always add cmdletbinding when doing a function though - mainly for write-verbose. – Matt Jul 25 '11 at 12:00
    
the function function oss { Out-String -Stream} doesn't do anything - there's no variable processing etc... – Matt Jul 25 '11 at 12:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .