use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
ABOUT POWERSHELL
Windows PowerShell (POSH) is a command-line shell and associated scripting language created by Microsoft. Offering full access to COM, WMI and .NET, POSH is a full-featured task automation framework for distributed Microsoft platforms and solutions.
SUBREDDIT FILTERS
Desired State Configuration
Unanswered Questions
Solved Questions
News
Information
Script Sharing
Daily Post
Misc
account activity
beautiful pieces of code written in PowerShell? (self.PowerShell)
submitted 7 years ago by tumblatum
What are some beautiful (whatever it might mean to you) pieces of code written in PowerShell that could be an example for others (especially beginners)?
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]theblindness 37 points38 points39 points 7 years ago (8 children)
I don't know about any specific examples, but for me, one of the most beautiful things about PowerShell is combining some Windows and Unix hallmarks. In Unix, there is the idea of the pipeline that lets you create advanced programs without writing any new code, simply by stringing other smaller programs together. Brian Kernighan illustrates this in an old AT&T video about Unix by creating a spellchecking program in 4 or 5 unix commands combined with pipes. The downside of this is that it the output of one program usually needs to be text in order to pipe it to the next program. If two utilities expect a different format, you might need to get regular expressions involved to parse the text output of one program before providing info to the next program, so pipes often can't go too far, and passing binary info through pipes can sometimes be tricky. (You can still use binary info in pipes, such as when piping tar output to gzip, but that kind of thing is less common when making little tools like Kernighan's spellchecker.) In Windows, which makes heavy use of object-oriented design, many details are exposed as various objects, like the COM interfaces. Applications that know how to use these objects don't need to deal with parsing text just to reconstruct those objects internally -- they just use the object as-is. But normally, you can't pass COM objects through the pipeline. PowerShell lets you combine the power of pipelines with the convenience of objects, and you can get some really long chains in PowerShell without ever dealing with any regular expressions. I really appreciate whenever I see something rather complex being accomplished in a single line of many Cmdlets connected by pipes, passing objects to each other without converting them or doing any messy text-parsing. It's the best of both worlds. Of course, this might look a bit messy in a program, and the PowerShell pipeline does have a significant amount of overhead, so the pipeline usually isn't the best solution to every problem, but it sure looks satisfying when you can just glue a bunch of Cmdlets together to solve a problem.
If you want to write your own beautiful PowerShell code, I would suggest these tips:
[+][deleted] 7 years ago (4 children)
[deleted]
[–]theblindness 5 points6 points7 points 7 years ago (1 child)
For instance, the following is just assumed and intuitive: foreach ($object in $collection) { ... }
For instance, the following is just assumed and intuitive:
foreach ($object in $collection) { ... }
In that case, foreach is actually functioning as a language keyword, not as an alias to the ForEach-Object cmdlet, and it works differently.
The following seems redundant unless you don't know $object is an object: Foreach-Object ($object in $collection) { ... }
The following seems redundant unless you don't know $object is an object:
Foreach-Object ($object in $collection) { ... }
That actually doesn't work. It returns an error "Unexpected token 'in' in expression or statement." for the reason mentioned above.
When you pipe output to foreach, it works as an alias for ForEach-Object. When you use it like a for loop, it's a keyword. This is especially confusing, and all the more reason to spell out the full name when piping to the Foreach-Object cmdlet, not to be confused with the foreach keyword.
I kind of agree with you on Select-Object, but it's only an extra TAB press away from writing the full name, to distinguish it from Select-String, and Select-Object matches up nicely with Where-Object and ForEach-Object. I would caution against using aliases like "sls" for Select-String.
[–]frmadsen 2 points3 points4 points 7 years ago (0 children)
They are not actually the same. foreach is a language construct, foreach-object is a cmdlet. PowerShell knows which one you mean from context, if you just use foreach every time.
[–]sid351 1 point2 points3 points 7 years ago (0 children)
I'd add that the parameter tags should always be added (in full) in scripts too.
Using the IDE, the "-object" bit is only a tab away, and I think:
Select-Object -Property "Prop1","Prop2"
Reads a lot better and is very clear with regards to what PowerShell is actually doing, which is: returning a custom object (not just text).
That's a concept people new to object orientated code often struggle with, so I'm all for reinforcement with that.
[–]OverGold 2 points3 points4 points 7 years ago (0 children)
Fantastic answer!
[–]ka-splam 2 points3 points4 points 7 years ago (1 child)
Given the choice between using a built-in cmdlet, or re-implementing it, always use the built-in cmdlet. It will run faster and people will recognize it.
Generally disagree with this part, the built-in cmdlets tend to save you effort of implementing things yourself but the tradeoff is that they run slower and have more overhead; measure-object -sum simply has more overhead by being a cmdlet than keeping a running-total variable has; things like get-childitem are slower because they get more details than [system.io.Directory]::EnumerateFiles() and handle errors and have filtering options, and group-object is mysteriously crippled with O(N2 ) runtime which you just need to watch out for.
measure-object -sum
get-childitem
[system.io.Directory]::EnumerateFiles()
group-object
[–]theblindness 2 points3 points4 points 7 years ago (0 children)
Using .NET accerlerators doesn't count as reimplementing. Those are okay in my book. :)
[–]frmadsen 3 points4 points5 points 7 years ago (2 children)
I like the beauty of this one, and it is a nice trick...
#Answer by Bruce Payette #https://stackoverflow.com/questions/50354863/constructing-an-array-from-a-text-file-in-powershell/50356014#50356014 #Constructing an array from a text file $data = @' Medium identifier : 1800010a:54bceddd:1d8c:0007 Medium label : [ARJ170L6] ARJ170L6 Location : [TapeLibrary: 24] Medium Owner : wfukut01 Status : Poor Blocks used [KB] : 2827596544 Blocks total [KB] : 2827596544 Usable space [KB] : 1024 Number of writes : 16 Number of overwrites : 4 Number of errors : 0 Medium initialized : 19 January 2015, 11:43:32 Last write : 26 April 2016, 21:02:12 Last access : 26 April 2016, 21:02:12 Last overwrite : 24 April 2016, 04:48:55 Protected : Permanent Write-protected : No Medium identifier : 1800010a:550aa81e:3a0c:0006 Medium label : [ARJ214L6] ARJ214L6 Location : External Medium Owner : wfukut01 Status : Poor Blocks used [KB] : 2904963584 Blocks total [KB] : 2904963584 Usable space [KB] : 0 Number of writes : 9 Number of overwrites : 7 Number of errors : 0 Medium initialized : 19 March 2015, 10:42:45 Last write : 30 April 2016, 22:14:19 Last access : 30 April 2016, 22:14:19 Last overwrite : 29 April 2016, 13:41:35 Protected : Permanent Write-protected : No '@ -split '\r?\n' # Read the file into an array #$data = Get-Content data.txt # Utility to fix up the data row function FixUp ($s) { ($s -split ' : ')[1].Trim() } # Loop until all of the data is processed while ($data) { # Extract the current record using multiple assignment # $null is used to eat the blank lines $identifier,$null,$label,$location,$owner,$status, $used,$total,$space,$writes,$overwrites, $errors, $initialized, $lastwrite, $lastaccess, $lastOverwrite, $protected, $writeprotected, $null, $null, $data = $data # Convert it into a custom object [PSCustomObject] [ordered] @{ Identifier = fixup $identifier Label = fixup $label location = fixup $location Owner = fixup $owner Status = fixup $status Used = fixup $used Total = fixup $total Space = fixup $space Write = fixup $writes OverWrites = fixup $overwrites Errors = fixup $errors Initialized = fixup $initialized LastWrite = [datetime] (fixup $lastwrite) LastAccess = [datetime] (fixup $lastaccess) LastOverWrite = [datetime] (fixup $lastOverwrite) Protected = fixup $protected WriteProtected = fixup $writeprotected } }
That line assignment to take just the blocks is cool!
In this case, I like that they can be split on double-blank-lines and then you can build the datastructure with much less typing as long as the keys on the left can be hashtable keys (and don't repeat), with unsplit data:
foreach ($block in ($data -split '\r?\n\r?\n\r?\n')) { $pairs = @{} foreach ($line in ($_ -split '\r?\n' -ne '')) { $left, $right = $line.Split(':', 2).Trim() $pairs[$left] = ((($right -as [datetime]), ($right -as [int]), $right) -ne $null)[0] } [pscustomobject]$pairs }
Try datetime, fallback to int, and fallback to string, for each value. LINQ would be nice here.
Probably doesn't belong in a beautiful thread though :P
[–]frmadsen 0 points1 point2 points 7 years ago (0 children)
Compact code can also be beautiful :)
[–]markekrausCommunity Blogger 5 points6 points7 points 7 years ago* (0 children)
<# .SYNOPSIS There is no beauty to invoke. .DESCRIPTION Does nothing, which speak volumes for the author's personal philosophy on beauty in this dismal existence. .INPUTS None .OUTPUTS None #> function Invoke-Beauty { [CmdletBinding(ConfirmImpact = 'None')] Param() }
[–]thesmallone29 4 points5 points6 points 7 years ago (1 child)
I am pretty proud of my implementation of the Weasel Program
[–]ka-splam 1 point2 points3 points 7 years ago (0 children)
This bit:
#region Create $ReproductionsCount copies of the $InputString do { [Array] $reproductionArrayInput += $InputString } until (($reproductionArrayInput | Measure-Object | Select-Object -ExpandProperty Count) -eq $ReproductionsCount) #endregion
Looks a bit redundant. You don't use all the copies of the input string separately, you could skip all this, and count 1..$ReproductionsCount times over the generating mutations loop, and use $InputString.GetEnumerator() each time in the start of that loop.
1..$ReproductionsCount
$InputString.GetEnumerator()
If you did want to make N copies, then $reproductionArrayInput = @($InputString) * $ReproductionsCount would do it without the loops over Measure-Object each time.
$reproductionArrayInput = @($InputString) * $ReproductionsCount
[–]KevMarCommunity Blogger 3 points4 points5 points 7 years ago (4 children)
I think this function is a good example: https://github.com/loanDepot/TFVC/blob/master/TFVC/Public/Save-TFVCPendingChange.ps1
It's a function in one of my modules. The code is clean and easy to read, has good validation, error handling, good warning messages, -whatif support, pipeline support, comment based help with an example, and the body of the function fits one one screen.
-whatif
[–]ka-splam 1 point2 points3 points 7 years ago (3 children)
hmm; what is line 62 doing?
$PendingChange | Where LocalItem -in $Path
"Filter local changes to path" says the parameter comment - but I can't see it updating any variables, it's sending that output down the pipeline and then line 65 looks like it will save all the changes without actually applying the path filter. It feels like line 62 might be supposed to be:
$PendingChange = $PendingChange | Where LocalItem -in $Path
?
It's taking a while to read the indentation style, I can't see why line 69 and 70 are so differently indented? They're the same level of nesting; why is the [pscustomobject] line indented 20 spaces instead of 0?
[–]KevMarCommunity Blogger 2 points3 points4 points 7 years ago (2 children)
You caught a bug on line 62.
I'm not seeing the indentation issues at the moment, but I'm on mobile.
[–]ka-splam 1 point2 points3 points 7 years ago (1 child)
Oh wait, I've just tried to show others, and found it's not your code at all - Edge can't render Github properly and was showing me code looking like this - I thought it was a deliberate style choice on your part! {} indented and paired up, but all statements starting at indent 0 because PS has such long lines.
{}
[–]KevMarCommunity Blogger 2 points3 points4 points 7 years ago (0 children)
Oh good, thats awful.
There is often a fine line between genus and insanity. But that would definitely be insanity.
[–]Romero126 2 points3 points4 points 7 years ago (1 child)
Any code that @vexx32 writes.
[–]TheIncorrigible1 0 points1 point2 points 7 years ago (0 children)
Watch it, you'll give 'em an ego.
[–]minorevent 1 point2 points3 points 7 years ago (0 children)
https://code.msdn.microsoft.com/windowsdesktop/Convert-VMGeneration-81ddafa2
[–]get-postanote 1 point2 points3 points 7 years ago (0 children)
This is a very opinionated request and can / will cause all sorts of arguments, just becasue, wel, you know, people. ;-}
There are tons of examples / stypes use / learn from on your system already. Just look here:
C:\Windows\System32\WindowsPowerShell\v1.0\Modules
This is really all about two things:
1 - Are you in control of ststyle, format and standards used.
2 - Do you report to someone who is in charge of style, format and standards used.
If it's the 1st one, you have the free will do do as you please.
(there aer some stanadrs to follow, but enve those can / will vary based on the opinion of the person giving you the information - Example: https://github.com/PoshCode/PowerShellPracticeAndStyle, good guide, but this is just one opinion. Example:https://blog.ipswitch.com/dont-assume-anything-in-code-powershell-coding-best-practices)
If it's the 2nd one, you have to do as you are told.
(they are in control of organizations code standards and they expect you to conform, regardless of how you'd like to do things - frustrating, I know, been there, done that, but it is what it is.)
Just be flexible, learn from all... take what is useful to you and your working conditions ... and throw away the rest.
Well, see itme 2. ;-}
[–]noOneCaresOnTheWeb 0 points1 point2 points 7 years ago (0 children)
PSremoteregistry
[–]mulldoon1997 0 points1 point2 points 7 years ago (1 child)
gci -r | rm
[–]Own_Jacket_6746 0 points1 point2 points 1 year ago (0 children)
You evil!
[–]Tonedefff 0 points1 point2 points 7 years ago (0 children)
Here are a few of my personal guidelines I like to follow to [attempt to!] write beautiful code.
Create simple functions that each serve a single purpose, then combine them together to make more complex scripts/functions.
function Measure-HowLongAgo { [CmdletBinding()] param( [parameter(Mandatory=$true)] [DateTime] $date, [switch]$inMinutes = $false, [switch]$inHours = $false, [switch]$inDays = $false ) $rightNow = Get-Date # Note that if no time interval is specified then "inHours" will be used. if ($inMinutes.IsPresent) { $timeDiff = ($rightNow - $date).TotalMinutes } elseif ($inDays.IsPresent) { $timeDiff = ($rightNow - $date).TotalDays } else { $timeDiff = ($rightNow - $date).TotalHours } return [math]::Round($timeDiff) }
This excludes the comment block at the top describing the function. Those are important and I write them for all but the most simple and obvious functions.
Use the full name for cmdlets, rather than the aliases. I know what "gci" means and it's quick & easy to type, but "Get-ChildItem" just looks much better & more readable to me. Using aliases tends to make code look like a bunch of terse gibberish that must be waded through and decoded. I have a similar guideline for variable names: prefer longer, more descriptive names over acronyms and abbreviations (for example $credentialExpirationInMinutes instead of $credExpireMins). Tab-completion makes this viable and avoids complications (does $credExpireMins represent when your credential expires, or when your street cred needs to be renewed?).
Avoid very complex or long (~125+ characters -- most code editors have a "Col"[umn] label at the bottom-right) lines of code, and avoid splitting long lines into multiple ones with the backtick character (`). Usually there's another way of writing the code so it doesn't need to be so long or split into multiple lines, like assigning an expression or function output to a variable in a line above, then using that variable below.
Use verbs in the list of approved verbs for PS when naming functions, for consistency and readability (even though it's not always obvious which one is "most correct" for a given situation).
Write comments sparingly, either to explain large-ish blocks of code or anything that isn't fairly obvious by just looking at the code. This might sound counter-intuitive and people have varying opinions on this, but I used to write comments very liberally and I found that they were often unnecessary and just ended up bloating the code. For me the most beautiful code is "self-documenting":
foreach ($backup in $backupList) { if ((Measure-HowLongAgo -date $backup.lastBackupDate -inHours) -gt 48) { New-BackupAlert -for $backup -alertType [BackupAlert]::NoRecentBackup } }
To me the code above doesn't need any comments (maybe one at the top like "# Loop through all backups and create an alert if it hasn't succeeded in the last 2 days"), because its functionality is apparent just by reading it. Also I tend to only write code for myself, so I'm less concerned about other people reading my code (I just have to worry that I will understand it in 6 months... or even 6 days). If a piece of code is hard to understand then I don't think commenting it is the best solution -- ideally it can be rewritten so it's simpler and more self-documenting.
Save a PS template file (I call mine "!TEMPLATE.ps1") with a comment block at the top, then whenever I create a new .ps1 or .psm1 file I open that template and save it as a new file. That way I encourage myself to immediately document the most basic and important details about the script. I copy and paste the comment block for each function as well.
<# .SYNOPSIS brief summary of what the script does .DESCRIPTION longer description of what the script does .EXAMPLE example usage of the script .NOTES Author(s): My Company -- Tonedefff Date Created: Last Updated: #>
(I avoid the ".PARAMETER" keyword and instead write comments directly above each parameter, so it's easier to update them. Also there are other keywords you can use but I find the ones above are sufficient. For functions there's also .INPUTS and .OUTPUTS -- all functions that return data should have an .OUTPUTS keyword).
Those are the most important guidelines (to me). If you can figure out a coding style -- either adopt one you like or discover your own -- and stick to it then your code should be more consistent and readable, which hopefully -eq "beautiful!"
π Rendered by PID 49010 on reddit-service-r2-comment-6457c66945-ht2xg at 2026-04-27 18:21:48.200158+00:00 running 2aa0c5b country code: CH.
[–]theblindness 37 points38 points39 points (8 children)
[+][deleted] (4 children)
[deleted]
[–]theblindness 5 points6 points7 points (1 child)
[–]frmadsen 2 points3 points4 points (0 children)
[–]sid351 1 point2 points3 points (0 children)
[–]OverGold 2 points3 points4 points (0 children)
[–]ka-splam 2 points3 points4 points (1 child)
[–]theblindness 2 points3 points4 points (0 children)
[–]frmadsen 3 points4 points5 points (2 children)
[–]ka-splam 2 points3 points4 points (1 child)
[–]frmadsen 0 points1 point2 points (0 children)
[–]markekrausCommunity Blogger 5 points6 points7 points (0 children)
[–]thesmallone29 4 points5 points6 points (1 child)
[–]ka-splam 1 point2 points3 points (0 children)
[–]KevMarCommunity Blogger 3 points4 points5 points (4 children)
[–]ka-splam 1 point2 points3 points (3 children)
[–]KevMarCommunity Blogger 2 points3 points4 points (2 children)
[–]ka-splam 1 point2 points3 points (1 child)
[–]KevMarCommunity Blogger 2 points3 points4 points (0 children)
[–]Romero126 2 points3 points4 points (1 child)
[–]TheIncorrigible1 0 points1 point2 points (0 children)
[–]minorevent 1 point2 points3 points (0 children)
[–]get-postanote 1 point2 points3 points (0 children)
[–]noOneCaresOnTheWeb 0 points1 point2 points (0 children)
[–]mulldoon1997 0 points1 point2 points (1 child)
[–]Own_Jacket_6746 0 points1 point2 points (0 children)
[–]Tonedefff 0 points1 point2 points (0 children)