PBS_2025_01_02

An audio podcast where Bart Busschots is teaching the audience to program. Associated tutorial shownotes are available at https://pbs.bartificer.net.

2024, Allison Sheridan
Chit Chat Across the Pond

Automatic Shownotes

Chapters

0:16 
Introduction to PowerShell
1:24 
The Decision to Dive Deeper
3:10 
Engaging with the Community
3:38 
Transitioning from Bash to PowerShell
5:32 
The Power of PowerShell
6:37 
Opinionated Design Principles
8:09 
The Language of Commands
9:48 
Installing PowerShell
10:27 
Cross-Platform PowerShell
14:59 
Setting Up Your Environment
16:34 
Writing Your First Command
17:36 
Understanding Command Syntax
19:52 
Functions and Scripts Defined
24:09 
Creating Your First Script
26:51 
Running PowerShell Scripts
27:40 
Exploring PowerShell's Big Ideas
27:58 
The Power of the Pipeline
34:29 
Understanding Data vs. Message Streams
38:42 
Utilizing Begin, Process, and End Blocks
48:56 
Parameter Types and Validation
51:15 
Introducing Message Streams
55:45 
Streamlining Output and Logging
1:00:34 
Conclusion and Next Steps

Long Summary

In this episode, we dive into the intricacies of PowerShell, a command-line tool that has gained significant traction for its robust capabilities. We kick off this deep dive by discussing the rationale behind exploring PowerShell and its innovative design principles. Bart reflects on his initial skepticism, describing how PowerShell managed to impress him by turning what he thought would be a tedious endeavor into an engaging experience. The conversation quickly transitions into the fundamental differences between PowerShell and traditional command-line interfaces like Bash, highlighting its unique verb-noun command structure that enforces clarity and consistency.

As we navigate through the nuances of PowerShell, we clarify how it functions as a modern alternative to older technologies, emphasizing its cross-platform compatibility and open-source nature. I share my own experiences of transitioning from Bash to PowerShell, noting the ease of installation across various operating systems, and the advantages of using package managers like Homebrew for Mac users. We also touch on essential settings for a seamless user experience when launching PowerShell, underlining the importance of creating a tailored environment in your terminal.

We intricately discuss the concept of pipelines in PowerShell, drawing a comparison with Bash. PowerShell distinguishes itself by allowing for a more structured handling of data through separate streams for messages and data. This separation not only enhances clarity but also fosters a more organized processing environment. I elaborate on how data can flow through pipelines without mixing with message streams, creating a cleaner workflow when executing commands, with objects being passed rather than mere strings.

The episode also explores the various message streams—verbose, informational, warnings, and errors—and their specific utility in PowerShell. We delve into writing output and how users can interact with these different message types to debug and analyze scripts more effectively. I relay the significance of using dedicated commands like Write-Host, Write-Verbose, and Write-Error, which serve specific purposes without contaminating the data flows of pipelines.

As we wrap up, I highlight the impressive potential of PowerShell's function-building capabilities and how it approaches parameters with a modern twist. Bart emphasizes the consistency in how functions and scripts are processed, sharing tidbits on best practices for creating effective scripts. Finally, we touch upon the community-driven aspects of PowerShell’s development, inviting audiences to chime in about their interests and feedback on the series. Join us as we begin a transformative journey to master PowerShell, preparing for our next episode where we will delve even deeper into its powerful parameter handling capabilities.

Brief Summary

This episode explores the intricacies of PowerShell, a command-line tool renowned for its robust capabilities. We discuss the reasoning behind our exploration of PowerShell, highlighting its innovative design principles and unique verb-noun command structure that enhances clarity. I share my transition experience from Bash to PowerShell, emphasizing its cross-platform compatibility and the advantages of using package managers for installation. We delve into the concept of pipelines, showcasing how PowerShell's distinct handling of data and message streams fosters organized workflows. The episode also covers the utility of various message streams and best practices for script development. As we conclude, we invite listeners to engage with the community-driven aspects of PowerShell and offer feedback for future episodes.

Tags

PowerShell
command-line tool
robust capabilities
innovative design
verb-noun structure
cross-platform compatibility
package managers
pipelines
data handling
community engagement

Transcript

[0:00]Music
[0:07]Well, it's that time of the week. Again, it's time for Programming by Stealth, and this is installment Tidbit 11a, maybe, recorded January 2nd, 2025.
[0:16]
Introduction to PowerShell
[0:16]I'm your host, Alison Sheridan, and of course, I'm joined by your co-host, Bart Bouchotts. How are you doing today, Bart?
[0:23]I am doing just fine, Alison. Yes, so this is going to stay as one file because it works as one text file, but I don't think it's going to work as one recording. Well, we've decided it isn't. So there will be two podcast episodes at the top of the file, but it will be tidbit 11.
[0:41]That's right. So Bart sent me a note yesterday, I think you said, I've written 125% of the show notes for tomorrow.
[0:50]Yeah, so what I really want to do, what I want people to take away is a flavor of why I think we might be interested in doing a deep dive into PowerShell. And i initially wrote it as a purely airy fairy waffly sort of an episode and that was very unsatisfying so then i wrote lots of detail and my sort of thinking was we cannot talk about the detail and have it in the show notes so there's more show note than there is show and that
[1:24]
The Decision to Dive Deeper
[1:20]doesn't seem to sit well with this audience i think it's probably a bad idea so we're.
[1:24]Going to do the detail bart sent me a note and he said no learning just top level i said i don't know how to do it without learning because he's got all the detail in here and we uh we debated a bit back and forth so i convinced him to cleave it into two episodes so we're not rushed and we're not getting excessively hand wavy i think
[1:42]I hope so so let's back up a little bit here and say that i think there's a chance this is going to blow people's proverbial dress up if it does then we can do this like we did bash so we go right back to first principles and we build it up in pieces and then we get to the end where we're bash masters um but i want to kind of give you the movie trailer version so it won't all make sense like a movie trailer doesn't all make sense but hopefully it make you decide whether or not you like this movie and if you do like this movie then please go to the pod feed slack at pod feed.com for slash slack and chime in let us know whether or not this is of interest and i'm kind of equally interested in people saying yeah great bart you love this good for you pass that's kind of also interesting because if you know five percent of the community love it as much as me and 95 percent of the community really don't care then we probably shouldn't dedicate many installments to it.
[2:45]Okay, that sounds like an interesting way to go. We'll see. So if you want your voice heard, again, podfee.com slash Slack. It's really easy to join. You go there and you join. You press a button, you say, I'm in. And then there's a programming by Stealth Channel, abbreviated PBS if you didn't figure it out. And it's also really fun in there. We don't talk about it too much in here, but there's a lot of PBS listeners in there who do have some fun with us. So join.
[3:10]
Engaging with the Community
[3:10]Yes, and it's been kind of interesting because people have been joining in not real time. So they discover they're they're on like episode 12 or something but they're already in the slack which is very interesting yeah anyway so as it always goes with me i think we spent ages learning bash and i was like yay i now have mastered bash this is amazing go
[3:38]
Transitioning from Bash to PowerShell
[3:31]us and i have written a grand total of no bash scripts since finishing that series really.
[3:39]Now weren't we going to move on to zsh at one point i guess we skipped over zsh because you have a new love
[3:44]Yeah well there's not that much meat there we should probably do a taming the terminal to finish that out because i think one episode is enough to say it's exactly like bash except for bullet bullet bullet and that is all oh okay okay but we should do that you're right that is actually a little loose thread we need to tie up but the reason i haven't been using bash is because in my work life i've ended up in a slightly more modern universe and the tool I need to fix my problems is a different tool it's still open source it's still on the command line I'm still running it on the Mac but much to my surprise it's a Microsoft tool and I'll be honest I didn't start playing with it because I wanted to I started playing with it because I had to it was the only tool for the job and I was grumbling and grumbling, and then I started poking at it. I was like, wait, this isn't a half-baked... Sort of quickly lashed together replacement for the old batch files we all hated. I don't know if you remember those in the old Windows days, but they're not happy memories.
[4:52]I never used Windows, Bart. Well, actually, that's not true. A couple of years on Windows Vista, but not on the command line even.
[5:00]Okay. Well, either way, I'm sure there are lots of listeners, I can think Alistair's probably on the list, who have the opposite of found memories for batch files. They were terrible. There's just no power. I wasn't expecting much, but the more I started using PowerShell, the more I realized that they did something amazing. They started over and they learned all of the lessons that we should have all been learning since the 1970s. So Bash started in the 70s, has lots and lots of technical baggage and has been
[5:32]
The Power of PowerShell
[5:32]evolving and getting better. But there were lots of lessons there. And it's like the Microsoft team went, imagine if the Unix guys knew everything they know now and just started over.
[5:44]And it's a complete rethink. And oh my God, it's so well done. And we're at PowerShell 7. So PowerShell 4 was the first one I used and it was rough. It still had those edges that needed to be cleaned off a bit. It's a little like, ooh, well, that almost works, or that works on Windows, but not on the Mac. But PowerShell 7, I do not run into problems where it doesn't work on the Mac. So yeah, it's cross-platform, Linux, Mac, Windows. It's open source. You can view all the source code on GitHub. It's actually PowerShell4 slash PowerShell on GitHub. Link is in the show notes just because, hey, we like GitHub. And yeah, it just works everywhere. And the more I started looking at its view of the universe, the more it chimed with me, the more I went, this is better, this is sensible, this is wise.
[6:37]
Opinionated Design Principles
[6:37]I'm going to put a pin in something straight away. It is opinionated. It is a language that has strong opinions, which means it's very standardized. You can kind of guess at things because it doesn't have conventions. It has rules. Okay, do you like that better? The name of a command has a rule. You can't just call something whatever you like. It's always verb-noun. So this command is going to do something. that's a verb to something that's the noun and so they're all named like that way.
[7:12]To do it okay i've never seen anything like that before do you like that you like that structured approach better
[7:19]When it comes to reading documentation it's amazing because when you're trying to figure out how to read something you just say you go into the docs and you search get dash and all the get functions show up and you go okay so i can get this i can get this i can get this i can get this. Okay, now I want to change something. Update dash. Ah, I can update this, this, this, and this. That makes more sense. Yeah. And if you search by the noun, so I need to change an AD user account, then search for AD user, and you'll see get, update, delete. And again, the verb and the noun tell you, what am I going to do to what? And they let you guess things. In a way. Yeah. Oh, it is because you find export-csv and you go, I wonder how I write the JSON. Export-JSON.
[8:09]
The Language of Commands
[8:09]And the other thing that has a strong opinion about is capitalization. And it has picked a standard which is not its own invention because it's called Pascal case because the first programming language to use it was Pascal in, 1990-06 or something. I don't know how old Pascal is, but it's been around a while. But for those of us who've grown up in JavaScript where camel case is king, pascal case is almost what we're used to, and then it isn't, because the first letter is capitalized too. So you capitalize the first letter and the first letter of every word.
[8:43]But, you know. 1970. It's 55 years old as of 2025.
[8:48]Yeah, so not quite reinventing the wheel. Okay, anyway, I jumped ahead a bit. So the tooling, okay, so there are lots of ways to install it on every platform, and it's very native on the platforms. But here in the Mac universe, the most native way to get it is our friend Homebrew, which we use for lots of terminally stuff if you listen to the NacillaCast. So if you brew install PowerShell slash tap slash PowerShell, you will get the latest stable release of PowerShell. There's a subtly different command to get the long-term support release, which means you stay at that same major version for years of support, but you're a little further behind. Or there's the opposite one, bleeding edge, where there's bugs and all sorts of fun for you to enjoy.
[9:35]Actually, when I was reading the error messages, actually, because I had some problems with the Xcode command line tools.
[9:48]
Installing PowerShell
[9:44]One of the things said, we really want you to do the... Oh, no, I know what it was. I know it was when I was installing it in VS Code. It said, you should really get the early release one. Get that one. Yeah, yeah, take that one. Oh, the early release one. Yeah, yeah. They want you to do the early release. So they're very enthusiastic.
[9:59]I guess they want beta testers.
[10:01]I guess, I guess. So you've focused there on Mac users. But again, we are talking about everybody. He's got links to all the different ways to install it on all the different platforms.
[10:11]Yes. and there's literally a page per platform so that you can click in and it'll walk you through. And they all work great and they're all very appropriate to their platform.
[10:20]And the abbreviation is PWSH. So like ZSH, Bash, PWSH.
[10:27]
Cross-Platform PowerShell
[10:27]Exactly, it sort of fits in, right? So PWSH PowerShell. So there we are. Like I say, this has been evolving. So if you're Googling around for stuff and you get old code, the old code still works on the new PowerShell, but there may be a nicer way to do things and there is a a feature that the documentation recommend you use to tell your ide what version of powershell you're using so it's basically power or pound sign octos or whatever we're calling it this week requires minus version and then the major version so 7.4 is currently the stable release and what that means is five years from Now, if you try to run that script, the PowerShell command line will know the version of PowerShell you used. And if there's been any breaking changes, it will actually use the old version of PowerShell.
[11:19]That's kind of an interesting way to do it.
[11:22]It is, because I have a lot of PowerShell 5 stuff with my work hat on, which is technically broken, but if you use it requires, it's like, okay, fine, I'll use the old version, no problem, sir. And your code still works, which is nice. And it helps you to figure out, well, when I wrote this, what was I thinking? Oh, look, it says requires minus version 4. Ooh.
[11:43]Well, it still won't take care of what was I thinking, but it'll tell me what version I was running.
[11:48]Why yeah sometimes that's enough to tell me oh that's when i was quite new at this oopsie, okay so the really big thing to focus on is how does power shell think about the world differently, and it's got a little bit of bash and a little bit of javascript in its brain but it's different to both of them and when we were writing javascript i always told you even if you've grown up in other languages where they use underscores don't try to do that in javascript when you're writing javascript do things the javascript way right the documentation writes things a certain way the whole community does the various libraries tend to copy whatever is going on in the community so if you do what everyone else is doing your javascript code will make way more sense to everyone else and when we were in bash i was like oh no use those underscores just like bash does in all of its examples because that community does things that way and so if you're gonna not hate powershell lean into the powershell way of doing things don't try to write PowerShell code that's actually C code. Right. If you're writing PowerShell, write PowerShell. And if you think PowerShell is stupid, don't use PowerShell.
[12:58]Fair enough.
[13:00]Okay. So I could mentally hear you as I was typing the show notes, Alison. I've talked quite a lot and you haven't run any commands yet. So what I figure is... Yeah. Yeah, so you've already mentioned that the executable is PWSH for PowerShell. So you can use the, actually, I'm skipping a slightly ahead of myself. So if you're on the Mac, you're going to need some sort of a terminal, right? You're running a shell, so you need a terminal. So you can use Mac's built-in terminal app. And if you just open a normal terminal, it will be ZSH. And then if you type PWSH, then you have a PowerShell terminal inside the ZSH terminal. But it'll work. But I like to have a different profile where I can just go new terminal and pick the PowerShell profile and when you do that you can tell the terminal never to bother with CSH just give me a PowerShell window and so there's a screenshot in the show notes with the settings to just say give me a PowerShell window and I for various historic reasons PowerShell 4 was always blue background white text so that people would know this is not a DOS window you just look at it and go oh black DOS blue PowerShell and so I'm still in that universe where PowerShell's blue so I made it blue.
[14:19]You know, I followed your lead there. You said to duplicate the ocean profile, I guess it's called. And it's a beautiful light blue and the white text looks great on it. I don't prefer the San Francisco monospace font that Apple likes. I think it's San Francisco. Anyway, I like Courier, but I changed it. But I got to tell you, everything's great until you get an error message. And then it's red on blue and it's impossible to read. It's really, really tough.
[14:50]Maybe my colorblindness helps, because I find that red fine.
[14:54]Really? No, I just look at it going, well, I can tell there's something went wrong because it's red, but that's about it.
[14:59]
Setting Up Your Environment
[14:59]Yeah, okay. Well, maybe you don't want to copy me then, but the important bit is the setting that says use PWSH instead of ZSH or whatever, because then you just have your window ready to go. And when you get a bit deeper, or if you're on Windows, actually, Windows rewrote, they have a terminal app for Windows, which is really, really nice, and it's open source even. So you don't have to use the icky command prompt. You can actually use a nice terminal if you live in Windows land. That link is in the show notes as well. And when you get as far as writing scripts, you should probably have an IDE. And you could use any IDE with PowerShell support, but do you know who does a really good IDE with PowerShell support? Microsoft. VS Code, the open source, a very powerful IDE for Microsoft, is great for running PowerShell. There is a plugin. and when you have the plugin installed and you open a PowerShell file, it will understand that perfectly and give you really good tooltips and stuff, but it will also open a little terminal right there in PowerShell where you can test your script while you're writing your script. It's very useful.
[16:04]I tried to get that to work on my MacBook Air. I may try it again on the MacBook Pro while we're chatting here since it drives you crazy that I can multiplex while we're doing stuff.
[16:12]Not crazy, just amazed. Oh, inspired. I can barely drink coffee and read.
[16:20]I like to do extra things at the same time, so I do most of them poorly.
[16:26]Anyway, so now that you have a place to type PowerShell, Hello World is the
[16:34]
Writing Your First Command
[16:32]traditional first thing one does in any language. So the PowerShell command to print Hello World is write-host and then in single quotes, Hello World. And that will write hello world to your terminal.
[16:48]Fascinating. Is that the verb noun thing you were talking about?
[16:50]That's it, exactly. So write will output something.
[16:54]To me, like it's going to show it to me. I am the host.
[16:59]Your computer is the host. We'll see why it's write host very shortly, because PowerShell's biggest genius move is to make the pipeline smarter. And that's where there's a difference in write host and write output. But we'll come to that.
[17:17]So at its most, most, most fundamental level, it's basically the same as bash or dos or any other command line I've ever used. The first word or the first thing is either a command or an operator. And then all of the various arguments are space delimited after that.
[17:36]
Understanding Command Syntax
[17:37]So cd space is the bash, you know, command cd, the first argument, whatever you go after the space. PowerShell is the same. So write-host is the command, and we're giving it one argument, which is hello world as a string. So, you know, in that way, the structure is the same. But this gives me the perfect opportunity to put a little jargon in your head. So like with everything in computers, in the 70s, when we dreamt all this up, we didn't pick one word because everyone was doing it at the same time in different parts of the world. So there are synonyms for arguments, which we have never used in this series because by pure luck bash uses the word argument and javascript uses the word argument so we've never bothered with the synonym for arguments which is parameters, but powershell maybe because of its love for pascal uses parameter so mentally you can translate it a parameter is an argument the reason i would say that you use the word parameter is because when.
[18:43]Much poorer answers, because they're answers from people who don't know PowerShell. Whereas if you Google with parameter, you get answers from people who know PowerShell.
[18:51]Oh, interesting side effect to that.
[18:54]Yes. Okay, so that synonym is out of the way. Another interesting design choice is that it functions all the way down. This confused me no end because I did my favorite trick. I didn't read any of the introductory part of the documentation. I didn't read any of the philosophy, any of the things I'm spending most of this episode doing, I didn't do. And so I found lots of documentation for writing functions. And I wanted to write a script. and I found no documentation that made any sense for writing a script because a script is just a function in its own file. If you take the content of a function and put it in a .ps1 file, it becomes a script. But in terms of the rules, it's function. The syntax for writing a function is the syntax for writing a script. It's not different syntax.
[19:52]
Functions and Scripts Defined
[19:52]I guess i don't see why that's a revelation
[19:57]Well if you think about java like in node.js or something functions are something that exist within your script maybe if you're trying to write a javascript command line scripts there's going to be a separate page in the documentation for that, but on the power of defining.
[20:13]An array and then the next thing is a function but you're saying the whole thing is a function
[20:18]The whole thing is in effect a function So the question, how do I pass parameters to a script, which is what I was trying to figure out, the answer is as if it's a function, because it is. So the syntax to say what parameters my script takes is the syntax to say what parameters my function takes, because the script is a function. So it behaves the same, which is amazing, right?
[20:47]Yeah.
[20:47]So your script behaves just like all the functions behave. And in fact, a PowerShell command is also the same thing. So PowerShell commands, PowerShell functions, and any scripts you write, they all are in the same syntax. They all behave the same way. They all deal with parameters in the same way. They follow the same rules. So again, it's very consistent. But because I didn't bother reading the bit that told me that it was functions all the way down, i got very frustrated for an afternoon until i finally found a i think it was a stack overflow that said yeah well you're overthinking this scripts are just functions in a file it's like oh and then i was fine right so we can make we can prove this to ourselves by writing a little function and pasting it into our terminal a little note here if you're going to paste something into the terminal from these show notes take it new lines and all just select the whole thing paste it into the power shell terminal and it will not mind in the slightest it will say oh you want to give me one to that input sir yes sir no problem i was so with that yes so we can say function space name of function write dash hello world so our verb is we want to write something to the screen and what we want to write is hello world so that's our noun so for write dash hello world.
[22:07]Space, because PowerShell doesn't believe in cuddling. No cuddling. Microsoft is not a fluffy company. Nothing shall be cuddled. That's my mnemonic, by the way. Microsoft are not cuddly.
[22:19]Space open curly bracket and then a new line with four spaces because the documentation says don't it's not tab it's four spaces it won't break but if you try to submit some code to the power shell gallery and it's got anything but four spaces now if you use vs code that's exactly what it'll do you'll hit the tab key but it's four spaces because if you look at the settings in power or sorry, in VS Code, it will say in the bottom right, tab mode for space.
[22:50]I believe I overrode that and made it two because four is such a waste of space. Yes, minus two. Well, you know, you embed something five levels deep, all of a sudden it's 20 characters. And if you, you know, you're looking at 80, 25% of your screen is blank.
[23:08]The software engineer says to me, that's a bad smell. Maybe some refactoring is needed. Maybe it needs to be broken into a few more functions if you're nesting that deep. Anyway, that's a philosophical conversation. So if you then put inside your little function write-host hello world then you can run that as if it was a command because a command is just a function in disguise, right? So you just say write-hello world to call the function as if it was any other command that existed in PowerShell because they're all just functions. And it will do what we told it. It'll print hello world.
[23:46]So that's just a function that isn't a script. If it was a script, we wouldn't write write-hello world.
[23:55]Okay, so the body of that function is the write-host hello world. So that's the actual, imagine that was like 20 lines of code doing something actually useful.
[24:09]
Creating Your First Script
[24:05]But it's one line of code doing something boring. So that's the body of the function. That's the bit that goes in the file. the body of the function so to make this a file so if we want to make this function, to be a script if we wanted to write this functionality again imagine it did something of interest right imagine it was 20 lines of useful code that you wanted to use again next week next month next year then you don't want to be copying and pasting it into the terminal every time you just want to be able to have it as a file and run it all right so you want a script So you take the body of the function, the actual content, and you put that content into a text file with the file extension .ps1 for PowerShell version 1. Their logic, by the way, is if they do the thing that Python did and have a version that changes the whole universe life and everything, they're going to call it PS2. And then all of your old code with the PS1 extension will know to use old PowerShell. And everything with a new file extension will know to use a new PowerShell. They have never done a big change like that, but they're ready. Which again, I'm thinking. I like this thinking.
[25:15]So we're on version 7.4 and we're calling PowerShell 1.
[25:20]Because it hasn't had a complete rethink, right? It hasn't had a start from scratch like Python has now done twice. Okay.
[25:29]Well, I was giving Bart a hard time this morning because I couldn't get anything to run in his examples because the font that Typora, our text editor of choice, uses shows that one and an L look exactly the same. And it never occurred to me that you'd have the number one in a file extension. You don't see numbers in file extensions. Not often. MP3? I will remember it now.
[25:53]Now that it makes sense because it's forward-thinking and clever. Now, I said a few moments ago that you should use require statements. So I would suggest when you're making write-helloworld.ps1, you remember to stick the octosorp requires minus version 7.4, then the body of our super exciting function. And then if you save that into the same folder where your bash shell script is, or your bash terminal is, then you can run it. And the way you run it is with the ampersand command, which is PowerShell's equivalent of bash's dot command. And you say ampersand and then the path to the script. Dot slash write dash low world at ps1 and it does exactly what your function did because your the script is just a function in disguise it's just a function in a file that you didn't have to copy and paste in again so it's basically a saved function think of it as a saved function,
[26:51]
Running PowerShell Scripts
[26:47]guys yeah right so now the bit i really i'm okay sorry how.
[26:51]Do we actually run that script because it's different
[26:54]Did you just so to run the script it's ampersand space and then the path to the ps1 file so if you're in the same folder it's dot slash if you're in a different folder you'd have to put that ampersand is new we haven't seen the ampersand is the run this so ampersand says whatever comes after me is not a it's not a command it's a path which you should use as if it's a function so basically the ampersand says run this file gotcha okay.
[27:25]Right, so the bit I really want to focus on today is the first of PowerShell's two really big ideas. So we've decided to make the split between part one and part two, right between PowerShell's two biggest brainwaves.
[27:40]
Exploring PowerShell's Big Ideas
[27:38]So we have one brainwave in each session. So the brainwave for part two is the amazing way PowerShell handles parameters. So that's to come. That's a teaser to your teaser. But what I really want to focus on today is how PowerShell expands on Bash's coolest feature, which is the pipe, right?
[27:58]
The Power of the Pipeline
[27:58]You and I, I think, were always going to like Bash because we were completely in line with Tim Verporten's thing of an app that does one thing and does it well. Well bash is built around this model of you have a massive set of small simple commands that do one thing and do it well and you assemble them into something useful using terminal plumbing as i jokingly call it in tipping the terminal the pipe symbol to take the output of one command uses the input of the next command and you build up this sequence of pieces to make a flow that in the end does what you want and it can be spectacularly powerful because you're taking all these cool pieces and connecting them together and that is completely the power shell mindset it is absolutely about connecting together small you know defined pieces to do powerful things and again with the verb noun right do this to this then do that to that then do that to that right so that they are clearly small pieces because you're only allowed one verb and one noun so if you're trying to do two things at once well hang on a sec the naming convention tells you you're doing it wrong.
[29:07]Right what are you doing are you getting something are you deleting something are you updating something you're doing a thing do a thing that means we need plumbing but in the bash universe that plumbing is kind of double jobbing because if there only is standard out right that's all that goes into the pipe when you pipe one command into another standard out becomes standard in standard error will still go to your terminal but it's not part of the pipe right it's sort of leaking it's leaking out of the pipe so if a command yeah but if a command outputs some information rather than some data they're all mixed together so the end result is that bash commands tend to be very very untalkative they don't give you information they just give you data, because otherwise you're polluting the pipe, unless you type minus V for verbose, and then they'll give you all that glop on the assumption you're not going to just pipe it into another command because you're trying to debug something, because now we have mixed our messages with our data. So the next step in the pipeline is completely confused.
[30:16]But they're two jobs. Why don't we give two tools? And so in PowerShell, there is a dedicated pipe for data and only data. And different mechanisms for dealing with talking to the human. So messaging and data go in different pipes. So instead of having a pipe, I'm going to keep calling them pipes because you shove information in one end. And by default, the data pipe goes to the next command in the pipeline. Or if there is no next command, it'll actually appear on your screen because, well, where else is it going to go? Right? Which is just like it doesn't bash.
[30:56]Consider little branches of pipes coming out. Like right along here, oh, let me squirt out a message to the terminal so they can see what I'm doing at this point.
[31:05]Exactly. So there is a data pipe, and that data pipe only contains data. And there are entirely separate pipes actually four of them but we'll talk about why there's four in a moment for descending different types of messages so you can send informational messages to say hey by the way i've just renamed this and it's now here i've just done x y or z, and that will not in any way muck up the data so you could be very informative to the user and the user can say oh i see that's doing exactly what i wanted and then the pipe sends only the data to the next command so you the human see what's going on and the next command gets only the data and then it does its thing and it can be quite informative and tell you what it's doing, and then the next one goes and it goes on and on like that so the data doesn't have to share a channel the data is all by itself which means it doesn't have to be strings.
[32:00]It can be objects, which means the data can be anything. If you have an array that you'd like to send somewhere else, fine. Shove the array into the data pipe and an array will arrive in the next point in the pipe. If you have a dictionary with 5 million entries, it's a piece of data. It's a big piece, but just shove it on the pipe. The next command will get this giant big dictionary and work with that giant big dictionary. No problem. So you can you know so you you have an excel sheet you can just load that entire excel sheet into a dictionary and then just pass that around or a csv file or a json file and just pass that whole thing from command to command it's very useful to be able to do that like.
[32:47]You said structured of that's just the rules
[32:49]Yeah you can do that okay the other thing is because these are now objects, they can actually, there's a way for PowerShell to know where one thing begins and something else, sorry, one thing ends and something else begins. So if you put two things into the pipe, the next thing in the chain behaves like a loop and it will do whatever it's supposed to do twice. So if I have a command, say, get dash random numbers, and I tell it to give me five random numbers, and then I say pipe that to write host, write host will execute five times. Because you sent it five things in the pipeline.
[33:33]Wait, I think you'll, because you asked it for five random numbers?
[33:37]Yes. So if the first thing in the pipe makes five things, the second thing in the pipe will happen five times. If the next thing in the pipe averages five things, it can put one thing on the pipe. So you can have it go out and in and out and in and out and in. Hmm. But each command in the pipe knows how many things have I been given. And then depending on the verb, it will either give you five updated versions or it will take all five of them and shove them into a file and give you nothing as an output. Perfectly valid thing to do. The out-file command will take whatever you give it and shove it into a file. Now it does produce an output. It's a single string that is the path to the file. so you can send stuff to out file and then the next step in the process you can use the file you just
[34:29]
Understanding Data vs. Message Streams
[34:28]made because what's come to you is a file.
[34:30]Name path right yeah right so you i like what you said in the show notes you said um let me see how exactly how far about to go back but you said while the unix pipeline carries a constant flow of characters making it very river-like the powershell pipeline is much more like a conveyor belt with individual pieces of data yes
[34:51]Took me a long time to come up with that analogy. I'm glad you brought it back. I would have been terrible to have it sitting only in the show notes.
[34:57]Right. Well, it's in bold. How could I miss it?
[35:00]That's why I made it bold. I was pleased with myself. So in the show notes, we actually prove this rethinking of the pipeline. So we start with a really simple function. Our function is called getDoubleValue. It takes a value and doubles it. Our verb is we want to get something. What do we want to get? A doubled value. Could have called it doubled value. Anyway, let's not overthink that. For now, because we're doing that as our cool thing for next time, We are defining the fact that this little function expects one parameter, as we're calling them. The syntax, I'm going to say park that. That's next week's cool thing. It takes a parameter called dollar number. And all we do is we return dollar number multiplied by two. Fascinating function. I can follow that.
[35:56]I can follow that. Before you go further, though, further, you had to name it get-double-value. You could not have named it pancakes. You could have called it get-pancakes.
[36:08]I could have called it get-pancakes. I could have. Okay, so if it's a function I'm never going to use other than for myself in my own terminal, PowerShell will not be cranky about it. It will swallow it up. But if you take that same function and you put it into a module, which is PowerShell's way of organizing code for sharing. So if you have a module, then you can share that with other people. And if PowerShell loads a module and that module does weird things, it will barf the user of your module screen full of warnings. Warning, invalid name. Warning, invalid name. Warning, invalid name. So you're strongly incentivized not to.
[36:50]Okay, I'll obey.
[36:52]Yeah, I would strongly advise it. Also, if you share your code with other people and you don't follow this, they will hate you. They will never use your code again because it won't make sense. Okay, so once we copy and paste those six lines all at once, blop in one paste into our PowerShell, then we can use it by saying get-double-value space minus number space 5. So as you can probably guess, we'll go into detail next time, but when I say minus number 5, that becomes the variable dollar number. And then we say return dollar number star 2. And again, it's in Pascal case, so dollar number has a capital N, which is completely different to what we'd expect from JavaScript.
[37:33]Yeah, so dash number also has to be a leading cap.
[37:37]Yes, it does, because that is in fact the same thing. Yes, yes, it's Pascal everywhere. It's very consistent. It's always Pascal. And then we get the number 10 as our output. Fascinating. Now, if we want to do this in a way that is pipeline aware, that can actually use the pipeline, we do it by adding, basically, the way the pipeline works is when you call a function with pipeline input, It gets to do as many or as few as it likes of a begin block, a process block, and an end block. The begin block happens once before any input is dealt with at all. So I could hand the conveyor belt with five things or with zero things. The begin block will happen once before anything is processed. Right. I'm setting up here. I run my begin block. Right. What have you got for me, conveyor belt? and then for each item on the conveyor belt process gets called so if there's five things in the conveyor belt it's
[38:42]
Utilizing Begin, Process, and End Blocks
[38:36]begin process process process process process and then the end block always happens at the end so.
[38:42]Is the begin block simply figuring out what have i been handed
[38:47]It depends on what you're trying to do so if you have a function whose job it is to make an average of five of whatever amount of things that gets handed you would begin by making some sort of a counter that says, what's the total value of everything I've been handed so far? Call it total zero or whatever, accumulator equals zero. Or maybe you make an array to start collecting the pieces. Whatever you choose to do, right? You do something to collect.
[39:13]So this is something you do, not something that the PowerShell script automatically does. This is something you're going to build.
[39:19]Exactly. So when you're writing a function, you decide what do I want to do once before I get any data? What do I want to do for each piece of data? And is there anything I need to do afterwards? So if you have a function to write to a database, you might open a connection to the database, write five records, close the connections to the database, Begin, set things up, process, do this, do this, do this, finish, end.
[39:43]That makes sense. Got it.
[39:45]So if we just want to double five numbers, then we don't have a begin. We don't have an end. We're just going to be given five numbers. We're going to double five numbers. So we just have a process block. And in that process block, we want to say, send our numbers to the next step in the pipeline. So instead of saying return, because now we're living in a pipeline universe, our function is going to use the pipe. We say write-output. So output is the pipe that goes to the next thing in the pipeline. Write-host goes to the human. Write-output is your data.
[40:23]I lost a little bit, and I know we're trying not to talk about syntax at the same time that we're talking about things that have syntax. So in our previous one we had a parameter and it was double dollar number and then yes you said return dollar number times two great um but now we have two parameters and i don't understand what they
[40:44]Are we have you.
[40:45]Jumped right to the process
[40:46]You're you're correct and i thank you for calling me back because we don't have two parameters we have two lines of code because our parameter dollar number is getting some metadata so we're actually giving extra information to dollar number and we're saying that it will accept value from pipeline so it says the parameter that's coming next will take the value from the pipeline so dollar number is where the pipeline says.
[41:12]Parameter value from pipeline equals dollar true so yes why why didn't we have to say that
[41:19]Before Okay, so the first example, we ignored the pipeline. The pipeline is something you can choose to support or not. So the previous one, we didn't support the pipeline.
[41:30]No idea what you mean.
[41:32]Okay, so our first draft of the function, we had to call by saying, get double value space minus name of parameter space value. There's no pipe there. If we tried to pipe the number five to that function, it wouldn't work because the pipe is not plumbed into anything. We're saying, if this function gets handed something from the pipe, if this function appears after a vertical line, then where does the data on the conveyor belt go? The answer is the variable called $number.
[42:05]I think I follow you. So in order for it to be able to take information from a pipe, it has to have the parameter value from pipeline equals $true?
[42:15]Yes, and that has to precede a name. So in my code, what am I going to call the pipeline? I'm going to call it dollar number. I could call it dollar pancakes in a different function. I could call it dollar something else in another function. I just have to say, because I could have 10 parameters here. I could have dollar number, dollar something else, dollar something else. One of them takes the pipeline.
[42:39]Only one.
[42:41]Right. Yeah, the pipeline is plumped to something. You just got to say, where do I plug this in?
[42:46]When something comes in, it's going to be going into dollar number.
[42:49]Yeah, exactly. Gotcha. Exactly.
[42:51]Okay. So this function is more capable than the previous function, even though it's going to output double whatever number goes into it?
[43:02]Yes, and more capable is the perfect way to put it. So if we treat this function exactly like the previous version, we say get dollar value minus number five, it will work perfectly because five is going to go to the variable dollar number. Dollar number is going to get doubled and then written to the output. And the output isn't being piped anywhere, so it just appears in our terminal.
[43:24]And it doesn't care that there was no pipe.
[43:27]It doesn't care because it's gone, well, I've been given something called number. I have a variable for it. Okay. In it goes, dollar number. What do i do i multiply dollar number by two great thanks done but now because it can accept the pipeline we have a different alternative we can say the number five pipe get double value, so we're now piping the number five into this function and now it goes oh i've been handed something in the pipeline what do i do with things on the pipeline they go into dollar number, and i call the process block once for everything i was handed well i've been handed one thing okay then five double it write the output so it behaves exactly like before now the magic comes.
[44:14]Okay before you get to the magic let me ask one other thing and i know again it's syntax but in order for it to accept things from the pipeline you said parameter value from pipeline equals dollar true is that a sacred phrase right there exactly as right it is capital value capital from capital pipeline equals $true?
[44:33]Yes. Now, there are other possible magic values. So you could have comma, and then there could be other magic words, which we'll talk about in the future.
[44:46]Okay.
[44:46]Because there are other features.
[44:48]What's sacred and what's Bart wrote it out verbosely so that Allison would know what it does? That's a sacred one.
[44:54]That is a sacred one. That is literally signaling the pipeline go here.
[45:01]So now we've piped 5 in to get double value. We probably hopefully got 10 on the command line that came out. But now the magic happens.
[45:09]Yeah. So I told you we can send as many things as we like, and the process function will just happen over and over and over again. So if I send 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, pipe all of that to get double value, we get lots of outputs. We get 2, 4, 6, 8, 10, 12, 14, 16, 18, 20. It just does it over and over and over and over again.
[45:36]So that param double dollar number, that's not the whatever you called it, that starting block.
[45:48]No, there is no begin block, right? There's only a process block.
[45:52]Okay, good. That is the process block. It's confusing because the next thing in the code says process. but you're saying the first part is also process
[45:59]Well okay so the the parameter is true for every possible iteration right number is always good whatever it's got in the pipeline is always going to be called dollar number if i get one thing then it happens once if i get two things and dollar process happens twice the first time the first thing is called dollar number the second time the second thing is called dollar number but they're always called dollar number i.
[46:22]Was looking for that top block to only happen once. That's since it's not inside the word process, but it's not. It is part of the process block.
[46:32]It's a mapping that says that whatever is coming from the pipeline will be called dollar numbers. So does that happen once? Well, they all get called dollar numbers. Oh, that's a deep philosophical question is what that is.
[46:47]All right.
[46:48]So now let's get a little bit clever. Let's start to use these begin and end blocks. So why do we write a function that will accept arbitrarily many numbers and add them together? Get dash sum, right? Verb noun. So again, we're going to have one parameter. It is going to take value from the pipeline. We're going to call it dollar number. Now we have a begin block. It says dollar total equals zero. So before anything on the pipeline is processed, we're setting dollar total to zero.
[47:20]There we go. So that's that begin block.
[47:23]That's the begin block. The process block then says $total plus equals $number. And that will happen once for each thing in the pipeline. And then an end block says write output $total. So we now have an example of a many to one, right? If we send zero things in, one thing will come out. Zero. If we send a thousand things in, one thing will come out, the total of those thousand things. But it's always something becomes one.
[47:57]Right, right. So this all makes sense except for one thing, and I was going to ask about it before, but I thought not going to get into the picky details. The second thing in the parameter statement or param statement, the first one is the parameter value from pipeline equals $true. We've talked about that. The second one says double in square brackets and then $number. And I assume that that double thing had something to do with what we said because we were doubling before. But now here it isn't get some, so it means something else.
[48:26]It means we want a decimal number we're going to talk about the power of this next time but one of the things that in bash all arguments are strings in powershell parameters can be of any type and then you can say to powershell if this isn't a number just tell the user they're wrong don't even bother rutting me i wanted a number if they've said minus number equals pancakes just give them an error message don't have to bother wasting cpu cycles.
[48:56]
Parameter Types and Validation
[48:57]Don't waste those pancakes
[48:58]Don't waste those yeah exactly i like it but.
[49:03]Double is like double precision
[49:05]It's a double precision floating point number yeah okay great int is if you want a whole number by the way much easier string.
[49:15]If you did ask then because i would have assumed that had to do with double all right great so now we can pipe now we can pipe two thing two numbers in and get some
[49:24]Yeah so if we say five comma seven and pipe it to get some we get 12 because it's gone total equals zero zero plus five five plus seven output that which is 12 but we can chain our things together so we can say one, two, three, pipe those to get double value. That will give us four, five, no, two, four, six, which then gets piped to get sum, which gives us 12.
[49:52]So you could just pipe these one after another.
[49:55]One after another, and they will connect as appropriate. So the get double value happens three times. The get sum sort of turns that into a three to one. If we put something after get sum, and it only happened once because get sum is going to make one output. So we have three inputs become three outputs become one output.
[50:13]I understand that.
[50:14]Yeah, it's amazing. So this is data. So we can send any data we like through this pipeline, and each part will happen the appropriate number of times. So you can say, get all users from Active Directory. If anyone's password is older than this, send them into the next step on the pipeline. So you can basically stick a filter as one of your steps in the pipeline. There's a thing called where object that applies logic to a bunch of input and basically throws away everything that doesn't meet the condition. So you basically get all the users, where object, and then put in your condition, pipe that to disable account. Maybe, right? So if your rule is, if you haven't changed your password in the last six months, we think there's something wrong with you. That's a bad example because we don't do that anymore, thanks to NIST. But you get the idea, right? We can apply some sort of a rule that says whatever, you know. But that's the idea of the pipelining. and it allows you to do very powerful things just on the command line.
[51:15]
Introducing Message Streams
[51:15]Now, you said that we had four message streams and I think we're finally going to get, we've gotten to that part where we get to learn what the message streams are.
[51:22]Yeah, exactly. So the data is now very well taken care of, right? Our data stream is robust and sensible and it's very powerful. But we also want to talk to the humans. We want to send messages. What are we doing, right? And so we get four streams in PowerShell. They are verbose, informational, warnings, and errors. So verbose is for, give me all the detail, right? Verbose is for when you're debugging stuff. And so if you use the write-verbose command, the output will only be shown to the user if the PowerShell shell is in debugging mode.
[52:01]We'll talk more about how you do that next time. But if you don't, those commands can be in your code and they won't cause any output. They're just there. But if you say, oh, Jesus, something terrible has happened. Debug my script. Then all of a sudden, all those print statements burst into life and they appear on your terminal. Oh, that's kind of cool. And to make your life a little easier, they automatically come out in yellow, prefixed with open square bracket, verbose, close square bracket. So you can tell whether it's verbose output versus normal output, which is cool. Informational is just another word for normal, run-of-the-mill, plain old output. Right host gives you that output. That's what you've been seeing all along. So anytime we've used right host, it was just informational output. If something goes wrong, but it's not terminal, it hasn't stopped the thing from happening, but we still need to tell you that something's not quite right. Look, I did go ahead and do the thing, but I actually got a bit of a warning back or whatever. Write warning will give a warning message which appears in yellow with a bright warning prefix. And fatal errors are supposed to be errors.
[53:13]So do you write into your code write-warning?
[53:18]Yes. So you might have an if statement.
[53:20]This is something it's automatically doing.
[53:22]Well, the built-in commands will do it automatically, right? So the built-in out-file command, if the file doesn't exist or if the operating system says you don't have permission, that will cause an error to come out. But when you're writing your own code and you want to raise a warning because your code has tried to do something and your code has failed, you can write your own warnings.
[53:48]How do you know? I feel like if I knew to write a warning, I wouldn't write the code through the warning.
[53:55]No, but you would, right? If you have a function which divides two numbers and you suddenly get handed a zero as the divisor, you should write an error actually, because you can't, right? Your code has to... Like, if you think about when you're writing in JavaScript and you say, if something, there's an error, well, what do you do? You can write an error.
[54:16]Okay. So this is Ray-Warni. Got it. Okay. Good.
[54:20]And all the built-in stuff uses these same primitives.
[54:23]Right error is the full failure.
[54:24]Yeah, right error is the full, full failure. Right warning is the, hey, pay attention here, right? And it's in yellow. So when you're running a giant big glop of PowerShell, you're seeing white, white, white, great, great. Oh, sugar, yellow. Scroll up. Well, it went yellow. Yeah, yellow is bad. Red is really bad. I hate seeing red in my PowerShell terminal. I'm saying, oh no, something broke. Yeah, so a fatal error should be a right error. So we could update our double value function yet again. And as well as writing the output to the stream, the data to the stream, we could also just write some messages so that we can tell people what we're doing. So inside our process block, we can say $answer becomes equal to the number I multiply by 2. Write host, $number doubled is $answer. And a little bonus here, double quotes means we interpolate. Single quote means no interpolation, just like in Bash.
[55:26]I always hate the word interpolation in this context because interpolation to me is where you calculate value between two numbers, a percentage along a line. So I don't know what it means.
[55:36]I know, and you had this exact same problem in Bash. Yep. It means that the dollar number becomes whatever its value is.
[55:45]
Streamlining Output and Logging
[55:44]If it's in double quotes.
[55:46]If it's in double quotes. otherwise it would print the character dollar followed by the character n followed by the character u if it was in single quotes I see, so it'll write host four doubled is eight, and it will write output the answer so the pipeline is not going to be polluted here the pipeline is only going to get told whatever the double value is but there's now also output to the human, so if we redo our big long pipeline one, two, three, pipe it to get double value, pipe it to get sum, the get sum is not going to get polluted like it would have in Bash world. We will see the messages saying that one doubled is two, two doubled is four, three doubled is six, and then we'll get the sum at the end, which is still 12. So they're separate streams, which is the cool thing.
[56:39]That makes sense.
[56:39]But of course, redirecting to files is another thing. Because bash mixes all the streams together the same things you use to send things from one command to another command you can send that same stream of of same river of characters to text files but that's also double jobbing so that's how double job begins i double jobbing, because that is used to write data to files and it's used to create a log file, But PowerShell again says, no, no, no, they're two different jobs. I'm going to give you two different tools to do each of those jobs perfectly well, but a different tool so that the streams don't have to get mixed up. So if the problem to be solved is I want to write some data to a file, then you, at the end of your pipe, you send the data to out-file, which will output to a file. So whatever has come to it in the pipeline goes to a file.
[57:38]Will it also write out to the terminal? I mean, can you say write-host and out-file?
[57:46]Okay, so the write-host is not in the data stream. So that's your messages. So that's your, what do I do with a log?
[57:54]Okay.
[57:54]Right? So that's why there's a second feature. If you want a log, it's called a transcript. And you can literally say, start transcript, put it in this file, run all these PowerShell commands in transcript. and then you'll wake up in the morning and find a file sitting there that tells you what did PowerShell do overnight when the Windows task schedule ran it at two in the morning. You just go and open the transcript file and you will see everything that would have gone through the terminal had you been there running it interactively.
[58:22]So the transcripts, that's separate from this out-file?
[58:25]Correct. So like I say, in Bash, there only is one thing. It's the river of text, you can pipe it to a file if you want to log, or you can pipe it somewhere else if it's data. In PowerShell, the question is, what am I trying to do? Am I trying to write data? Okay, out-file. Am I trying to write a log file? Okay, that's a transcript.
[58:48]But the question I asked you was whether you could write-host and out-file. Yes or no?
[58:56]Write-host. Okay, so the stuff you write to write-host is never going to go into the file because it is going to the message stream, not the data stream. Remember, we've separated messages and data.
[59:06]But I can't send the same information to both places?
[59:10]If you do a write output and write host, absolutely, it'll go to both places. You do that explicitly. They're not mixed together. If you want the same thing to two places, you put the same thing in two places.
[59:22]That's what I'm asking. can you do a write-host and an out-file?
[59:26]Absolutely. Yeah, absolutely.
[59:28]Yeah. Got it.
[59:29]Yeah. That's your choice. Absolutely. Whatever you're writing to write-host, write-verbose, write-warning, or write-error, they can be put to the transcript. And when you're setting up a transcript, you tell it, I only want the errors. If you want an error log. Or I want warnings and errors. Or I'm writing a debug log. Send it all. For both, everything, send it all to my transcript. Or you could have two transcripts, one for your errors, one for your normal output, your choice. Because you have the four streams, you choose which of the four goes into which transcript.
[1:00:05]That makes sense.
[1:00:06]It makes sense. So again, every problem has its own solution instead of this double jobbing idea where you have a pipe and whether it's messaging or whether it's data, it's all in the one pipe, your problem. Therefore, we're just going to be not very talkative, right? It's everything has a job for everything or a tool for everything, everything in its place. I've got that all wrong. We know what I mean. So the end result is that you have a lot more control, a lot less confusion.
[1:00:34]
Conclusion and Next Steps
[1:00:34]It does sound like it. It sounds clean. Like you say, like if you had written it before you knew all the pitfalls or after you knew all the pitfalls, the other languages have run into, the other shells have run into.
[1:00:45]Yeah, and what I find, so in the real world, when you're solving real problems that have token made up problems, you get way more robust solutions because at every point in time, the tool you're using is designed to do the job you're trying to do. So you're never trying to use a Swiss army knife. You are trying to use a Phillips screwdriver. You are trying to use an Allen key, right? The tool is always right for the job and you end up with solutions that aren't prone to breaking. And when they break, they break in a really controlled way and they will write their errors in a very sensible way and you can debug and you can fix and you can get it working again. And so I find my sanity is a lot better when I have a folder of PowerShells than when I have a folder of Bash scripts.
[1:01:30]I can see that. It seems to me, I think we've come to the end of the part where I was going to make you stop. Am I right?
[1:01:39]We have indeed, because the second power feature is how amazingly well PowerShell handles parameters. Like, it's brilliant at parameters, because it's learned. It's learned so much. And so that's going to be our starting point next time. It's totally blown my dress up. I was forced to do this against my will, kicking and screaming. I very grumpily started playing with PowerShell. And like I say, it was about three hours later, I was eating all the humble pie.
[1:02:07]Oh, that quickly.
[1:02:09]That quickly. Yeah, I could tell, oh, this isn't half baked. I'm very big on my pie analogies now. I'm getting very hungry, I must be. But it was clear this was powerful.
[1:02:21]All right. Well, I have a feeling I know what my answer is to the question of whether we want to keep going. But maybe this will be enough, these two pieces. But let's see where it goes when we come back in a couple of weeks.
[1:02:33]Excellent. Indeed we shall. And until then, I'm going to say happy computing and great anticipation. Although you can read ahead.
[1:02:41]If you learn as much from Bart each week as I do, I'd like you to go over to lets-talk.ie and press one of the buttons over there to help support him. He does 98% of the work here. I'm just the stooge that listens to him and asks the dumb questions. If you go over to lets-talk.ie, you can support him on Patreon, you can donate via PayPal, or you can use one of his referral links.
[1:03:05]Music

Error: Could not load transcript. Please try again later.

Reload

Loading Transcript...