We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

Writing Award Winning PowerShell

00:00

Formal Metadata

Title
Writing Award Winning PowerShell
Subtitle
Functions and Script Modules
Title of Series
Number of Parts
60
Author
License
CC Attribution - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Identifiers
Publisher
Release Date
Language
Producer
Production Year2018

Content Metadata

Subject Area
Genre
Abstract
Learn to write award winning advanced functions and script modules in PowerShell using the industry’s best practices from a former winner of the advanced category in the scripting games without having to sift through 10 years’ worth of outdated content on the Internet. Transitioning from writing PowerShell one-liners and basic scripts to creating reusable PowerShell tools with advanced functions and script modules can be a daunting task and with all the different ways that you’ll find on the Internet to accomplish the same task, it can definitely seem overwhelming. During this session, we’ll demystify many of the intricacies of toolmaking while demonstrating the best practices for using parameters, parameter validation, cmdlet binding, supports should process, pipeline input, error handling, module manifests, and custom formatting. Who better to learn how to write PowerShell functions and script modules from than a former winner of the advanced category in the scripting games and a multiyear recipient of both Microsoft’s MVP and SAPIEN Technologies MVP award. During this session, I’ll share my secrets for writing PowerShell advanced functions along with the lessons I’ve learned from the hundreds of tips and tricks that I receive via code reviews by the 600,000+ readers of my blog site each year.
Function (mathematics)Scripting languageModul <Datentyp>Online helpElectronic program guideWindows PowerShellAbelian categoryGame theoryWritingSoftware developerExecution unitSoftware testingControl flowSource codeVisual systemIntegrated development environmentCore dumpScripting languageFunctional (mathematics)Module (mathematics)BlogHeegaard splittingBitDigital rights managementGoodness of fitContent (media)Multiplication signCodeSoftware developerVideoconferencingFeedbackYouTubeCategory of beingLink (knot theory)Core dumpGame theoryWindowPeer-to-peerSlide ruleSource codeOnline helpVisualization (computer graphics)Physical systemPoint cloudProcess (computing)QuicksortType theoryComputer clusterUnit testingModule (mathematics)Pointer (computer programming)Expert systemComputer programRevision controlServer (computing)Virtual machineData centerKey (cryptography)NumberDirected graphComputer configurationRegulärer Ausdruck <Textverarbeitung>Graphical user interfaceBasis <Mathematik>Group actionSinc functionDefault (computer science)Point (geometry)Computer animation
InformationContent (media)Covering spaceFunction (mathematics)Modul <Datentyp>Scripting languageParameter (computer programming)outputError messageModule (mathematics)File formatProcess (computing)Demo (music)Coma BerenicesChemical equationPresentation of a groupMessage passingComputer configurationZoom lensFingerprintProgrammable read-only memoryData typeSoftware testingModulo (jargon)Directory serviceSmith chartTouchscreenWorkstation <Musikinstrument>CodeVirtual machineWindowSource codeDisk read-and-write headDemo (music)Right angleMultiplication signCore dumpLoop (music)Control flowCuboidParameter (computer programming)MathematicsDynamical systemScripting languageError messageTwitterModule (mathematics)Power (physics)Real numberPoint (geometry)CASE <Informatik>Hydraulic jumpSlide ruleSoftware testingRepository (publishing)MyspaceRevision controlComputer animation
Demo (music)Process (computing)Scripting languageModul <Datentyp>Function (mathematics)InternetworkingCodeParameter (computer programming)Positional notationSet (mathematics)CodeMultiplication signControl flowComplex (psychology)Presentation of a groupQuicksortInternetworkingAliasingSoftware repositoryFunctional (mathematics)Electronic mailing listVideo gameGoodness of fitRule of inferenceParameter (computer programming)Power (physics)Functional (mathematics)Analytic continuationException handlingRepository (publishing)Demo (music)Euler anglesFile formatSheaf (mathematics)Process (computing)Object (grammar)BitModule (mathematics)Covering spaceCategory of beingOrder (biology)Table (information)Line (geometry)WritingDialectMachine visionBlogSpacetimeScripting languageBlack boxVideo game consoleType theoryComputer animation
Process (computing)Positional notationParameter (computer programming)CodeFunction (mathematics)Scripting languageRepository (publishing)Open sourceElectronic mailing listTask (computing)Execution unitModul <Datentyp>Pascal's triangleCASE <Informatik>Term (mathematics)Mathematical singularityModule (mathematics)CollisionFunctional (mathematics)Functional (mathematics)Task (computing)WritingCASE <Informatik>Scripting languageCodeExecution unitRevision controlServer (computing)Term (mathematics)Electronic mailing listMathematical singularityModule (mathematics)Parameter (computer programming)Function (mathematics)Process (computing)Right angleSequelProper mapModule (mathematics)Repository (publishing)CollisionOpen sourceSlide ruleShared memoryProjective planeInformation retrievalPower (physics)Fitness functionElectronic data processingComputer animation
Function (mathematics)Pascal's triangleCASE <Informatik>Mathematical singularityTerm (mathematics)Module (mathematics)CollisionProcess (computing)Demo (music)Modul <Datentyp>Scripting languageAerodynamicsCategory of being.NET FrameworkObject (grammar)Junction (traffic)Local GroupParameter (computer programming)AdditionPoint (geometry)DialectPower (physics)Hydraulic jumpFlow separationModule (mathematics)Semiconductor memoryRight angleDynamical systemScripting languageLink (knot theory)Electronic mailing listWindowDifferent (Kate Ryan album)CodeType theoryCore dumpGroup actionParameter (computer programming)Object (grammar)Computer animationSource code
Function (mathematics)Revision controlCollisionScripting languageModul <Datentyp>Read-only memoryStandard deviationModulo (jargon)Form (programming)Limit (category theory)InformationModule (mathematics)Electronic mailing listLine (geometry)MIDICodeHost Identity ProtocolContent (media)Source code8 (number)Sinc functionInformationUniform boundedness principleRevision controlContext awarenessFunctional (mathematics)Point (geometry)CollisionVariable (mathematics)QuicksortDemo (music)Source codeMultiplication signCore dumpMereologyModule (mathematics)MiniDiscSpacetimeNeuroinformatikModule (mathematics)Error messageScripting languageCodeComputer fileForestNetwork topologySoftware testingVirtual machineFerry CorstenFunctional (mathematics)Doubling the cubeUser profileComputer configurationThermal expansionStatement (computer science)Type theoryCategory of beingStructural loadProjective planeVideo game consoleDot productSemiconductor memoryCASE <Informatik>Right angleReal numberGoodness of fitProduct (business)Computer animation
Process (computing)Demo (music)Function (mathematics)Scripting languageModul <Datentyp>Variable (mathematics)Positional notationParameter (computer programming)Type theoryCodeProduct (business).NET FrameworkProcess (computing)Object (grammar)Server (computing)Multiplication signSequelSocial classWindowExpert systemDirectory servicePositional notationGraphical user interfaceScripting languageVariable (mathematics)String (computer science)Electronic mailing listOnline helpFluid staticsEmailCausalityQuicksortTranslation (relic)Computer fileInterior (topology)Parameter (computer programming)Programming languageComputer animation
Variable (mathematics)Positional notationSource codeInternet forumObject (grammar)String (computer science)Support vector machineTerm (mathematics)Slide ruleContext awarenessType theoryPerfect groupDifferent (Kate Ryan album)Online helpInternet forumDependent and independent variablesComputer animation
Parameter (computer programming)Element (mathematics)Pascal's triangleCASE <Informatik>MultiplicationCodeWindowOnline helpDatabaseParameter (computer programming)Covering spaceWeb serviceElement (mathematics)Figurate numberMultiplicationNeuroinformatikNormal (geometry)Process (computing)1 (number)Hydraulic jumpDemo (music)CASE <Informatik>BuildingComputer animation
Process (computing)Demo (music)Function (mathematics)Scripting languageModul <Datentyp>Software testingFisher informationParameter (computer programming)ComputerCountingVirtual machineComa BerenicesKey (cryptography)Lie groupThermal expansionVisual systemIRIS-TCompilation albumBlock (periodic table)Computer wormProgrammable read-only memoryoutputMenu (computing)BlogVariable (mathematics)Ring (mathematics)Sheaf (mathematics)Gastropod shellData typeExecution unitString (computer science)Server (computing)1 (number)Functional (mathematics)Parameter (computer programming)MathematicsDemo (music)Server (computing)CodeVirtual machineWindowFree moduleBlogFile archiverLine (geometry)NeuroinformatikData miningCalculusRevision controlOrder (biology)Functional (mathematics)Different (Kate Ryan album)Computer clusterSheaf (mathematics)Process (computing)Constraint (mathematics)Validity (statistics)String (computer science)Degree (graph theory)1 (number)Presentation of a groupCalculusOnline helpError messageQuery languageType theoryEntire functionComputer fileFreezingModule (mathematics)Multiplication signModule (mathematics)Mainframe computerComputer animation
Function (mathematics)Software testingParameter (computer programming)Scripting languageModul <Datentyp>VacuumInformationComputerConvex hullString (computer science)Error messageRegular graphoutput8 (number)ExplosionExecution unitEnumerated typeMotif (narrative)Parameter (computer programming)Computer fileNormal (geometry)outputValidity (statistics)Scripting language1 (number)Pattern languageFunctional (mathematics)Regulärer Ausdruck <Textverarbeitung>Message passingGroup actionCodeError messageNeuroinformatikFitness functionPointer (computer programming)Software testingServer (computing)Online helpDefault (computer science)Equaliser (mathematics)CountingIntegerMultiplicationSign (mathematics)String (computer science)Local ringDifferent (Kate Ryan album)Standard deviationType theoryIntegrated development environmentPoint (geometry)Multiplication signComputer animation
Function (mathematics)Modul <Datentyp>Scripting languageSoftware testingoutputEnumerated typeMaxima and minimaPhysical systemTelephone number mappingUsabilityData typeTorusAddress spaceParameter (computer programming)Digital rights managementCategory of beingMIDIQuicksortSet (mathematics)Module (mathematics)Smith chartString (computer science)Default (computer science)CodeFunctional (mathematics)Enumerated typeSet (mathematics)Function (mathematics)Module (mathematics)Functional (mathematics)MultiplicationType theoryRegulärer Ausdruck <Textverarbeitung>Graph coloringModule (mathematics)Extension (kinesiology)Address spaceParameter (computer programming)Validity (statistics)EmailComputer configurationResultantProduct (business)Electronic mailing list1 (number)Scripting languageRepository (publishing)Constraint (mathematics)Workstation <Musikinstrument>LaptopError messageComputer animation
Software testingFunction (mathematics)Error messageParameter (computer programming)Module (mathematics)Position operatorScripting languageModul <Datentyp>Convex hullString (computer science)outputSimilarity (geometry)MaizeFunction (mathematics)CodeBlogVideoconferencingIntegrated development environmentComputer fontCore dumpWindowConfiguration spaceDefault (computer science)Parameter (computer programming)Poisson-KlammerSquare numberPosition operatorBitComputer animationLecture/Conference
Function (mathematics)Software testingoutputParameter (computer programming)Modul <Datentyp>Scripting languageCore dumpPosition operatorInflection pointParameter (computer programming)Computer configurationPosition operatorOnline helpCategory of beingComputer animation
Modulo (jargon)TorusAttribute grammarParameter (computer programming)Function (mathematics)Scripting languageModul <Datentyp>Digital mediaPosition operatorHill differential equationSoftware testingGamma functionString (computer science)Set (mathematics)outputDemo (music)Computer configurationSet (mathematics)Parameter (computer programming)Category of beingMultiplication signComputer configurationVideo gameBlock (periodic table)Type theoryDifferent (Kate Ryan album)Poisson-KlammerInternetworkingComputer animation
Function (mathematics)Scripting languageModul <Datentyp>Parameter (computer programming)Software testingComputer iconSet (mathematics)Computer configurationoutputCategory of beingInformationWechselseitige InformationHill differential equationAerodynamicsPosition operatorSummierbarkeitModule (mathematics)Attribute grammarConvex hullLie groupVariable (mathematics)Group actionPhysical systemEquals signNumberMaxima and minimaRevision controlDot productMessage passingInequality (mathematics)Total S.A.Menu (computing)Internet forumPhysical lawForm (programming)ComputerServer (computing)Port scannerProcess (computing)String (computer science)Object (grammar)Data typeTask (computing)Block (periodic table)FingerprintNormed vector spaceEvolutionarily stable strategyCategory of beingParameter (computer programming)Type theoryServer (computing)NeuroinformatikLoop (music)Integrated development environmentRange (statistics)QuicksortOffice suiteException handlingHybrid computerNumberAsynchronous Transfer ModeString (computer science)Process (computing)Total S.A.Operator (mathematics)Revision controloutputVariable (mathematics)Software testingFilm editingComputer configurationTouch typingCuboidFunction (mathematics)Ferry CorstenError messageGradientFunctional (mathematics)Object (grammar)PlanningScripting languageCodeBlogOnline helpResultantSubsetElectronic program guideSocial classKeyboard shortcutGreatest elementLink (knot theory)Core dumpComputer animationLecture/Conference
ComputerSoftware testingFunction (mathematics)Scripting languageModul <Datentyp>Visual systemProcess (computing)Message passingHost Identity ProtocolString (computer science)Exception handlingBlock (periodic table)Software testingError messageParameter (computer programming)Variable (mathematics)Group actionDefault (computer science)MathematicsDensity of statesComputer animation
Scripting languageFunction (mathematics)Modul <Datentyp>ComputerSoftware testingMessage passingIRIS-TModulo (jargon)Compilation albumData typeContent (media)Directory serviceComputer fileModule (mathematics)Latent heatWindows ServerCommon Information Model (computing)Demo (music)Maxima and minimaDefault (computer science)Execution unitDrum memory1 (number)Online helpDirectory serviceModule (mathematics)System administratorDomain nameScripting languageDefault (computer science)Translation (relic)CodeNumberExistenceModule (mathematics)Product (business)Semiconductor memoryRevision controlGoogolInstallation artDifferent (Kate Ryan album)OvalComputer fileTouchscreenWindowFunctional (mathematics)Standard deviationCuboidMathematicsComputer animation
1 (number)Default (computer science)Modulo (jargon)Function (mathematics)Scripting languageModul <Datentyp>Wide area networkExecution unitModule (mathematics)Maxima and minimaHost Identity ProtocolType theoryFluxSurjective functionGraphical user interfaceRevision controlInformationForceInheritance (object-oriented programming)Template (C++)Software testingDirectory serviceData typeContent (media)CodeSource codeHash functionModule (mathematics)Parameter (computer programming)Unit testingCodeProduct (business)Module (mathematics)Multiplication signDemo (music)BlogInformationScripting languageMultiplicationCurveLine (geometry)Default (computer science)WindowFunctional (mathematics)Computer fileSlide ruleLink (knot theory)Core dumpMetadataStandard deviationFunctional (mathematics)Revision controlPhysical systemAnalytic continuationTable (information)Template (C++)Order (biology)AliasingQuicksortSource codeComputer animation
Revision controlScripting languageModule (mathematics)Parameter (computer programming)Data structureDefault (computer science)Message passingSource codeFunction (mathematics)Modul <Datentyp>HypertextMaxima and minimaHash functionWindowDynamic random-access memorySoftware testingDirectory serviceModulo (jargon)Port scannerInternetworkingNormed vector spaceMiniDiscDemo (music)Local ringInheritance (object-oriented programming)CodeForceData typeWaveInformationContent (media)Internet forumSpacetimeFree moduleFile formatWireless Markup LanguageType theoryModule (mathematics)Electronic mailing listStandard deviationType theoryCASE <Informatik>Computer fileMereologySoftware testingRootFunctional (mathematics)Functional (mathematics)QuicksortDefault (computer science)InformationFunction (mathematics)NeuroinformatikFile formatDemo (music)Parameter (computer programming)Scripting languagePhysical systemTable (information)Line (geometry)Slide ruleReal numberModule (mathematics)Code1 (number)Descriptive statisticsCategory of beingComputer animation
Demo (music)Process (computing)Function (mathematics)Scripting languageModul <Datentyp>CodeBlogTwitterEmailIdentity managementComa BerenicesEmailSlide ruleComputer animationJSONXML
Transcript: English(auto-generated)
So welcome We're going to be presenting writing award-winning PowerShell functions and script modules in here today, and I was going to present this at a SQL Saturday in Nashville earlier this year, and there was ice
So I didn't make it up there, but I posted it on reddit and you know how you have a lot of people you get a lot of Comments from jerks, so I'll just call them jerks on reddit and one guy said well You didn't say it was a good award. It could be the worst script the worst award so
but you want hopefully this will prevent you from getting the worst award and I'll tell you a little bit about me You're not here to learn about me, but who in the room does not know who I am Okay, good. I think I've done my job of branding them pretty well So I'm Mike up Robbins. I'm a Microsoft MVP. I used to be a PowerShell MVP now
I'm a cloud and data center management MVP. We all got rolled up So like Kirk next door He's a he's a cloud and data center management MVP also as I previously said I run the Mississippi PowerShell user group along With Ron Edwards, and I told you guys already that I won the advanced category in the scripting games in 2013
Well Ron Edwards the co-founder of my user group won the advanced category in 2012 So we're the only user group with back-to-back winners of the scripting games And when Ron won it, Ed Wilson was still running it. I've authored or co-authored a number of books
there's links in the slide deck and all this is on github already and The USB keys that we gave out the windows PowerShell TFM fourth edition is this book here that me and Jason Helmut co-authored It's got the full version on there. I already mentioned about the scripting games
You can learn more about me at Mike F Robbins calm You're not here to learn about me But one thing I will tell you about my blog is I've been blogging about PowerShell since 2009 So I have over 500 blog articles and I put all my code on github now I started doing that and what I do, I won't go back and update the blog articles
but I'll update it on github until you go out there and get the latest version and Just to give you an idea of the type of content I have I get over like 600,000 hits a year and one of the reasons I do that I mean, I'm selfish I do it for myself. I can't remember how I did something later down the road But Then also if you guys would enjoy the content then it's out there
One thing also I get a lot of peer reviews because I will post it on reddit and you get a lot of trolls Out there that but listen to what they have to say because like one of my videos I put on YouTube I got some great feedback and then one guy comes along and says hey It would be great if you would stop bumping the bike and I was like what a jerk, you know
But then I went back and listened to the video when he was right So listen to people if you guys saw Lee Daley He won one of the awards yesterday, and I don't know Lee Daley But he has commented on some of my posts on reddit because a few weeks ago I posted some code where I was splitting a path and I did it with a regular expression
And I just wrote the code. I never even thought about it and Lee said hey Is there any reason you're not using split path and no I just never thought about it So I went and updated the code and gave him credit for it. So that's the sort of things I don't have it. I'm the advanced person at work and
Although I have some other guys that write some PowerShell and I will let them review my code I generally don't they wouldn't catch something like that is what I'm getting at So if you want peer reviews, it's a great way to get it by blogging your code Okay, we're gonna skip through some of this I know all you guys are either an IT pro a developer or somewhere in between
When I tell the IT the IT pros in my shop say you're not an IT pro You're a developer and then I go over to the to the developers and they say oh, you're not a real developer So I'm somewhere in between I'm sure you guys are too So who's using unit testing today like pester, okay good. What about source control?
great, I Unit testing And that gives me an idea how advanced you are because if you're using both those and you're you're more advanced But if you're not then you're less advanced is what I would say
Because if you start writing code that you value you're going to put it in source control The unit testing it helps it can cut down on the time Who's using VS code today? Visual Studio code? Awesome And I'm kind of like the scout front here. I'm like this, you know I use the best tool for the job at the point in time. I won't be using VS code today in this session
I'll show it a little bit. I've I've been using it for about a year now pretty heavily. It's the I generally don't open up the ISC But there's a couple features in the ISC since I've been using it for about the ISC for about eight years I feel a lot more comfortable up here in front of a hundred people
using the ISC And let me just say this so Visual Studio code is nothing like Visual Studio Visual Studio code is free. That's a misconception. I've heard it is very lightweight. It's almost like using notepad It's that light Where if you install Visual Studio on your machine, it's very heavy and bloated
And if you take the defaults it installs SQL Server and everything but the kitchen sink So anytime I install Visual Studio I install it on a VM because I don't want all that garbage on my machine and I use Visual Studio So infrequently, I don't want I don't want the slowdown. So I assume that if you're not using VS code you're using the ISC and
PowerShell studio is another option. I write my GUIs in that but I typically do not use that on a day-to-day basis Who is using PowerShell core? Okay, good and One thing about PowerShell core. There's actually some notes in the slide deck. I don't see the notes
If you want to see the notes just download the PowerPoint I don't think they're in the PDF copy that I uploaded PowerShell core is not a replacement for Windows PowerShell. It installs side-by-side on a Windows system and Everything is totally separate. Even if you update your help in Windows PowerShell
You don't have the updates in PowerShell core. You have to update it there, too. Now. There's a module you can install to to put the C Program Files Windows PowerShell module path in your In your PS module path for PowerShell core and I know that sounds confusing
But what it does it allows you to use your Windows PowerShell modules and PS core It just gives you a pointer and I'll show that here in a minute. How many PowerShell experts do we have in the room? See I'm great We have one So I invited Joel Bennett He's not here to come heckle my session and also Jason Helmick
So I did Windows updates this morning two reasons Don Jones told me not to do them so I did them and They were available. So I said I'll head off the problem and do it, but that's the benefit of source code I told this story a few minutes ago. I'll be brief
So I committed my code to get hub because if I host up my machine I could say hey is somebody in the audience Got a machine I can present on and I could just pull down my code and present so This is what you want to try to avoid. This is the reason you're here in this session You don't want to write code and six months later. You're ready to gouge your eyes out
So the content we're going to cover I'm going to go through this real quick. I had it up earlier It's right off the abstract of the synopsis. I always like to make sure you're in the right session So demo time I will I'll be happy to follow up with you on that
I don't have any test code to test that with and that dynamic parameters I actually rarely use dynamic parameters. Let me ask the how many people in the audience use dynamic parameters Okay, yeah, if uh Mike F Robbins at gmail.com. I mean pretty much find me Mike F Robbins anywhere. I sign up for everything
I've been signed up for like myspace and all this sort of stuff. I'll never use just so I get the brand So anytime you steal code from somebody just like this code I stole here give the person credit for it Thomas Rainer he's uh
He said he stole it for somebody and couldn't remember who he stole it from So what that does I'm just throwing an error in case I run the entire script I used to use break but what I found break doesn't always break breaks designed to break out of a loop So I've had some scenarios where it didn't break and I started using start sleep So I would catch it in time and then I saw him present this and I decided to steal it
So I think I've already zoomed in to 125% I saw a tweet yesterday from Michael Bender about people with that are colorblind set the the errors to To yellow so I'm gonna go ahead and do that I normally set them in the green anyway, because we are gonna have some errors in this session
And this is just prep for the session. I've already imported this module. I have a mr. Toolkit module. That's in my In my github repository also Just want to prove to you I'm not pulling your leg I did Windows updates today
If I say it hey you can bet you it's fact because I can't remember who I tell a story to you So I always tell the same story So I don't have to worry about remembering what I said or it's at least what I believe at that point in time Because what's correct changes just like with your code. And so now we got yellow error messages. We are gonna
Skip a lot of this because I can tell that uh, I'm gonna have a lot less time than I thought I was gonna have We're on Windows 10 1709 with PowerShell 5.1 which ships in box with that version we've got power PowerShell core 6.0 2 also installed
Let's jump back to the PowerPoint slide real quick. I Normally don't jump around but this is something new. So I'll see how it goes So one thing I find people doing is they don't think before they write code They have no idea what they're trying to accomplish and they don't have a plan. So they plan to fail
So and learning is not equal searching the internet So what I would say that I search the internet all the time I download code all the time, but what I do when I download it I want to know how it works. And that's the reason I like script modules so much is yes You can put some DLLs in there But generally the code I download doesn't have DLLs because I don't want to bring black boxes into my corporation
So If you're still in our borrowing code then just give the person credit for it and Think about what problem are you trying to solve? Before you start and Don't reinvent the wheel. So has somebody else already rent the code you could contribute to maybe you could add functionality to
And one thing I'll say with that is uh, so if you go out to github and I'm a big believer I don't use like back ticks for line continuation But some people do they like their parameters lined up and if I'm Contributing to somebody else's repository. I'm going to follow their guidelines, but I'm not going to write my code that way when it's my code
the worst thing you can do is go contribute to somebody's github repo and Reformat all their code and say hey look I did this great thing for you I reformatted your code the way I like it, you know, yeah, that's not going to get accepted
So Don't over complicate things keep it super simple and don't write code. That's unnecessary A lot of people say well, it's not hurting anything. Well, it does add complexity so the thought process Most of you guys in here should know a lot of what I'm going to cover in this talk talk
But for some reason as humans we have a problem doing the things we know we should do And I was talking to Mark Manasi about this last night and he's presenting right now by the way And it's his last presentation before he retires He recommended a book on this and I don't have the book to reference
Anyway, avoid aliases and positional parameters in any code that you share Even if it's a one-liner now typically the rule is to avoid them in functions and and scripts If You open up the console you type out some code and you close it out and it's gone who cares what you typed in there
Now I say it's gone But it's always going to be there because the psread line so you can go find what you typed in but nobody cares about that Readability and I've been there when I was writing my chapter in the PowerShell deep dives book. Jeff Hicks told me I Mean I had great code, but it was all left justified
And he's like go put some spaces in and format your code and make it look better and I'm like it looks fine to me So Jeff is that Jeff Hicks has been a good mentor to me. He's left me some comments on my blog article That's really that's really helped me, you know, so I appreciate that
Don't write and I mentioned this already don't write unnecessary code. I The order you put your commands in didn't matter and that couldn't be further from the truth Because if you select some properties from the pipeline and then you pipe it to where object Those properties may not exist anymore and then just like piping a format table or format list
You you don't want that in the middle of your command. So order does matter One thing I would say with that and it's kind of unrelated to this but related to what I just said is Don't put sort object and format table in your code unless you have to because it does slow your code way down
because And it makes it where it's not reusable and we'll cover that more later so attention to detail goes a long way when writing code and power any kind of Code and PowerShell is no exception One thing I'll say with that I kind of have a problem with this that I write a function and I'll spend to the end of time on that function
Because I can always find something oh I could do this better and that better and something else So one thing I would caution you is don't do that you have to have a little bit of I don't care attitude and Set a date set a time that you're going to be done and Jeffrey Snover He always says to ship is to choose
so have a v1 and if you want to go back and add something then have that would be a v2 feature and Maybe you release it and you put that in a to-do section Hey, I'm gonna do this before somebody comes out and say oh, well, you didn't do this that and the other but set a deadline because You need code that works, but you also want code that you can support later down the road
so clarity and what I mean by that is a is Begin with the end in mind when you write something and know where what you're trying to accomplish and
Once you know what you're trying to accomplish break it down and these are good lessons for life I've found in general and I just apply them to PowerShell break what you're trying to accomplish down into manageable steps and then it seems like it's a lot a Lot less difficult to figure it out and it's no different than this demo
So it's in regions and it was a lot smaller than coming up with an hour and 45 minute session Yes, definitely. I have problem you uh
Because me I know I'll get tunnel vision and I'll be focused on exactly what I'm working on, but I don't see the big picture So one thing with all this ultimately doing this stuff is about bringing value to your business and bringing money in the door And like me I work for health care companies. So I don't work. I'm not selling anything
And we're not a revenue generating department, I'm sure I'm not the only one who's ever heard that so but the good thing is So and I have another slide so I won't go into that yet
Simplicity there's power in simplicity when you go down the road, you know, do you need pipeline support and Do you need these different things? Because what I found is when I write functions and when I had pipeline support It seems to double the amount of code that I'm writing and do I really need that now sure. It's a nice to have
so should you write a script or function I Prefer to write something that's tool oriented and what I consider to be tool oriented as functions and When I write functions, so module auto loading was introduced in PowerShell version 3
So when I write a function I throw it into a module and I put it in the PS module path I don't have to worry about it from now on I just go open up PowerShell and call it and it just works. I don't have to remember Oh, I'll save that script over here over there over somewhere else It's also easier and I know that you can put scripts in the PowerShell gallery, but I don't do that
I ignore that because I disagree with that But you can have an internal nougat repository or the PowerShell gallery and it makes your code a lot easier to share So the other thing is what I don't do in my functions I don't put proprietary data and what I mean by that output credentials output server names. I don't put so on
Because It makes it easier to open source and a lot of people have trouble getting their company to help them open source code But the company is really shooting their self in the foot Because you will write better code if you share it publicly You're not going to write something that's quick and dirty and you'll also get peer reviews. So if it's something generic, that's not
Like me since we're not a revenue generating department. I'm not giving away anything It's going to cost our company any money Now then what I do I write caller scripts and I put the proprietary data in the caller scripts and I don't share those with anybody outside my company
And those are real simple that they're generally real simple They can get more complicated, but I just call the individual pieces the individual functions You also get ideas and suggestions when you share your code and you'll get contributions. Maybe you have a problem
you don't know you have or Maybe there's some functionality that somebody else needs and they may add the functionality that may benefit you And ultimately it's about writing better code. You can get better code by By not doing anything other than sharing your code
Okay, so if you don't know what function is you might be at the wrong conference yeah, so I know that's that may seem a little mean but uh That's why I have a smiley face there that hey if you don't know what a function is then we're you know We welcome you here and we'll teach you what it is
So what's a function? It's a list of commands or instructions that are packaged as one unit. It performs a specific task So a PowerShell function should retrieve data process data or output data should do one of those things and not all those things So if you need it to do all those things you would write a function to do each one of those and then
you would write a script and you would call those three functions and It makes sure just like I was talking about it makes your code more modular It makes it like Lego pieces when I was a kid I loved to play with Lego and that's why PowerShell is a really good fit for me so the naming this should be a
Pretty much a review for everyone here, but just in case I'm not going to make any assumptions Pascal case name, which is like a proper case name capitalize the first letter of the verb all terms in the noun Use an approved verb Otherwise, you're going to get a warning when you import your module. I'm going to show you that here in just a second So use a singular noun and with a singular noun
Well that that's not nouns, okay Prefix the noun so I performed a technical edit on a book on a sequel book for PowerShell And I was brought in late because the previous person that was doing that job quit
It's one of the few technical edits. I've ever got paid for because they wanted it done really quick one day into the project I was like yeah, I'm going to quit because the guy that was writing the book he had written a whole book without using verb-noun and his his deal was that he
There would be collisions with other commands And I was like no, that's not how you do it I'm like you're you're not a PowerShell guy and the community won't hold you accountable But it'll make me look really bad, and I'll be held accountable by the community so I said yeah
I'll just have to quit you can you can reform or I'll quit so I think the previous guy told him that and he actually did quit So he did reform and wrote it properly so sometimes on this stuff you have to stand your ground you know and Don't do it the right way or don't do it at all
So when you prefix your noun so what I do you could write something like get version And if you wrote get version you're going to get a collision somewhere and you could write get PS version for getting the PowerShell version and You're probably going to get a collision there. I would never prefix with PS because the PowerShell team may use that so And I as I was saying earlier my my initials are Mr.. For microibon, so it's mister
So you'll get get mister PS version or get mister version something like that So all my modules all my commands are missed get mister set mister and so on and I know hey, there's other There's other people that I may get collisions But you can import the module with the prefix parameter and you can prefix those commands, so that's pretty easy to avoid
So an example of a preverb prefix singular noun Okay, jump back to the demo and several of these regions were just to remind me to go to the power points
Okay, so how do you think you create a new module? if you search you you would think that uh With PowerShell that would be pretty simplistic, and it would be new module right a new script module. Well you would you would be wrong
Because new module creates a dynamic module in memory And I'm going to use it here simply to show you the warning So that's the warning there that you would see if you used unapproved verbs There's a list of verbs on the web. I've got a link to it here But for the most up-to-date list run get verb from within PowerShell. I'm going to run it now one thing
I will tell you Let's just run get verb so in PowerShell core get verb returns a different type of object And it returns two new columns, and it has a group
Parameter for just filtering filtering by group and on top of that. There's two new verbs build and deploy So the moral of the story here is if you want to make sure your code is compatible with PowerShell core and
Windows PowerShell you have to test in both because there's things that work in PowerShell core that don't work in Windows PowerShell and vice versa I've been running all my code in both just to see what didn't work and I haven't found a lot because I don't use I Generally don't use WMI unless I'm doing like DSC and DSC doesn't work in PowerShell core currently
So I've talked about part of this already. Let me just run these commands real quick. So my demo won't fail so I talked about get getting collisions and get version get PS version and then I would run I would
Create it as get Mr. Version. This is like the simplest function you would ever write I try to keep my code simple when I do demos Because a lot of times you can't see the forest for the trees when it gets really complicated
so I'm just going to query the function PS drive and You can see the functions on there They're not part of a module. Well, there is one. Well, there's one already loaded on there It's part of a module part of my mr. Toolkit module and that's that Mr. Toolkits available on github and in the PowerShell gallery The latest code is on github. So I'm going to remove those
And a lot of people that what they'll do is close out PowerShell and reopen it Because it's not part of a module to get rid of those You can simply just delete them off the function PS drive and you'll notice that they're gone Now the one that we had the unapproved verb for still exist
So with it anytime you have a module, I mean, this is this is pretty simple here But you would just remove the module which it sounds like it deletes it off disk or something but it doesn't I call it unload the module because it unloads it out of memory and Then if we check for it you would see that it doesn't exist
There's a lot of commands in here So I wasted a lot of time on my demos this year because I had the bright idea Since I've been writing books on the lean pub I said I'll write all my sessions as a chapter in a book and give it to everybody Well, I guess about halfway into that project
I figured out that there's no way I can finish this and get my demo ready, too So I abandoned that and I may do that at some point in the future You know, but what I did is I took the book and I cut and paste out of it and then reformatted everything in here So if you read through this you're going to get the context of the book
all except for the stuff updated this morning right before the demo and I did that also because Don told me not to do it So I guess I'll have to start covering up this mic when I say that sort of stuff Oh
So all the text says exactly what I've told you now dot sourcing functions So one thing I was told is you could go a long time and not understand the function PS drive or dot source and functions And all that sort of stuff. I'm sure all of us probably know what dot sourcing is, but just in case you don't We're going to create a new function in a ps1 file and we're going to add some code
I don't like typing to be honest with you That's why I like tabbed expansion and also I'm going to inject code into my files so that I don't have to type and This is one of the reasons I'm using isc steroids and I know other products do this too
But I can just say yes, and hey it refreshes So the problem when you run a script You could go a long time also without knowing this but I ran the script I call the function in the script
So we got an error it doesn't exist and how many people know why I got this error Okay, good. Yeah, see that's why I never assume anything Because I've presented before and a lot of times people say oh well that was too easy and a lot of people say well That was really advanced. So I have a hard time after working with PowerShell for a long time judging
What I should be teaching because I'm like, oh, that's super easy and somebody else is like, well, that's really advanced So the problem is is The function is in the ps1 file and what it does by calling the script Appear it loads it into the script scope
So when the script exit it deletes the function so it no longer exists on the function ps drive It actually never put it on the function ps drive because all those are loaded in the global scope so what dot sourcing is And I could look at the function ps drive and we would also get an error there
but if I query the the Well, that that's the same command. I just ran if I dot source the function So there's a space between these dots and all that is it's a little confusing looking But it's a relative path So it's dot space and then the path to the ps1 file
So if I run that and just to show you I want to make sure I didn't run these I put comments But I could I could dot source the fully qualified path And there is a space in there or I could use the variable has the C demo in it So I could use a variable So that dot source is it and what dot sourcing does it loads it into the global scope?
So even when the script exits, it's still it loads it on the function ps drive and it still exists So now you can see sr71 is the name of my computer and I keep saying I'm going to rename it to the name of the guy in Star Wars the
I forget his name Finn, whatever his like NC whatever name is too bad. I don't have any more prizes So you'll notice it doesn't exist in a module
Now this is a great way to test your functions and what you want to do when you're testing your functions Don't test them in the ISC or even VS code test them at the console and have you ever had the problem? Well It doesn't work on other machines, but it works on my machine
Use the no profile option so when you call PowerShell dot exe or The PowerShell core executable which I can never remember the name of that thing There's a no profile option to make sure you're not using a profile that when you're writing functions you can all will you also use a require statement at the top and
you can specify the PowerShell version that it requires and You can also specify the modules that are required because maybe you're using a module that doesn't exist on that target computer All that information is in here
So we're going to go ahead and remove that function from the function PS drive We'll double check make sure it's gone. It is gone so variables
Okay, so don't don't use static values Use variables and parameters Hungarian notation The fastest way to find out that if somebody knows PowerShell or not is to see how they if they're using Hungarian notation
And I have seen people and I won't mention any names But on really important mailing list who are experts in the industry But they're not PowerShell experts and they have emailed code Wanting help with it with Hungarian notation Because one of the problems we have in the industry is somebody they'll be a sequel expert or there'll be an active directory expert
sequel is a good example because they write code too and Then they'll think just because they know transact sequel that they know PowerShell Well, we probably all know that's not the case because although I can write some basic transact sequel It's probably not the best practices because I don't do it every day and even uh
So years ago I took a VB script class and I took a Windows scripting host and I actually took a VB dotnet class and This has been like more than 10 years ago been at the same company over 12 years. I Still have some of my VB dotnet code running in production today that I wrote back then that is mission-critical
So and I won't go into detail about it But I Probably what I probably need to do the next time it breaks is I need to use PowerShell studio and I just need to rewrite a GUI on top of PowerShell to do that process because that's what I know a
Lot of sounds with sequel. I'll even suck the data out of sequel server and then do some Some sort of translation or some sort of Manipulation with the data and then I'll stick it back in sequel just cause I know how to do it in PowerShell But I don't know how to do it in sequel Okay, that's Hungarian notation
if you didn't know what it was it's typing your variables with string or int or so on and Since PowerShell is a typed language You've made you can uh You don't need to name it the type of object that it is If you want to know the type of object you just pipe to get member, you know
It's really easy to find out the type of object. So it should be out file and not str out file Use a meaningful name for your variables It'll make troubleshooting a lot easier so Don't reuse variables and I'm guilty of this
I have a good example a great example that I wrote some code and I used a variable and Then later in the script. I didn't need that variable anymore. So I reused the name and it worked great and then six months later and let's see I Have a slide on that. I want to share now why it's okay. It's the next slide
Why it's in context so Anyway, this is a response to me I was looking for help a great place to find help is on PowerShell org on the forums even as an MVP Hey, I don't know everything I asked for help
And uh, I believe in staying humbled But it's kind of funny that Dave Wyatt if you don't know who Dave is. He's a great guy he He's Like he's like a Jedi like a PowerShell Jedi. He's always got the answer and it's always the right answer
If you've been on the PowerShell forums, I'm sure you've run into him, but he tells me that hey I was using VM and he would use VM and VM object instead of using VM twice because you can't tell What different type of thingies are in your variables? So I thought that was kind of funny So a lot of what I'm covering in this session is pitfalls that I've had or
Things that's been difficult for me to learn sure exactly So yeah, six months later. It seemed like a great idea on day one. It worked. Perfect six months later
I'm like who wrote this?
Okay parameter naming. So try to try to design your parameters like the building command It's like computer name and it's computer and then up so C is an uppercase and the end is an uppercase Try to and use the the cmdlets that like ship with windows
Even if Microsoft writes them and I'll pick on the azure cmdlets Do not model your commands after the azure cmdlets Whatever you do and I probably don't have to say anything else about that. You probably know it's exactly what I'm talking about So anything but the azure cmdlets, you'll probably be okay
But the real built-in ones that ship with windows that was written by the PowerShell team are probably a good example to model your parameters and your cmdlets in general off of plural parameter names So a lot of people have trouble like I'm going to query multiple data potentially query multiple Databases and should my parameter name be database or databases?
Well, there's documentation out there that says You should only use a plural name When it when it always accepts plural values it won't accept a single value, which is probably never Because if you can give it multiple values, you can probably give it one so I never use plural names to me
It's more standardized So avoid them So it if they if they can accept a single element then And I've already said this if they accept a single element they should be singular
Even if they can accept a multi elements so Pascal case name just like so this makes it real easy because you're going to use Pascal case for a lot for your name of your command and for your parameter names don't use lowercase computer name and what you want to try to do is
When somebody downloads your code you want them to feel like that most people's going to know how to use PowerShell if they're downloading your commands anyway, or at least know how to call the commands and That way when they're using your commands and they're they've already used things like get date and get service and get process and so on
It kind of feels like the normal commands It's going to prevent your phone from ringing if it's internal to your company or Issues on github or so on that people can't figure out how to use it and help is another thing and we'll cover That in a second, so let's jump into the present into the demo again We have about an hour left at this point, so I'm not using the timer. I don't need the timer
Yeah, it's getting a little warm in here. I
Didn't bring shorts one time. I wore shorts too. I left. I live in meridian, Mississippi So I left home in shorts, and I got to see out on us freezing to death And but I checked the weather on Saturday It was colder at my house in meridian, Mississippi, then it and it wasn't Seattle on Saturday We had some unusual weather. It was 20 degrees difference in mind in my mother's house, and she was like two hours south of me
Okay, so what I'm going to do here. I'm gonna do exactly what I just told you. I'm actually going to Call the function right after I load it So I've used computer name and I've already I was going to ask you why use computer name instead of server name host Actually, I didn't know I've got the answer right there anyway, so it really doesn't matter and
It's about making your commands look and feel like the native ones and if in doubt just go query the native ones Maybe I'm unsure So I'll write a hey and why not use PowerShell to find out it's write a function
So should I use computer computer name server name host machine or so on? Well, there's a few with different different uh Different ones, but by by large computer name wins. There's a few with server name There's one with computer. So that's how I figure out how to what what command to use
what? parameter name to use So let's get back to our well there was one more command I do want to run so I had I had trouble with one recently and I I chose the wrong one
So I use file path instead of file but if you look at that 74 commands with a path parameter and eight with file path and that's out of the ones I have loaded because earlier I had no other modules loaded when I ran through my demo at the hotel and I had 32 commands or
Maybe 33 they had a computer named parameter and none of the other ones they had zeros So maybe it's that mr. Toolkit module that I loaded that I wrote Somebody tweeted out a really old blog article mine a while back
I mean like from 2009 and I I've got a I'm going to archive some blog articles because I tweeted back to him and I Said whatever you do don't do it that way So, of course I can tab expand to see what the parameters are
But I prefer not to do that. So I'll just show them in so right now. I only have a computer named parameter Because this is a function and not an advanced function There's another way to see them and get command sovereign run it that way also So we're about to do something really complicated and when you don't know how to do this
It sounds like it's like huge. We're going to create an advanced function Really complicated It's so complicated That it takes one line to do it commandlet binding that turns a function into an advanced function
There's almost no reason to not turn all functions into advanced functions. Now. You may have some helper functions and that's fine And what that gives you is common parameters So now if I'm gonna run the same commands I ran before the only thing I've changed is add commandlet binding
So now notice I have common parameters and then you can see all the individual common parameters by querying it the other way
most of these sections Now have recommended reading so everything you ever wanted to know about PowerShell is in the help You really don't need to buy any books The About help topics are a great great place to read and what most books are they're just the cliff notes versions of the help topics
Okay, so who likes to prevent resume generating events? See as you can tell I like I like to little live a little dangerous, you know, so Do one does updates before presentation update your demo?
So there's no what if or confirm for those things Anyway We want to add what if and confirm support to our function and the way you add that is supports should process That's it. Very simple And when would you add this? That's what most people have trouble knowing when to do this
They either always do it or they never do it. So if your command is going to make changes Then you would want to add what if and confirm if You're just running something that gets something that makes no changes. There's no reason to add this
So you can see now I've got what if and confirm and I'll just query it the other way and they're at the very bottom
What if and confirm so if all the and see I said it again, so luckily all you guys have a book already If all the commands in your function already support what if and confirm you have nothing more to do it's automatic
But if they don't then you have to write additional code I don't have a demo with that code, but I'm going to tell you where to find the information So if you go out to my blog, there's a free book on there It's called free book on Windows PowerShell advanced functions. It was written by six
MVPs and I wrote one chapter in it. Jeff Hicks wrote the chapter on on Confirm and what if so you can go download that and read that chapter and it's a deep dive into that There's also parameter validation. I wrote a chapter June Blender wrote a chapter Adam Bertram
Francois Xavier Bo Prox, it was a entire week of articles And they're actually blog articles on our all our individual blogs But we compile Jeff compiled it as a book and then I stole it and put it on my blog
Yeah, I would definitely recommend going through there and reading that to get the details of that
So now we're going to jump into parameter validation And while a lot of people don't consider this to be parameter validation I use type constraints and I recommend it and what I mean by type constraints is I'm going to type computer name as a string
So if I call it with one param with one value for the parameter It works fine if I call it with two again error That's because I'm accepting one value because I've typed it as a string a problem with this You probably don't want people to ignore the computer name parameter
But they can ignore it not give it a value at all. It's probably not what you want So in order to prevent that you would use a mandatory parameter I'm not going to cover all the different parameter validations because there's like 50 million of them I could do it I could do all hour and 45 minutes on that. So now what we've done we've
We've said mandatory and this is PowerShell 3 plus compliant code PowerShell 2 is deprecated so I quit right in PowerShell 2, but if you wanted it compliant with PowerShell 2 you would say equal Equal true equal dollar sign true or equal dot you would you would never really have to say equal dollar sign false
You would just leave mandatory out And I think that's one of the reasons they got rid of the Equal true is because if you specify it it's on and if you don't specify it, it's off To show you how that works
So now if I don't specify anything it prompts me to say yeah got to give it a computer name So I could say server 01 I hit enter All it did was return server 01 it could have done did whatever So the problem is what if I want to give it more than one computer name?
So now what I've done is I've actually I'm going to allow it to have a an array of strings Still have the mandatory parameter now when I call it without the parameter notice. It says computer name zero
So I can give it multiple. It'll keep asking for names until I don't give it a value and press enter So that's how you can restrict somebody to using a certain type like an integer or you can
One value versus multiple values so One of the pitfalls is default values do not work with mandatory parameters. I See a lot of people try to make this work Doesn't work. So I've given it a default value here this here you call the function
Guess what didn't use the default value? So what you have to use you have to use a different type of parameter validation if you want that functionality Use validate not null or empty
So I've removed I've removed mandatory and added validate not null or empty. There's a lot of these different ones I've got another good example to you of one. I never use you can do validate count validate pattern validate script
I should have the about help topic in here that lists all those So now if I call it without specifying the parameter guess what gives me the local computer name because The default is environment computer name and it's preferably to use environment computer name over daughter local host
It makes it a little more dynamic and it's considered to be a best practice Sure, yes
What I would do is uh, so you might be able to use yeah What you could do I?
Wouldn't use validate set I would use validate script Is how I would do it and then that way I could call the other function And I want to show validate script here in just a minute to populate that but dynamic parameters may be a better fit for that
Okay, so when I do specify the parameter and values then I get the parameter and values So you get the best of both worlds and you also can't if you give it a null Or you get them an empty string along with the value. You'll get an error Because it doesn't allow about
nulls or empties validate pattern I Never use it. You can write your own better So I've got this long regular expression of validate of file name who can read that who knows what that means
Anybody in this room? Yeah, my nasty salt. That's exactly right. I talked to him last night. I'm like all this grouping and this look ahead and That gets confusing So the reason I don't use it
Always like to be very specific There's a reason I do everything I do Okay, so somebody
Yes, PowerShell will allow this The reason that so it tells you what you specified does not match this Pattern exactly probably meant nobody in this room would know what they're talking about either
But yeah, definitely a normal user supply an argument that matches this Yeah, okay, I Don't know about you guys, but I don't read regular expressions You can and that's what I'm going to show next
You could do the help now I don't use the help in parameters because what I've done I've queried all the native ones and there's like almost they never use those so that tells me that normal users probably don't know to look for that help a simpler way is just to return a meaningful error message and
That's when I write my own and use validate script I use the same regular expression very similar code The one thing that this allows me to do is return a meaningful error message, which you can see here
But at that point in time you're asking for users input And I'm just using file name as an example Probably you would have them put a path in and you would do like test path on the existing file name Well, typically what you want to do at least from a best practices standpoint. You don't want to validate
You don't want to validate input inside the function You don't want to allow it to get that far you want to validate input at the parameter and say nope. I Mean to me why allow your script to continue any further than it has to If if the user doesn't provide valid input and the other thing by using the parameter validation that's built in now
It is a custom script. So it's really not a lot of difference in that scenario but one of the reasons I use parameter validation is My validation that I write it's going to be very similar to anybody in this room. So it's kind of standardized and
certainly if somebody Has a different way of doing things Please speak up because there's been things that I do certain ways that I have changed based on knowledge from other people Because I certainly can't think of everything. I think I already ran that
Okay, so now you get this message it's either not a valid file name or it's not recommended So you can read it and usually you're not going to write a lot of code in there. Anyway, I
Scroll up just a hair So it's very simple. It's just validate script it says hey if it matches this then true and if it doesn't then throw an error and what I'm
what I'm curious and it relates to the other gentleman's question is Something I have not tried is can I call that other helper function from this There you can
So that may be the other option is just call your other script from here So that way your code is a helper function. So enumerations are another way to validate
To validate input. So if I if I run this it's going to return all the colors So if I provide it with a couple of colors It's going to say hey, yeah, those are valid Maybe I want to use pink Sorry, can't you use pink so it's got to be a valid value inside the enumeration to be able to use it
and the only thing of I've done is is used it right here use the enumeration as a value Or as parameter validation, it's very similar to using a type constraint
Okay, so how do you find enumerations? That's the question I always get. You can run this command here, which is seems to be a really complicated one-liner. It'll give you a list of all the enumerations. An easier way is to
Warren Frame wrote a command called get type that you can find in the TechNet script repository. I've actually added it to my Mr. Toolkit module. It's still got Warren's name in it, so he still gets credit, but you can run that command and it returns all the enumerations.
So an example is the ones for the days of the week. It's probably an easier way to get the ones for the days of the week. So the other thing is type accelerators. How much code have you seen people write to validate IP addresses? And it may not be a lot of code,
but how complicated code have they written may be a super complicated regular expression. So is this valid?
It is. Is this valid? It's not. And the good thing is for this little thing, IP address, that's it. That's all the code I wrote, and I can validate IPv4 and IPv6 addresses. So hey, IPv6 valid,
IPv6 not valid. Now earlier, I added some code, and I imported my Mr. Toolkit module at this point, and I got different output from that command. I'm like what? But it's because I have the same function in that toolkit, and it's different.
Oh well that one would be not valid anyway. I think it'll it'll allow strings. Yeah, you can validate. There's one for email addresses also.
So I'm going to show how to get all those also. So I want to open up the one that I had earlier. So this was another one I wrote because the output I showed you is probably not really the output you want. So I'll just go ahead and load this function. So it'll be the last one loaded, and it will win when I run it.
So now if I run this command, that's more like the output you would want. Hey true. False. True. False.
Yeah, so everybody always asks how do you find the type accelerators? Well with this command, but there's an easier way. I think it's called mail address. Yeah, there it is.
And it works really well. I've tested it. An easier way if you have the PowerShell community extensions, which is written by a PowerShell MVP by the name of Keith Hill, and Keith works on VS Code a lot, so he's contributed to that. But you can run this command.
Now what I will tell you is if you have the PowerShell community extensions installed, if you haven't previously run a command in there, this won't trigger autoloading is what I'm getting at. So you have to import the module before you can actually run that command. I kind of found that the hard way. It's like why is this not working?
And it's kind of like PS drives, they're not there automatically. They don't autoload. So we're down to about 40 minutes. Multiple parameter sets. This is something I find that not a lot of people do.
Sometimes I do it one way versus the other, but and I'm going to base it off what David said is
you should probably use the import them and use the fully qualified name because maybe you have like the VMware module and the Hyper-V module and maybe they have some of the same commands and you want to make sure you're loading the right one. The reason that I loaded it a lot manually because I
I have my modules in my GitHub folder instead of them that I'm developing instead of my PS module path, so I import them because I would want to make sure I'm controlling when they're imported. Really, and I could see that.
But yeah, it's probably best to I would say to always be more declarative to be very specific. That way you know you're going to get the results you expect
to be explicit. Okay, so we're going to create a function with multiple parameter sets, and this is this is a little code snippet from one of my DSC functions. So I've got a name parameter. I got a module parameter and a path parameter.
I want name and module to be available in separate parameter sets. So let's take a look at the syntax. I've got two parameter sets. If I call one, I just have it return the name of the parameter set.
If I call the other one, that works too. The problem at least right now is positional binding does not work, and I've actually told it what the default parameter set is. So you can see the default parameter set is name.
Not used to using the trackpad on this laptop. I have a docking station at work. It's the other thing to be productive. I like to have three monitors, so and that's one of the reasons I use this ISC steroids, and I know other products do this, but I break out the the output pane on a separate monitor.
And that's one of the reasons I still like this because you can't do that in VS code. And it gives me more room to write code. You know it's just a personal preference. But I do use VS code, so and while I'm talking about VS code. I'll get back to the to this. This is what my VS code environment looks like, and I have a video on configuring it this way.
It's on my blog. Oh, and one more thing. I don't think I ran this earlier, but let's go ahead and run this, and I know this font's really small, but notice I actually have my VS code defaulting to PowerShell core.
So I run stuff in the ISC and use Windows PowerShell, and I run it via VS code, and I'll use PowerShell core. And if you're interested in that, the it's all done in the configuration.
I noticed this morning. I still had 6.01 referenced, so when I opened it up. I had an issue, but I had to update that. Okay, so what up? the problem we we have is a positional binding is not working. So what I found even though I said a default parameter name set,
I have to set a parameter in position zero for it to be positional. So if I look at the syntax now, and all you guys should know what this means in this room.
So I've got square brackets around name, which means name is optional, but the entire parameter is not optional because the entire thing is not in square brackets, and module, of course you can't have module and name both positional because it wouldn't know which one, but if you use module, you have to specify module. So now notice I'm going to call the command with
without the name parameter, and it's going to work positionally. There's a little bit bigger problem that I found or a little misconception. So I want you to notice here,
so what I've specified, I've seen a lot of people do this, so I specified parameter set, name, then module, and I specified parameter again with all the different options that I want to be the same in both
of those, and this might, it may initially appear to work, but it doesn't work properly, and it's because you, well, I'll get to why it doesn't work, if I can select this.
So notice path is in position one now, so I can pipe something in.
I can pipe in the path. Hey, it works great. I can look at help for that parameter. Hey, I can pipe in by value and by property name. That must be a win.
The problem is, and in both the parameter sets for path, it actually shows value from pipeline and by property name is false when you drill down into it.
So how's that? What's the deal? It's because I didn't read the instructions. I didn't read the help topic. So if you're going to specify all the same options in both your parameter sets for the path parameter, there's no reason to specify parameter more than one time.
Just say parameter and specify what you want and say that's it. It'll be available in both with all the options.
So the only one, I'm going to skip these first two and run this last one, because the first two is going to return the same thing as before. So what I want you to notice is now they're available by property name and by
by value. I hate the word by value. To me, it's by type. It should be by type and by property name, because by value actually binds by type. So what if I want different options
for path? So what you should do is be explicit. Notice the square brackets opens here, and it closes here, and that's for name. And then I'm explicit again for module. So I have to specify the options that I want in each one of these blocks for that parameter name.
And it works perfect. It's one of those things when you search the internet on how to do something instead of figuring it out for yourself. Let's do this. Make our life easy, and we'll just run the last one. So I specified different options.
That's what I'm trying to show you here. So you'll notice
with one of the parameter sets, it can come in by by value and by property name. And I thought I had different ones. Maybe not. Oh, did I? Okay, thank you. But I ran the entire thing one more time.
After this, I have a couple things I definitely want to cover that's not
very intuitive. Here we are. Okay, so the bottom one is false. One of the options you got true false, and you got true true. So that's how you get different options, and it works perfectly, because until you drill down into these commands, you can't see that there's a problem. I think we're going to come back to, well,
let's see, we've got about 30 minutes. I'm going to come back to the return keyword, because that's totally separate, but I'll just cover it real briefly, is return is probably the most overused command in PowerShell, and it can cause you a lot of pain, too, because
when used inappropriately, it will actually exit out of a loop and not return all the values that would normally be returned. Now when you're using classes, you need return. You have to use return in classes.
I do want to show you this real quick. I can't leave you hanging. So in PowerShell 4, I wrote a new Mr. GUID function, because with DSC there was no new GUID command. So I'll use return, so hey, it looks great. So what's the big deal? You can get the same results
by just calling the variable. That's not really how I like to do it, though. How I like to write my commands is to use write output. It's going to be the same output. The problem is it's not always the same, and there's
really no reason to store it in a variable and call the variable anyway. You could just output the value, cut to the chase.
So this one, I'm not using return. So without the return keyword, it returns any grade or number than 4 is returned. So notice that, 579.
Same code. I'm going to add return. Who knows what's going to happen? There you go. So you guys know this. So that's why you, if you're in the habit of using return, and you use return all the time, you're going to shoot yourself in the foot. So, and I'll just show you that real quick.
So I want to make sure we, so it's going to return 5, and then that's it. It exits the loop. Now I've kind of got the same sort of thing going on here, so it shouldn't take very long.
So we just use a range operator and give it 1 through 10, and notice the total of seven items were returned.
So we add return. I have a detailed blog article on this as well. So now when I run it with return, guess what? We don't get the verbose output. First value, that's it.
You should use it in classes, and if you understand how to use it, then yes, because you may want the functionality I just showed you, you may want to grab the first value, and then that's it. Just understand how it works, and the the help topic for return is really good. I've got, well, I believe I have a link in here.
Oh yeah, so I've got all the, all the links I have in here go to the PowerShell core help topics, and I cut the version off the end of it, because that way it'll go to the latest version even if you look at this in a couple of years, and it, they've got version 14 now.
So verbose output, you guys probably know how to do this, but I've got inline comments. So if you're doing something like return, you might want in inline comments, but nobody's ever going to see this, and from what I've found, people will go update the code, and they'll never update those comments.
So I would rather have no comments than comments that are wrong. So when I run that with the verbose parameter, sorry, can't see it. Same command, except I've used write verbose.
You call it without verbose, you don't get it. You call it with verbose, you get it. So that's it for write verbose. Pipeline input.
Oh, what fun. So we've got about 25 minutes. Okay, so what we're doing here, what we've added, we've made a parameter mandatory, and we're accepting
pipeline input by type. They call it by value, but it's really by type. If I pipe a string into this, it's going to bind to the string, and that's why you can't have value from pipeline on two different strings.
And if I pipe these to get member, of course, if I scrolled up, you guys know that those are strings. Server one and server two. It's pretty self-explanatory. So what I'm going to do now is create a custom object. It's got a name of computer name, and it would show PS custom object if I piped it to get member.
When you pipe it in, some older versions of PowerShell would actually give you an error, but newer versions just give you some output that you don't want. So now let's try by property name.
One thing that, well, and I have another script to run. So now I'm going to try to pipe my strings in, and guess what? Nope. We don't accept pipeline input by type. But if I pipe the custom objects in,
they work just fine. And also be aware that syntax I was using is version 3. Well, actually the mandatory would be equal true if it was version 2, but the value from pipeline, I don't remember if it had true on it or not.
But anyway, I quit writing version 2 since it's deprecated. I do have one box with version 2 on it. All the boxes in my environment have 5.1 except for the exchange server. Don't touch it. It's running exchange 2010, but we're in the process of, it's in hybrid mode. We're going to Office 365.
So what I have done here, and see there it is again, somebody wins a book. I've allowed value by pipeline, by type, and by property name. So I can pipe in my strings. I can pipe in my custom object, and hey it works either way.
But one thing to note with this is it's always going to try by value or by type as I call it first. It'll only try to bind by property name if by type doesn't work. I think Don in his book he called it plan A and plan B.
So one thing that trips a lot of people up is the values you pipe in are not available in the begin block. So notice it should say test and output the computer name. It's only going to say test because you can't access those values in the begin block.
So let's get cover error handling real quick. I think Jeffrey Snover covered this a little bit yesterday. There's something very specific I want to cover. So I have a function that has no error handling.
I try to query a computer name that doesn't exist, and I get an error message. It's an unhandled exception. So the only thing I'm going to do to this,
try catch is what you add for error handling. So notice when I'm calling test ws man, I have it inside the try block. A catch block, so with try catch a lot of people think oh, I have to have a try block, have to have catch block.
That's actually not true. You have to have a try block and you either have to have a catch block or a finally block, but you can have all three. But to me I always have a catch block. I guess that's why people make that assumption. But guess what?
It's not going to work. So still get an unhandled exception. And why do I get an unhandled exception? Because it's not a terminating error.
So I've said I've added error action stop to this. So one of the common questions is what I do if I'm running a DOS command or something in .net, it doesn't have error action parameter on it. So there's an error action preference variable. What you can do is
immediately before you call the command, change the error action preference and then call the command and then change it back. But what you need to do is actually store the error action preference variable value in another variable because the default is continue, but something else could have changed it from continue to something else.
So you want to make sure you get it back to what it was originally after your command runs, so don't make assumptions. So the comment is that's a good place to
set it back in the finally block, and I've never thought about that, but that is a good idea. I don't know why David didn't raise his hand when I asked for PowerShell experts, or maybe you did and I didn't notice. I mean this is actually, so you guys know he actually, he's the guy that writes the code. He wrote PowerShell Studio.
So now when I call it, I'll get a, so I gave a warning instead of an error. It's a much nicer. So we've got a little over 15 minutes left. My alarm's about to go off, so nobody panic.
It's not a fire alarm. Comment-based help. I've got long live comment-based help and comment-based help is dead because I've been looking at MAML, but I talked to some other MVPs. I was at the MVP Summit last month here in
Seattle, and although Platypus is available, and there's a session this week you should check out, I'm not sold on a MAML-based help, especially after what I heard yesterday, and what most MVPs said for the code they're writing, what I've been told in the past, and I still hold this as valid, is if I'm going to write something to sell, I'm probably going to create MAML-based help.
What MAML-based help gives you is multiple cultures, so different languages, help for different languages, and updatable help. That's the two things that buys you. But most MVPs that I talked to,
they said, with the code I write, if I need to update my help, I'll just publish another version of my module, a minor version, and the other thing is, they said, I wouldn't attempt to write it into different cultures, you know, especially the people like me. I only speak one language, so I don't think I'd trust Google Translate. There you go.
Okay, so I'm going to skip over those sections. So, a script module. How do you create a script module? If you ran help new module, you would find out, as I previously said, that creates,
that creates dynamic modules in memory. There's no command for creating a module. It's called new item. So, I'm going to create a folder and a file, a PS1 file, so your script module resides in a PSM1 file.
I'm going to inject a couple of simple functions into that file and open it up. Let's close these out. I was glad to see yesterday, they mentioned there's a command similar to PSEdit in
PSCode. So, that's one of the pieces of the puzzle I was missing. So, I tried to call the command, hey, it doesn't exist. What's the deal? So, yeah. So, that's the alarm to let me know that Don Jones is going to show up in five minutes.
I did not.
So, anyway, you see where it resides at. It's not in the PS module path is the problem. So, I would have had to import it explicitly or put it somewhere in the PS module path. So, the PS module path and, let's see, we've got a few minutes.
So, it's pretty easy to get the PS module path. You guys probably already know this. I had the AWS command that's loaded, so I have one extra value here. I want to talk about these real quick because these can be confusing. Just clear the screen before we do this.
Okay, so the first one, I never use this. Why? Because that's not my My Documents. I have three Active Directory users. One, I'm a standard user on my desktop. I'm a standard user in the domain. Number two, I'm an admin user on my desktop.
Standard user in the domain. And number three, I'm an admin on my desktop and an admin in the domain. So, I log in as a standard user and then I run PowerShell as an admin. So, it's a different user. So, Mike F. Robbins is not the user I'm logged into the box as. So, if I go to My Documents, it's not there.
Now, that's one change I've made with VS Code. I run VS Code as a standard user and then I actually, if I need to test as an admin, really you only need to run PowerShell as an admin if you're doing something that requires UAC elevation on the local box. If you're running stuff against a remote box, then UAC doesn't come into play anyway.
So, the second path, this was added in PowerShell 4. This is where you should put, this is the all users path and typically, what I would recommend is put all your production modules in here that are user created and
this is where the PS Gallery installs by default unless you give it scope of user. Say that again. Yes, and that, I guess that is one reason to run this as an admin because you would, though, and see the problem with that, I have another problem because the user I'm logged into Windows doesn't have access
to that users. Yeah, so it's it's kind of a chicken and the egg problem. It's okay. It's not something I do or I've really thought about.
You would, it would just be a dependency that you would have to validate. That would be my main concern is having a dependency. It's not there by default, but it's no different than the AWS module, you know.
So, I wouldn't say it's a bad thing if it's a standard in your company. I believe in consistency, so if that's your standard, set it as a standard and stick with it. So the the Windows folder, the system 32, you'll read some of the outdated documentation that tells you to put modules in here. That is false.
I've been told by a member of the PowerShell team, or multiple members of the PowerShell team, you should never put anything here unless you're Microsoft. Now, I think the old documentation was before this all users path existed and I'm curious to know you can install the PowerShell Gallery on PowerShell 3 and 4 and
I'm curious to know if you install the PowerShell get module on PowerShell 3, how does it handle to all users or does it create this? Because that didn't exist in PowerShell 3.
The one thing that can trip you up on this is the PS auto loading preference, which has no value by default. I changed this once upon a time to none because I wanted to go back to the functionality in version 2. Well, yeah, it doesn't work that way. If you set it to none, it means none. No core modules, no nothing. You have to import everything.
So if you run into trouble with auto loading and you know your modules in the right place, you might want to double check this. And if you're like David and you want to always module qualify, you could set it to that.
Okay, module manifest. We need to move this. This trackpad is killing me.
Okay, so we moved it in a PS module path. Didn't do anything else. No importing, no nothing. Just copied it. Guess what? Now it works. So I do like that functionality, but you may not get what you think you're getting. There's an order of precedence too with aliases and functions and cmdlets.
I know that Jeffrey Snover, I think he talked about that in his unplugged demo at Ignite last year, and that was really interesting. So if you run get module and you see a module at 0.0, it's a dead giveaway that that
module probably does not have a manifest, because I don't know of anybody who would publish a module at 0.0. I heard a talk one time from Lee Holmes who said all modules should always have manifest, and it's metadata about your module. So we're going to create a new manifest.
And what I've used here, you guys probably know, I've used splatting because it's a really long line. I don't want to use the backtick as line continuation. It's not exactly, I don't think that's what splatting was designed for, but it works well as that. I think it was designed so you could dynamically
allocate your parameters. Like if you have a credential parameter, you can add it to a you can add it to a hash table if it's specified, but not if it's not specified. You can check the PS bound parameters. So I've got a little snippet here about line continuation,
and I think I'm going to skip that because I think I've talked about that enough. There's a Plaster session this week. I am going to cover Plaster real quick. This is kind of getting toward the end of the demo. So you're going to start from the PowerShell gallery. I have a detailed blog article that I wrote recently about this.
A lot of my recent blog articles were building up to this session. I was like, I don't have time to blog in and work on this session. So what I've done here, I've actually created, I've created the information that's required for a Plaster template, and I've sorted in hash tables, and I'm going to splat that also.
I'll open up the XML file that I just created. So that's what it looks like. It's got my metadata basically in it, and that's metadata about the Plaster template, not about the modules.
I'm going to create a PS1 file that's going to be used for every one of my script modules. It's going to dot source the PS1 files. I'm going to open that up. So I use something like this on every one of my script modules because I put my functions in PS1 files, so when I put it on GitHub, it's really easy for somebody to grab one function.
There is a link in this slide deck from from a MVP from Europe who I saw do something last week that I'm really interested in. I like this for GitHub and for development, but I would prefer my functions to be all in the PS1 file when I put them on the PowerShell gallery for production.
He's written some code to put it all back together and do unit tests and all that sort of stuff on it. So the, uh, Plaster does that? Okay. I did not know that. I'm actually a newbie with Plaster.
What I did, I used to have a function that created my script modules and functions, and it was very specific to me, and what I decided to do was translate that exact functionality to Plaster to reduce the learning curve. So what I'm going to do now is actually update the Plaster template with the information that I
want to add to all my modules, and it's not that one. It's this one. So you can see here in there all my modules. I've got parameters here, and I've provided some default values.
It's going to want the module author's name and all that sort of stuff, and then it's going to prompt me. Well, no, it's not going to prompt. It's going to replace this with some of that parameter information. Excuse me. Keep forgetting about the microphone.
So what I'm going to do now is create a script module.
So I have to give it this information. So I'm giving it all the paths. Now what I would recommend when you create your script modules, the only thing that's required, I believe, is the path, but from what I've found, if you don't give it a root module, your module won't do anything. Now I've found I've actually seen some with DSC that doesn't require a root module,
and I haven't figured that out yet why it works, but for the most part you always have to have a root module. The other thing I would recommend specifying is the description and the author, because if you're going to put it in PowerShell Gallery, those are required.
Actually, if you're going to put it in a NuGet repository, the PowerShell Get, those are required, because they run test module manifest against those, and we didn't run this yet.
Okay, so and I use the verbose parameter. If you have any problems, it can give you additional information. So you'll see where it's located at now. It's my demo folder. That's my plaster template there. I should have had that moved up in my demo a little bit, because I just created the
module. Okay, there's a session on PSScript Analyzer this week,
so if we got just a minute to cover the format data, that's the last thing on the list of what I said I would do, then I have it done. So notice the last thing on this. This is a pretty standard function, but FreeSpace is the very last thing.
I have to add this to my functions to export, so I wrote a pester test. I can actually test it and see if it exists, and it does. Update the module manifest
to add the XML file. Make sure that they still exist. Let's reimport the function. Let's call the function before we reimport it. Maybe I have to reimport it. Thought I had already imported it once.
What I want you to notice is, so this is in a list. I don't really want a list. So we all know that, hey, if it's four properties or less, it's in a table, and if it's if it's more than four properties, it's in a list.
So what I've done here, I've added one line to this very bottom line. I've added this type information. Instead of being a PS custom object, it's going to be a Mr. System Info. I need an XML file that's going to specify the ones that are going to be listed in the table.
We will get there. I actually have to update the module manifest to tell it about the formats to process file. I'll reimport the module, and when I run it this time, I'll get it I'll get a table.
Now the other thing you're going to you can do, and the code is here if you want to see it. Let's see. So we've got like one minute. One last thing. You can always do one more thing. It's like you tell your wife, you know, or your husband, just five more minutes.
And you're like Dr. Jekyll, Mr. Hyde, you know, on the computer. So now what we're going to do, we're actually going to add a type file, because I don't want my output in bytes and all that sort of stuff.
We can run all that. So we'll add the type file to the module manifest. We'll import the module again. We'll run the command. Guess what? Now we've got it in usable values. But the thing that this buys you is those original byte values still exist in case you want to use them down the road.
So if I... Yeah, I know. So notice I've got size and longer values, and that's the last thing I want to show there. I'm going to jump back to the slide deck real quick. And I really want the last slide. Well, we need this slide. We can't leave without seeing Jason again.
So when you get through and you've written great code, then six months later you'll be the guy drinking margaritas instead of trying to gouge your eyes out. So I've got some resources in the slide deck, and that's the last slide. Those are all the books
I've participated in. This is the one that all you guys got a copy of. If you want my email address, go out to my about page and decode it. It's encoded. Thank you.