{"id":53,"date":"2009-02-07T22:37:19","date_gmt":"2009-02-08T05:37:19","guid":{"rendered":"http:\/\/jameskovacs.com\/2009\/02\/08\/PowerShell+Processes+And+Piping"},"modified":"2009-02-07T22:37:19","modified_gmt":"2009-02-08T05:37:19","slug":"powershell-processes-and-piping","status":"publish","type":"post","link":"https:\/\/www.jameskovacs.com\/index.php\/2009\/02\/07\/powershell-processes-and-piping\/","title":{"rendered":"PowerShell, Processes, and Piping"},"content":{"rendered":"<p><a href=\"2009\/02\/01\/Getting-Started-With-PowerShell-Developer-Edition\">Last time<\/a>, I discussed why you as a developer might be interested in PowerShell and gave you some commands to start playing with. I said we\u2019d cover re-usable scripts, but I\u2019m going to delay that until next post as I want to talk more about life in the shell\u2026<\/p>\n<p>PowerShell feels a lot like cmd.exe, but with a lot more flexibility and power. If you\u2019re an old Unix hack like me, you\u2019ll appreciate the ability to combine (aka pipe) commands together to do more complex operations. Even more powerful than Unix command shells is the fact that rather than inputting\/outputting strings as Unix shells do, PowerShell inputs and outputs objects. Let me prove it to you\u2026<\/p>\n<ol>\n<li>At a PowerShell prompt, run \u201cget-process\u201d to get a list of running processes. (Remember that PowerShell uses single nouns for consistency.)<\/li>\n<li>Use an array indexer to get the first process: \u201c(get-process)[0]\u201d (The parentheses tell PowerShell to run the command.)<\/li>\n<li>Now let\u2019s get really crazy\u2026 \u201c(get-process)[0].GetType().FullName\u201d<\/li>\n<\/ol>\n<p>As a .NET developer, you should recognize \u201c.GetType().FullName\u201d. You\u2019re getting the class object (aka System.Type) for the object returned by (get-process)[0] and then asking it for its type name. What does this command return?<\/p>\n<p><a href=\"\/wp-content\/uploads\/WindowsLiveWriter\/WritingPowerShellScripts_12E74\/image_2.png\"><img loading=\"lazy\" decoding=\"async\" title=\"image\" style=\"border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px\" height=\"75\" alt=\"image\" src=\"\/wp-content\/uploads\/WindowsLiveWriter\/WritingPowerShellScripts_12E74\/image_thumb.png\" width=\"466\" border=\"0\"><\/a> <\/p>\n<p>That\u2019s right! The PowerShell command, get-process, returns an array of System.Diagnostics.Process objects. So anything you can do to a Process object, you can do in PowerShell. To figure out what else we can do with a Process object, you can look up your MSDN docs or just ask PowerShell itself.<\/p>\n<p>get-member \u2013inputObject (get-process)[0]<\/p>\n<p>Out comes a long list of methods, properties, script properties, and more. Methods and properties are the ones defined on the .NET object. Script properties, alias properties, property sets, etc. are defined as object extensions by PowerShell to make common .NET objects friendlier for scripting.<\/p>\n<p>Let\u2019s try something more complex and find all processes using more than 200MB of memory:<\/p>\n<p>get-process | where { $_.PrivateMemorySize \u2013gt 200*1024*1024 }<\/p>\n<p>Wow. We\u2019ve got a lot to talk about. The pipe (|) takes the objects output from get-process and provides them as the input for the next command, where \u2013 which is an alias for Where-Object. Where requires a scriptblock denoted by {}, which is PowerShell\u2019s name for a lambda function (aka anonymous delegate). The where command evaluates each object with the scriptblock and passes along any objects that return true. $_ indicates the current object. So we\u2019re just looking at Process.PrivateMemorySize for each process and seeing if it is greater than 200 MB.<\/p>\n<p>Now why does PowerShell use \u2013gt, \u2013lt, \u2013eq, etc. for comparison rather than &gt;, &lt;, ==, etc.? The reason is that for decades shells have been using &gt; and &lt; for input\/output redirection. Let\u2019s write to the console:<\/p>\n<p>\u2018Hello, world!\u2019<\/p>\n<p>Rather than writing to the console, we can redirect the output to a file like this:<\/p>\n<p>\u2018Hello, world!\u2019 &gt; Hello.txt<\/p>\n<p>You\u2019ll notice that a file is created called Hello.txt. We can read the contents using Get-Content (or its alias, type).<\/p>\n<p>get-content Hello.txt<\/p>\n<p><a href=\"\/wp-content\/uploads\/WindowsLiveWriter\/WritingPowerShellScripts_12E74\/image_4.png\"><img loading=\"lazy\" decoding=\"async\" title=\"image\" style=\"border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px\" height=\"109\" alt=\"image\" src=\"\/wp-content\/uploads\/WindowsLiveWriter\/WritingPowerShellScripts_12E74\/image_thumb_1.png\" width=\"429\" border=\"0\"><\/a> <\/p>\n<p>Since &gt; and &lt; already have a well-established use in the shell world, the PowerShell team had to come up with another syntax for comparison operators. They turned to Unix once again and the test command. The same operators that have been used by the Unix test command for 30 years are the same ones as used by PowerShell.*<\/p>\n<p>So helpful tidbits about piping and redirection\u2026<\/p>\n<ul>\n<li>Use pipe (|) to pass objects returned by one command as input to the next command.<\/li>\n<ul>\n<li>ls | where { $_.Name.StartsWith(\u2018S\u2019) }<\/li>\n<\/ul>\n<li>Use output redirection (&gt;) to redirect the console (aka stdout) to a file. (N.B. This overwrites the destination file. You can use &gt;&gt; to append to the destination file instead.)<\/li>\n<ul>\n<li>ps &gt; Processes.txt<\/li>\n<\/ul>\n<li>Do not use input redirection (&lt;) as it is not implemented in PowerShell v1. <img decoding=\"async\" alt=\"smile_sad\" src=\"http:\/\/spaces.live.com\/rte\/emoticons\/smile_sad.gif\"><\/li>\n<\/ul>\n<p>So there you have it. We can now manipulate objects returned by PowerShell commands just like any old .NET object, hook commands together with pipes, and redirect output to files. Happy scripting!<\/p>\n<p>* From <a href=\"http:\/\/www.amazon.com\/gp\/product\/1932394907?ie=UTF8&amp;tag=jamkovweb-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=1932394907\"><em>Windows PowerShell in Action<\/em><\/a> by Bruce Payette p101. This is a great book for anyone experimenting with PowerShell. It has lots of useful examples and tricks of the PowerShell trade. Highly recommended.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Last time, I discussed why you as a developer might be interested in PowerShell and gave you some commands to start playing with. I said we\u2019d cover re-usable scripts, but I\u2019m going to delay that until next post as I want to talk more about life in the shell\u2026 PowerShell feels a lot like cmd.exe, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[16],"tags":[],"class_list":["post-53","post","type-post","status-publish","format-standard","hentry","category-powershell"],"_links":{"self":[{"href":"https:\/\/www.jameskovacs.com\/index.php\/wp-json\/wp\/v2\/posts\/53","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.jameskovacs.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.jameskovacs.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.jameskovacs.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jameskovacs.com\/index.php\/wp-json\/wp\/v2\/comments?post=53"}],"version-history":[{"count":0,"href":"https:\/\/www.jameskovacs.com\/index.php\/wp-json\/wp\/v2\/posts\/53\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.jameskovacs.com\/index.php\/wp-json\/wp\/v2\/media?parent=53"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jameskovacs.com\/index.php\/wp-json\/wp\/v2\/categories?post=53"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jameskovacs.com\/index.php\/wp-json\/wp\/v2\/tags?post=53"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}