Why the HECK Do You Want to be Taught .NET in a PowerShell Class?!?!?!

Ok, that post title is deliberately provocative. Twitter and all that.

So look, we're designed this advanced PowerShell class. One of the top five constant suggestions I get whenever I say "advanced" and "PowerShell" is ".NET Framework."

And I get it. When there's no cmdlet, .NET has a ton of goodies that can solve a lot of problems. Maybe you don't like turning to it, but you'll do it if you have to.

My problem is, what's that look like in a class?

I mean, for me, using .NET basically works like this:

  1. Spend hours on Google finding the .NET class that will do whatever I need done.
  2. Look up class documentation on MSDN.
  3. Fiddle around in PowerShell with properties and methods until I get what I want.

I can totally see a class making #2 and #3 a little easier. That's just some basic experience, which is what a class helps build. The problem is, I can teach someone those steps in 30 minutes or less. The hard part is #1, and I truly don't know any way to "teach" that. You're either good at Google, or you aren't. I certainly can't provide some kind of mega-directory to the whole Framework - that's what bloody Google or MSDN Search is for.

#3 can also be a hard part, because it requires you to know a bit about the underlying technology. It's easy to use .NET to resolve DNS names to IP addresses - IF you know how DNS works. If you don't, .NET is hard to use for that task. I can't turn a PowerShell class into a "here's how ____ works, so that I can show you how to do it in .NET."

So everytime I try to teach .NET in a PowerShell class, I end up showing people how to read the MSDN documentation, execute methods in PowerShell, and look at properties in PowerShell. Kinda boring. I mean, they're just freakin' objects, right? Once you've grasped "objects," isn't .NET easy, assuming you've done #1 and found the class you need?

So if you were taking your dream class in "advanced PowerShell," and you were all excited that it had a module on "Using .NET Framework," exactly what would that module look like? What would you want to be TAUGHT?

Leave a comment. Tell me.

(By the way, if your answer to the question is, "I want to learn how to find what's in the .NET Framework," there's no need to leave a comment - we all want that, I've just no clue how to teach it other than teaching you to be better at Google!)

Posted in:
About the Author

Don Jones

Don Jones is a Windows PowerShell MVP, author of several Windows PowerShell books (and other IT books), Co-founder and President/CEO of PowerShell.org, PowerShell columnist for Microsoft TechNet Magazine, PowerShell educator, and designer/author of several Windows PowerShell courses (including Microsoft's). Power to the shell!

17 Comments

  1. I'm one of the people that left the comment. Maybe you could provide some guidance on when using .net is appropriate and provide some references to resources to get people started. I just missed it, it doesn't mean that it has to be given a lot of attention.

    • Yeah. That's tough to do in a lab-based class, especially since I have a responsibility to make it "teachable" by the average MCT. Maybe this is something that could be done as an appendix. I dunno... I half think there's a standalone, short course here, but I'm not sure there'd be any demand for it, and they're expensive to create.

  2. So, I was totally one of the people that suggested teaching .Net usage. My intention was exactly to teach #2 and #3. If you don't know how to read MSDN help and translate that to Powershell syntax, Google isn't going to help you much anyway.

    Static Methods; Generic Classes; stuff like that. These are the things I get ask about when someone I know tries to break into leveraging .Net with PowerShell.

    I don't think it needs to be a very large portion of the course, but understanding the basics of how to access that .Net functionality from PowerShell can open a lot of additional functionality including the multitude of 3rd party .Net libraries.

    • I don't mind covering the #2 and #3 bits. I worry because students always get stuck on #1 and get ticked off when the course doesn't (because it can't) help make that better. They wind up down-rating the course, which affects it's success numbers, which affects whether I get paid for it or not. I'll keep thinking about this one - it's something that's been a "thing" forever, that's for sure.

  3. Don,

    Some of the common things I see most people struggle with regarding PowerShell and .NET are:

    1) converting sample MSDN code from C# or VB to PowerShell. This is not very straightforward unless you already know how those languages are constructed. Maybe some example scenarios would be good.

    2) instantiating objects directly from .NET classes. Maybe explaining some of the base concepts of what a class is, what makes up a class such as public/private properties/methods, constructors/destructors, etc. CMDlets do their best to hide the ugly side of .NET development, but that doesn't do ITPros any favors when they need to dig deeper than CMDlets allow.

    3) maybe a deeper investigation into the differences between what a CDMlet is doing behind the scenes to instantiating an object versus an example of how you could do the same thing with native PowerShell .NET code.

    I think when people are requesting .NET content from an advanced PowerShell class, it is probably coming from a "they don't know what they don't know" standpoint. I imagine providing some of the basics, and assuming that PowerShell coders are not also professional devs, will go a long way toward bridging that gap. That might be enough to empower people to know what to Google for next time the need arises and what to do with the information once they find it, which I think are the things lacking the most.

    Sounds great. Good luck!

    -Corey

    • “They don’t know what they don’t know”, Is exactly the problem I was thinking about.

      For example, System.Net.IPAddress. Pretty much everyone will understand what that class represents, but looking at the MSDN documentation there are things that someone only familiar with PowerShell cmdlets might not be familiar with. Constructors, Static Methods, Fields. If you knew the PowerShell syntax for working with those member types, you could work with a large portion of the raw Framework.

      Maybe that's not the most functional example, but my point being if you can't work with that, then there's no point even trying to Google for a .Net class that might meet your need.

      • That's really useful. Combined with a quickie on how to translate the MSDN C# examples into PowerShell... I think that's useful, actionable, well-scoped, and do-able.

        • I aggree with Corey and Chris.
          in addition to my other comment show how the .NET building parts work: Constructors (instantiating objects), Static Methods, Fields, overloads of functions and constructors

  4. I have two suggestions.

    1) Maybe you can come up with some heuristics for them to use to determine if some functionality that they would want or need is available in .NET.

    The biggest hurdle for me when I first started looking at .NET was that I didn't have any idea of what type of functionality I could expect to find. For example, I wanted to find how to make x-y scatter plots like in Excel. I looked and looked, but I couldn't find it. The way I finally made sense of this was that the charting tools in .NET are probably geared towards business types, and x-y scatter plots are more scientific/math/student type of a chart, so it makes some sense that I couldn't find it in .NET. So now, one heuristic I use when I want to find a specific functionality in .NET is whether a person in a business setting will want that functionality and I use that to determine how long to keep searching.

    Of course, different parts of .NET will have different goals, so the heuristics will most likely be specific to the kind of functionality they're searching for.

    2) The other thing is that, since you know what kinds of functionality they need, maybe you can tell them the things to look for that will make it hard or impossible to use that functionality in native PowerShell.

    For example, the first thing I wanted to do in .NET using PowerShell was use [array]::BinarySearch on an array of PSCustomObjects. Well, in order to use binary search, I needed to create an object that implements IComparer and I kept trying to find and figure out how to do that natively in PowerShell. It wasn't until I found Jaykul's post about binary search that I finally realized that it just wasn't possible to do that natively in PowerShell. Yet. Hopefully.

    Anyway, those are a couple of things that I think would be good to know for someone wanting to learn about .NET using PowerShell.

  5. My take is that you could focus on the discoverability. PowerShell has great discoverability, for PowerShell. Teach people how to go beyond that with ILSpy, .NET Reflector, etc, to give them deeper visibility into the .NET Framework.
    Some of my favourite PowerShell functions are the ones that do magic by bringing cool things from .NET into a simple PowerShell function, such as:
    http://gallery.technet.microsoft.com/scriptcenter/New-ISOFile-function-a8deeffd
    or
    http://convertwindowsimage.codeplex.com/

    • Yeah, I hear ya... but I'm not sure I'm convinced. It sounds an awful lot like just teaching a .NET course in the guise of PowerShell. "Deeper visibility" isn't the same as "discoverability." Not that a .NET course wouldn't be useful, but I'm not sure it's honest to call it a PowerShell course. Maybe what's needed is a short .NET course for admins - bit more forthright.

      • Make it a series, call it the PowerShell DevOps series and make the outline match the Continuous Integration / DevOps principles with the idea of turning an IT Pro into a DevOps ninja. Course pre-req: you push buttons. Course outcome: you make buttons for other people to push.

        • Great concept, but I'm not sure it's something Microsoft Learning is ready to buy into in terms of course development. They'd probably justifiably worry about their training channel knowing how to market or sell the course. DevOps is still a pretty squishy term, and you still get WAY more of the audience fighting against it than embracing it. Which will hurt them in the long term, sure, but in the short term it makes it hard to financially justify spending the money to build a course nobody might buy...

          • I personally like the DevOps idea. Although it is manly directed to the relationship between Developers and IT-Pros (hate that term,I prefer SysAdmin).
            I am doing Programming since 1990 and because I am a SysAdmin I develop mainly my own Command line stuff. In 2005 I began to develop with .NET.
            So am I was every Time a DevOp, even when there was no word for that.
            I see a DevOp as a Person who is in both roles. And PowerShell is definitely even in both roles!
            You cannot archive everything in Windows and PowerShell with Cmdlets but you can with the Help of .NET and .NET can use the Windows API.
            Only with these techniques you have the deepest impact possible.
            In the Moment you begin to use .NET directly with PowerShell you are a DevOp if you will or not.
            You try to sell PowerShell scripting not as development to not intimidate SysAdmins from that. (That is in most cases the right way)
            I Think, even a PowerShell scripter is a developer, because even scripts needs a well design and get developed.
            The only difference I see in real world, scripters start often with very dirty code used in production and going professional more and more ...... real developers should learned their trade before produce.

            1) you can teach search strategies to lower the search time.
            I use every time the only the keywords no sentences. If I search PowerShell stuff the I use the Keyword "PowerShell" within the search. If I search .NET Functionality I use the Keyword "C#". And that is the trick do not search classes, search functionality and you stumble over a C# code which does the function. In that code you see the .NET classes or a new developed class. To find a needed functionality .NET name spaces are only helpful some times because Microsoft opens new name spaces with similar functionality.

            2) First in my live I have learned woodworker. There you use many dangerous machines. My master always teched me "if you know how a machine is build up you want get hurt." I think that it is what to teach. How is .NET build up? If you Use PowerShell you can live with the simple Object model. The simple model you can say: Think to an object as an carrying case in the memory with Properties as Name=Value and Methods, the name of the Object is the handle to that case.
            If you want to deal with .NET you have to explain how to use the MSDN documentation AND inheritance, what is an .NET interface and the mechanism behind that and so on. Even you have to explain the foll blown Object paradigm. Without to teach developing!
            I think it is best to do a demo-show of the development of classes (with inheritance). So the audience can look a .NET developer over the shoulder.
            Even here, If you know how a machine is build you can imagine the use cases. One main point about .NET is to know the mechanism of inheritance because there you can get functionality that is hidden in the ancestors. There you have to show how to click trough MSDN to explore the inheritance. Get-Member reports only the direct members!
            3) Don't fiddle! RTFM 😉 Read MSDN Class documentation and use it 😉 Or ask in Forums. If you do not find a ready .NET class in the MS Framework search for 3td party solutions (on http://www.codeproject.com or so).
            At the end tell them that PowerShell himself has limited possibility to develop classes. With New-Object you have only a similar mechanism. You can define Properties and Methods with the Object but there is no inheritance interfaces and other advanced .NET stuff. If you show the Add-Type cmdlet you have the full possibility to develop inside, like a .NET developer. But then tell them, they have to book a .NET developer training.

            Hope my writing and the intension behind is understandable …

  6. I think an advanced .NET module could cover all 3 and I think .NET is an important advanced skill to have. PowerShell is about automation and about stringing commands and objects together within its pipeline. This mostly revolves around the core set of cmdlets or the cmdlets provided by other products or 3rd parties. I think it should be reinforced that PowerShell with .NET isn't scripting with C# but an automation tool that can glue many different and often disparate things together.

    #1 isn't as important as #2 or #3. Understanding the MSDN documentation for the BCL/FCL is important to understand how to solve and answer your .NET/PowerShell questions. Learning MSDN while at the same time reinforcing the use of Get-Member with .NET classes should really help ease that and show the linkages between PowerShell and .NET. MSDN documentation is a fire hose and looking for that one thing to do a thing can be daunting. Understanding namespaces in .NET can help focus what you are looking for. However that dovetails into #3, find some code on Google or MSDN and use New-Object and Get-Member and step through it. I think that is one of the most beneficial aspects of PowerShell and .NET. You don't code, compile, execute, test, debug. You just instantiate and execute methods or get/set properties and repeat. If things get too messy start a new session. Start-Transcript and Get-History are also good PowerShell tools to reinforce .NET testing and learning.

    I don't think .NET can be taught in the same way that for example Remoting can be taught. Remoting is a singular thing with clean and often universal usage scenarios. If you get into .NET with PowerShell its not about knowing ".NET" its about having the tools for operating .NET within PowerShell. You either know what your looking for or you know how to use Google to learn what your looking for. Exploring .NET with PowerShell is what should be "taught".

    I think in addition to Get-Member the class module should cover Add-Type and some of its various usage scenarios. Nothing specific, contrived examples would be fine. With Add-Type show how you can load/write C# code or types turning it into an object that can be used in a standard PowerShell pipeline. For example along with Select-Object, Sort-Object, ConvertTo-Html, etc. Additionally using Add-Type to load DLLs that aren't necessarily part of the .NET BCL or FCL. Typically what you would be faced with if you were using a 3rd party .NET dll. Not sure how you could pull that off in an MS course. There must be some MS product .NET SDK out there that you could install and use Add-Type with to demonstrate. Importing DLLs are fairly common usage scenarios of mine. I still see a lot of people who have stumbled upon old v1/v2 examples that use the old reflection method. Add-Type is so much cleaner, friendlier, and much more useful.

    More then a couple times I've instantiated a .NET object from a 3rd party vendor or in house development that otherwise didn't have a PowerShell cmdlet or useful equivalent as part of some larger solution. PowerShell can really facilitate tying all of these things together. Advanced PowerShell users should know what options, and tools are available to them. With .NET its never going to be clear cut, but a little knowledge can go a long way to producing a better PowerShell solution.