locked
grokking the gist of "the powershell" RRS feed

  • General discussion

  • Not sure if this is the right place for this question, so apologies in advance if this is unwarranted.

    Just wanted to ask for some “resolution” as to why PS infuriates me so much, because I understand that with any language there are decisions and trade offs.

     However I just want to know why powershell seems so unintuitive? Is it because I’m more of a developer and not a system administrator? The conflict being that I find myself more and more in devops roles that cross many boundaries.

     Just a few examples to highlight my frustrations:

    Piping (why/when/what can/cannot be piped still eludes me, I see no rationale)

    “Destructive by default” – eg: something like copy-item important.txt c:\ -recurse – could be devastating... unless you KNOW to put -confirm or more complex structures around it...

    String handling – I’m always getting caught out in my logging by “$obj.FullName” vs “$($obj.FullName)”

     

    Is there any insights into WHY it is the way it is or guidance you can provide on how to GROK powershell so that I don't feel LOST every time I start a new script or look at an existing one – I’ve read a lot but I’m not a 100% scripting guy, so its difficult for me to (a) remember what I’ve learned when I come back to scripts after a while and (b) to find the right resources in the first place to know I’m not straying down the dark side...

     

    Thanks in advance for any input.


    - sure I'm noJedi but that's no reason to stop trying to make stuff levitate! -

    Monday, February 29, 2016 12:49 AM

All replies

  • The answer is pretty much like the answer to understanding any advanced technology.  Start by reading the manual. Once you have done that 90% of your issues will be gone.

    I am a long time developer in many, many languages and many different operating systems.  PowerShell is very intuitive and has been since the beginning. 

    First you have to accept that it is a scripting system and not a language although it comes with a language-like syntax designed to allow us to manage the command environment.

    PowerShell was designed to combine all of the best features of other scripting systems like those on Unix and other systems.  There is not much that is unusual.  The biggest difference between PowerShell and other script systems is that it uses C#-like syntax and the Net classes.  The pipeline exists in Unix and in Windows batch scripts and commands.  PowerShell just adds more to the "pipeline"  and comes with a set of commands that work with the pipeline.

    Reading the manual and taking one of the free online e courses will get you unstuck.


    \_(ツ)_/

    Monday, February 29, 2016 1:10 AM
  • thanks for your reply.

    I do understand that its a scripting language and not a compiled programming language - although, the fact that you explicitly highlight this, perhaps my understanding of the subtitles are not accurate or as solid as I thought...

    I have read the entire User Guide (https://technet.microsoft.com/en-us/library/cc196356.aspx), but it has not revealed such secrets to me as you have described - certainly not 90%! - and I still don't "get it" ... I don't understand the reasons why its done the way it is...

    eg: I understand the "verb-noun" construct, but - to me at least - it makes it difficult to "find things" (nouns)  without knowing of their existence prior to use ( eg: not everything HAS a get/set/other)... perhaps I am not reading the right manuals or there is some kind of magical graph illustrating the various nouns and their HAL-like abstraction domain?... now that'd be handy...

    You imply that its very intuitive, and given some languages out there perhaps your "right" however I think that the "language" is definitely consistent and "predictable" but I can't see how it is intuitive (best example I can find is the syntax of the "$($obj.property)" within strings... that is far from intuitive... again IMO, and everyone is different, so maybe different languages must also have such syntax oddities, and so maybe I just haven't experienced these and find it weird... I program in C# also, but I find it "like" but far from it... further from C# than JavaScript is to Java (again in my opinion))

    I'm NOT trying to argue the stupidity or greatness of one language or the other more trying to get a mental understanding of why the language is like it is so that I can stop struggling against it and understand how to work with it better... hopefully that makes sense and you understand what I'm getting at...!?

    I found this - https://blogs.msdn.microsoft.com/powershell/2007/03/07/why-cant-i-pipe-format-table-to-export-csv-and-get-something-useful/ which I think indicates that I am probably just missing some understanding of which things (for example) "format" the output and which things return "objects" that can be piped... if this is the case then is that just expereince/practice or am I looking for any particular clue in the help pages or "other" resources perhaps?

    Anyway, if you can provide direct examples of why things are "constructed this way" to help me understand the language as a whole and/or suggested links to "free online e-courses" or the "manual" (if you aren't referring to the technet user Guide) that you think would be useful then I think your post in general would be much more useful, thanks!


    - sure I'm noJedi but that's no reason to stop trying to make stuff levitate! -

    Monday, February 29, 2016 6:45 AM
  • On my system:

    S C:\scripts> (get-command *).count
    3353

    How long will it take to learn all of those commands?

    How can I'm use SQL?

    PS C:\scripts> Get-Command -Noun sql*

    CommandType     Name                                               Version    Source
    -----------     ----                                               -------    ------
    Function        Start-SQL
    Cmdlet          Add-SqlAvailabilityDatabase                        1.0        SQLPS
    Cmdlet          Add-SqlAvailabilityGroupListenerStaticIp           1.0        SQLPS
    Cmdlet          Backup-SqlDatabase                                 1.0        SQLPS
    Cmdlet          Decode-SqlName                                     1.0        SQLPS
    Cmdlet          Disable-SqlAlwaysOn                                1.0        SQLPS
    Cmdlet          Enable-SqlAlwaysOn                                 1.0        SQLPS
    Cmdlet          Encode-SqlName                                     1.0        SQLPS
    Cmdlet          Get-SqlCredential                                  1.0        SQLPS
    Cmdlet          Invoke-Sqlcmd                                      1.0        SQLPS
    Cmdlet          Join-SqlAvailabilityGroup                          1.0        SQLPS
    Cmdlet          New-SqlAvailabilityGroup                           1.0        SQLPS
    Cmdlet          New-SqlAvailabilityGroupListener                   1.0        SQLPS
    Cmdlet          New-SqlAvailabilityReplica                         1.0        SQLPS
    Cmdlet          New-SqlCredential                                  1.0        SQLPS
    Cmdlet          New-SqlHADREndpoint                                1.0        SQLPS
    Cmdlet          Remove-SqlAvailabilityDatabase                     1.0        SQLPS
    Cmdlet          Remove-SqlAvailabilityGroup                        1.0        SQLPS
    Cmdlet          Remove-SqlAvailabilityReplica                      1.0        SQLPS
    Cmdlet          Remove-SqlCredential                               1.0        SQLPS
    Cmdlet          Restore-SqlDatabase                                1.0        SQLPS
    Cmdlet          Resume-SqlAvailabilityDatabase                     1.0        SQLPS
    Cmdlet          Set-SqlAvailabilityGroup                           1.0        SQLPS
    Cmdlet          Set-SqlAvailabilityGroupListener                   1.0        SQLPS
    Cmdlet          Set-SqlAvailabilityReplica                         1.0        SQLPS
    Cmdlet          Set-SqlCredential                                  1.0        SQLPS
    Cmdlet          Set-SqlHADREndpoint                                1.0        SQLPS
    Cmdlet          Suspend-SqlAvailabilityDatabase                    1.0        SQLPS
    Cmdlet          Switch-SqlAvailabilityGroup                        1.0        SQLPS
    Cmdlet          Test-SqlAvailabilityGroup                          1.0        SQLPS
    Cmdlet          Test-SqlAvailabilityReplica                        1.0        SQLPS
    Cmdlet          Test-SqlDatabaseReplicaState                       1.0        SQLPS

    You have to read and study a real book or course.  You cannot learn PowerShell beyond how to do simple things with the user quick-guide.

    A good book will take you two hours a day for two weeks.


    \_(ツ)_/

    Monday, February 29, 2016 6:56 AM
  • There are 2 commands you should remember:

    get-help
    get-member

    Try these:

    get-help get-help -online
    get-help get-help -examples
    get-process|Get-Member

    And if your creating a script use powershell ISE
    the crtl-j wil make you happy.

    Tuesday, March 1, 2016 3:17 PM
  • Hi all,

    (DISCLAIMER: I probably failed to explain myself/my problem clearly)

    All excellent resources for beginning to learn the ins/outs of PS, however none of your suggestions seem to be resolving this for me.

    :(

    I have diligently reviewed them all and - while I did learn a thing or two (Yes - Ctrl+J really does make me happy in PS-ISE!), my original questions still remain... :~(

    HOWEVER, In reading and re-reading and (thanks to some of your links) learned some new terms, which in turn helped me enter better search terms into various search engines. So, I'm going to have a crack at (a little tongue in cheek, but still mostly seriously) answering my own question - feel free to correct, add, append, redirect:

    • "reasons" :P
    • writing (and perhaps more relevantly parsing) a language, is difficult and so the PS syntax is the way it is because it made the most sense for the most use cases at the time of designing it
    • the "$($var.property)" syntax is essentially a short cut variable to make it possible to create less variables for string processing, while keeping the " vs ' (double/single) quote parsing as simple as possible for general string handling, rather than the more complex escape character syntax in a lot of programming lanugages- so just learn it...
    • in general a lot of the functions ARE destructive by default because: a) you really should learn how to use -whatif as a habitual best practice for creating scripts and b) a key difference in a scripting language is a focus on GTD (getting things done) so "actions" are made easier by default - yes you have to be more careful - so just learn it...
    • piping works pretty much everywhere, if piping DOESN'T work, then you need to rethink what's happening, because the "object" has probably been converted to text or formatted content at some point that isnt' really an object... and so doesn't make sense to pipe...? (this is a long shot, but is my best explanation on why it sometimes doesn't work... this is probably why you guys suggest get-member as this might somehow hint/show some property that indicates if an item will be PIPE-Able!?)
    • intuitive is fairly subjective - powershell syntax is instead very CONSISTENT, which makes tools like get-member and get-help the core instruments to learning about the elements of powershell and associated modules.

    I don't have any suggestions how NOT to be caught out by "hello $me.Name you forgot the `$() !!" not working the way I think it will... I think you just have to practice and get used to looking harder at ".Anything" in strings and testing thoroughly...


    - sure I'm noJedi but that's no reason to stop trying to make stuff levitate! -

    Tuesday, March 15, 2016 1:50 PM
  • The code coloring of the ISE makes it visually apparent when you need to use a subexpression:


    Tuesday, March 15, 2016 2:04 PM
  • I'm not sure why "destructive by default" is a problem for you. I don't know any other shell commands that don't actually do an operation unless you specify a "no, really do it" parameter. Actually PowerShell is better because -WhatIf is a core part of its ecosystem.


    -- Bill Stewart [Bill_Stewart]

    Tuesday, March 15, 2016 2:31 PM
  • Hi Mike, I had seen this, however, in practice it seems to be too subtle for my eyes... :(

    Maybe when I'm used to it (practice practice practice) I would notice this "absence" of differentiation between the standard text and the .variable alerting me to my error... but so far I've been too focused on the script to notice the error until its too late - but thanks for the suggestion, and like I said perhaps with experience this becomes more obvious...?


    - sure I'm noJedi but that's no reason to stop trying to make stuff levitate! -

    Tuesday, March 15, 2016 2:33 PM
  • Hi Mike, I had seen this, however, in practice it seems to be too subtle for my eyes... :(

    Maybe when I'm used to it (practice practice practice) I would notice this "absence" of differentiation between the standard text and the .variable alerting me to my error... but so far I've been too focused on the script to notice the error until its too late - but thanks for the suggestion, and like I said perhaps with experience this becomes more obvious...?


    - sure I'm noJedi but that's no reason to stop trying to make stuff levitate! -

    You can always adjust the colors that are used in the script pane if you'd like to. Hit Options from the Tools dropdown and play around until you find something that works for your personal preference.


    Tuesday, March 15, 2016 2:38 PM
  • Hmm... yeah possibly, didn't think of customising the ISE windows - I might need to try "something dark" - I do notice that I do find it easier to see the "quoted" text "not working" in the default blue PS console (but everything else is harder... DOH!) because "text" goes a faded green, but variables are "lit up" more...

    Okay time for settings experimentation... thanks, for the idea!


    - sure I'm noJedi but that's no reason to stop trying to make stuff levitate! -

    Tuesday, March 15, 2016 3:01 PM
  • (UPDATE: totally not dissing (sp?) powershell - finding it V useful! - just trying to understand the subtlties of it - I have read a LOT about the language, but have not found anything that explains the logic/thinking behind is structure - so trying to grok (understand) that I thought, might help me mentally hurdle the last of "getting comfortable" with it, rather than all the gotchas, I keep hitting. perhaps I'm laboring the point, but I still haven't quite answered/confirmed/denied my understanding of some of the aspects - a lot of the things I read say "today there is no difference between scripting and formal languages" - but perhaps I'm reading the wrong things...!?

    I can't seem to mark any of these as answers, so I've just "up voted the ones that have helped my understanding, which is what I was after... thanks again to all who posted useful info! It really has helped me grok stuff... =) )

    Hmm... yeah, I see your point, however (and perhaps this is just my background/frameworks/experience tinting my bias), but in my experience I've been used to (almost?) opposite behaviour in languages... caught me out a twice already!

    I agree with you that -whatif is excellent... and I probably just need to get used to writing all scripts with this in anywhere I'm doing something that could be destructive... practice and experience I expect will be all that can help this...

    I had just not seen the -confirm option and it seems (again IMO) counter-intuitive when you side by side it with the -force option... even though force is more powerful than just replace existing files - it seems from my experience that -force is only needed if (for example - the target is READONLY) "tougher" limitations need to be overwritten - if its my file and its "normal" and in the way it will get creamed unless I explicitly figure out a way to say (either) -confirm or provide (again for example) an exclusion list... (ie: prior code checks for the existing file with Test-path perhaps and builds an array of paths? there's probably a super easy way to get around this...)

    I know your answer is going to be "this is scripting languages" (and your probably right, but for reasons that elude me probably, which is what I was trying to learn).

    ie: most shells and programming languages in my experience work like this:

    copy d:\stupidfile.exe c:\sytemfile.exe
    "file already exists are you sure you want to replace existing file"? Y/N/a

    UNLESS you say "/overwrite" or "/Y"or something like this as a command line parameter, powershell (and possibly all shells?) are the opposite... thus my "unintuitive" comment - unless there is a -noreplace value that I've missed somewhere...?!

     

    - sure I'm noJedi but that's no reason to stop trying to make stuff levitate! -




    • Edited by noJedi Tuesday, March 15, 2016 10:17 PM
    Tuesday, March 15, 2016 3:42 PM
  • Why would you want to continue to g around in circles trying to prove that somehow PowerShell is wrong and you know mode.  You are mostly wrong in all statements made about language design.  This is usually due t a lack of any complete technical discipline.  Your extended and complex but wrong discussions serve only to do disservice to others who may be trying to learn.

    I recommend that you spend the time necessary to gain a complete understanding of the fundamentals.  In  the first few chapters of most books on PowerShell you will see why most of your statements are flawed and naïve.

    There is no substitute for learning.  Attempting to levitate shows an unwillingness to accept science.  You can say those fancy things but levitation is still impossible without a rocket, a jet or a helicopter.  You are trying to do the impossible with words.


    \_(ツ)_/

    Tuesday, March 15, 2016 4:09 PM
  • copy d:\stupidfile.exe c:\sytemfile.exe
    "file already exists are you sure you want to replace existing file"? Y/N/a

    The help for the cmd.exe copy command explicitly says the following:

    The switch /Y may be preset in the COPYCMD environment variable. This may be overridden with /-Y on the command line. Default is to prompt on overwrites unless COPY command is being executed from within a batch script.

    (relevant portion bolded)

    So you can see cmd.exe will not prompt for overwrite if you run the copy command in a script (batch file), but it will prompt if you type the command at the command line. This is a peculiarity of cmd.exe that's not present in other shells or languages.

    PowerShell makes no distinction between commands run at its command line vs. commands run in a script, and in my opinion this consistency is a good thing. If you want prompting, use -Confirm. If you want to test, use -WhatIf. The rules are simple and straightforward.


    -- Bill Stewart [Bill_Stewart]

    Wednesday, March 16, 2016 2:47 PM
  • !!!! Whoa... okay then ... (better go check some of my old batch scripts   o_0   you are right, that inconsistency does suck!)

    Okay so now we're getting into it but from a more technical level - was hoping there might be some kind of philosophy or "method to the madness" but it seems its more of a "practicalities thing"! Probably makes sense from an operations point of view if I think about it now.

    This is obviously why -confirm and -whatif exist, to allow for this "way" of development of scripts... I think that makes it much clearer for me, thanks for the heads up - obviuosly I'm too much relying on "programming thinking" and not "scripting thinking".

    Thanks, interesting and V. helpful info!

    UPDATE: just found this - for anyone else wanting to grok it - this really helped me "think like powershell" (there should be a t-shirt...) https://channel9.msdn.com/shows/Going+Deep/Expert-to-Expert-Erik-Meijer-and-Jeffrey-Snover-Inside-PowerShell/


    - sure I'm noJedi but that's no reason to stop trying to make stuff levitate! -


    • Edited by noJedi Thursday, March 17, 2016 12:40 AM awesome reference
    Wednesday, March 16, 2016 10:36 PM
  • Okay and two more (gotchas?) for those learning:

    Powershell <=2.0 - (are we NEVER supposed to use this now? what if you are  restricted in what you are allowed to install on Win7 like me, because you seem to be stuck with it and it makes learning soooo much harder... IMO... fortunately I can remote into a more modern OS which has a higher version! phew...) it seems to lack a LOT of niceties (particularly for those struggling with bugs and learning?) and doesn't seem to have a lot of the formatting things that were suggested (particularly in strings, which probably explains why I was having sooo much problems with that...

    ISE - not sure if its improved post 2.0, but, in that version a good tip is when you are developing is that there is no way to "clear the session" - so you might get odd behaviour when you create a variable called $x which is a string and then reuse it in an "inner scope"   but then use F8 to run highlighted bits but in teh diferent scope its an int or other type of object...

    Both these things assisted in my confusion on a lot of matters - particularly the formatting, so maybe this will help anyone else just "using the default PS install" - find a NEWER one! :)


    - sure I'm noJedi but that's no reason to stop trying to make stuff levitate! -


    • Edited by noJedi Thursday, March 17, 2016 1:25 AM
    Thursday, March 17, 2016 1:20 AM
  • ISE - not sure if its improved post 2.0, but, in that version a good tip is when you are developing is that there is no way to "clear the session" - so you might get odd behaviour when you create a variable called $x which is a string and then reuse it in an "inner scope" but then use F8 to run highlighted bits but in teh diferent scope its an int or other type of object...

    This is a good observation. This is exactly why, when I test using the ISE, I always develop and debug using a script file.


    -- Bill Stewart [Bill_Stewart]

    Thursday, March 17, 2016 2:07 PM