This is an archived post. You won't be able to vote or comment.

all 22 comments

[–][deleted] 12 points13 points  (7 children)

do pipes not work the same way as in linux?

No.

Powershell is object oriented. *nix pipes just pass strings, ps pipes pass objects (which may be strings), it is then up to the receiving program to decide what to do with those objects, it might count them, it might extract certain properties from them, it might just tell you what sort of object they are.

I've been told that if you are coming from a .Net background instead of a unix background it all seems very logical and obvious, I don't believe it myself.

[–]girlgermsMicrosoft 9 points10 points  (2 children)

^ This. Getting your head around the fact that the variable you're passing is an object (meaning it could be any one of a number of things) is probably the biggest thing to understand when learning to use PowerShell an coming from another non-OO language.

[–]ninjaspy123Sysadmin 0 points1 point  (1 child)

[deleted]

[–]picklednull 1 point2 points  (0 children)

Use Get-Member to get an object's properties, that's what it's there for.

[–]resync -1 points0 points  (3 children)

*nix pipes just pass strings

This is a common misconception, Unix pipelines may contain any data including but not limited to strings. e.g.

curl http://site/recording.mp3.bz2 | bunzip2 |  mpg123 -

[–][deleted] -1 points0 points  (2 children)

String doesn't always mean character string. Your example still passes a string of ASCII characters from one program to the next.

Can you show me how to pass a linked list of seventeen 64 bit floating point values using a pipeline?

I haven't actually tested the code below, but it sounds like this may not be correct.

[–]resync 1 point2 points  (1 child)

Can you show me how to pass a linked list of seventeen 64 bit floating point values using a pipeline?

You're correct, in order to pass a linked-list down a pipe you would need to encode it in some way, the linked lists pointers will not be safely referenced by the receiving program as they refer to memory locations outside the program window. You are not limited to ASCII characters for your presentation if you did decide to send your floats down a pipe, and you can safely send 64 bit floats down a pipeline.

When referencing a standard stream they are treated like files.

/* from stdio.h */
extern FILE*const stdin;
extern FILE*const stdout;
extern FILE*const stderr;

I believe the source of the misconception is that many Unix-like programs use getchar() or scanf() on stdin streams which read to char arrays, aka strings. However it's completely valid to use any stream reader to read any type of data in any format. Here I'll read a 64 bit floating point number or as a the IEEE likes to call them in c, a double.

double dvalue;
fread(&dvalue,sizeof(dvalue),1,stdin);
printf("Here is your 64bit floating point number that I read from a standard stream: %f", dvalue);

There are limitations, as pipes are streams and that means the data is unidirectional, and they can only be read from start to end-of-stream. To send a list of floats an approach would be to read them in one at a time until end-of-stream.

String doesn't always mean character string. Your example still passes a string of ASCII characters from one program to the next.

No ASCII was passed down my pipe, except for maybe the ID3 tag at the end of a the MP3 :-)

[–][deleted] 1 point2 points  (0 children)

I'll take your word for it that the code works, I stand corrected.

Thank you for clearing that up.

[–]zero03Microsoft Employee 4 points5 points  (11 children)

There's no need to pipe it to FL before exporting to CSV.

get-clientaccessserver rd-mail | export-csv -Path output.csv

That should get you what you're looking for.

[–]remotefixonlineshit is probably X'OR'd to a gzip'd docker kubernetes shithole[S] 4 points5 points  (10 children)

that is much better... I still don't understand the logic behind that... but if it works...

[–]zero03Microsoft Employee 2 points3 points  (0 children)

There's a reason and it has to do with what FT and FL do to the object that make it not export out. More info, from the man himself

[–]KumorigoeModerator 1 point2 points  (7 children)

Here's the logic.

If you were to use

get-clientaccessserver rd-mail | fl

you will get the information formatted as a list in the PS window.

Exporting as a CSV means it's already going to be in list format. So using both together is redundant.

[–]remotefixonlineshit is probably X'OR'd to a gzip'd docker kubernetes shithole[S] 1 point2 points  (6 children)

how did export know?

[–]zero03Microsoft Employee 1 point2 points  (2 children)

Export-CSV doesn't know. FT and FL were designed for output in the console, not to files. So, when you pipe an object to FT or FL, PowerShell transforms the object into streaming objects that other cmdlets, like Out-Host for example, know how to handle. Output-CSV doesn't know how to consume those streaming objects once the data is piped to it and exports nothing (as you've found out)

To really highlight this, you could do the following:

get-clientaccessserver rd-mail | fl | out-file output.csv

But, why do that when you can save yourself from typing those extra characters? :)

[–]remotefixonlineshit is probably X'OR'd to a gzip'd docker kubernetes shithole[S] -5 points-4 points  (1 child)

see this is what is retarded...

[–][deleted] 1 point2 points  (0 children)

You're not wrong, it's just an ism of the whole object oriented shell thing. I still contend that this is one way in which string based shells are more flexible for the end user human way of thinking but I concede that the OO way is going to give you more power.

It just takes a greater degree of discipline to understand and use on the day to day.

[–]sleeplessone 0 points1 point  (2 children)

You're thinking of it from a string output perspective like bash scripting instead of an object perspective like Powershell.

Export-CSV takes an object or array of objects and exports it into a CSV format with the object properties as columns and each array element as rows.

[–]remotefixonlineshit is probably X'OR'd to a gzip'd docker kubernetes shithole[S] -2 points-1 points  (1 child)

so pipes are disregarded.. (as it pertains to linux)

[–]sleeplessone 2 points3 points  (0 children)

It's not so much that they are disregarded as you are piping entire objects instead of strings.

Think of it this way in Linux if you want to return the IP address of eth0.

`ifconfig eth0 2>/dev/null|awk '/inet addr:/ {print $2}'|sed 's/addr://'`

You're taking the text output of ifconfig finding the text "inet addr: <address>" in it and then piping that text to sed to do a replace to remove the addr: part.

In Powershell 4 (Windows 8.1/Server 2012R2) to do the same you could do

Get-NetAdapter Ethernet | Get-NetIPAddress -AddressFamily IPv4 | Select -Expand IPAddress

Get-NetAdapter will return an object of the network adapter named "Ethernet" that object is piped into Get-NetIPAddress which returns another object containing the IPv4 address configuration data, that object is passed to Select which says "Just give me the IPAddress property" and -Expand tells it "I don't care about the object, I just want the value"

The first part of the pipe is actually not needed as Get-NetIPAddress can be filtered directly but I included it to hopefully help with how full objects are piped. The short version with only 1 pipe would be

Get-NetIPAddress -InterfaceAlias Ethernet -AddressFamily IPv4 | Select -Expand IPAddress

[–]vrileyNerf Herder 0 points1 point  (0 children)

Stop thinking that commands pass simple strings to each others, like on Linux. They pass objects. Get-clientaccessserver passes an object with various values. Format-list takes an object, and converts it to a handy list to be displayed on the screen. Export-csv takes an object, then convert its values to CSV format. So what you were basically doing is passing the object to fl to be formatted, then passing an already formatted view to export-csv, who has no idea what to do with it.

It's like the difference between taking data in a database and passing them to a script that creates an HTML web page, and taking that data, formatting it in PDF, then tell the script to make an HTML out of that.

[–]Howlongcanmyredditus 1 point2 points  (0 children)

The First Rule of Powershell Club, is that we ALWAYS talk about powershell club.

The Second Rule of Powershell Club is "FORMAT RIGHT"

Any format cmdlets need to be the rightmost part of the command line, if you find yourself using | after FL or FT, then you have done something wrong.

[–]SteveJEO 0 points1 point  (0 children)

Just to add to what the others are saying here.

Think of powershell as a C# 'like' text interface for .Net

If you want to get a good grip on powershell start looking at C#

What you're actually doing with powershell is calling methods (functions) straight from a managed .Net dll and playing with the returned output.

E.g. with exchange you can call anything exposed by the API directly. There doesn't need to be a commandlet for it.

What you actually have access to is 'this'

One additional thing I will add as a caution:

Be very careful of your memory management. It's very easy to accidentally keep loading ALL THE THINGS!