2

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?

2
  • 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, 2011 at 7:39
  • 1
    In PowerShell 3, oss is pre-defined for you.
    – jeatsy
    Mar 3, 2013 at 1:05

2 Answers 2

2

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.

6
  • '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, 2011 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, 2011 at 13:55
  • Do I really need to resort to cmdletbinding just to read from and write to the pipeline?
    – jonathan
    Jul 23, 2011 at 14:07
  • No, it'll work without - I always add cmdletbinding when doing a function though - mainly for write-verbose.
    – Matt
    Jul 25, 2011 at 12:00
  • the function function oss { Out-String -Stream} doesn't do anything - there's no variable processing etc...
    – Matt
    Jul 25, 2011 at 12:01
1

FWIW:

  • I've been using this grep replacement function for, well, as long as I've been using PowerShell :

    function grep { $input | out-string -stream | sls $args }

  • Current versions of PowerShell (>=3.0) have both an alias for Select-String (sls) and a shortcut function for Out-String -Stream (oss). Get-Command also has its own alias, gcm. Thus the standard abbreviated form for your command is gcm | oss | sls child

  • Wildcards are allowed in Get-Command's name parameter, which means gcm *child* basically does it (and is of course much faster)

You must log in to answer this question.

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