Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 542899
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 13, 20262026-05-13T10:29:41+00:00 2026-05-13T10:29:41+00:00

Is there any recommended coding style how to write PowerShell scripts? It’s not about

  • 0

Is there any recommended coding style how to write PowerShell scripts?

It’s not about how to structure the code (how many functions, if to use module, …). It’s about ‘how to write the code so that it is readable‘.

In programming languages there are some recommended coding styles (what to indent, how to indent – spaces/tabs, where to make new line, where to put braces,…), but I haven’t seen any suggestion for PowerShell.

I’m interested particularly in:


How to write parameters

function New-XYZItem
  ( [string] $ItemName
  , [scriptblock] $definition
  ) { ...

(I see that it’s more like ‘V1’ syntax)

or

function New-PSClass  {
  param([string] $ClassName
       ,[scriptblock] $definition
  )...

or (why to add empty attribute?)

function New-PSClass  {
  param([Parameter()][string] $ClassName
       ,[Parameter()][scriptblock] $definition
  )...

or (other formatting I saw maybe in Jaykul’s code)

function New-PSClass {
  param(
        [Parameter()]
        [string]
        $ClassName
        ,
        [Parameter()]
        [scriptblock]
        $definition
  )...

or …?


How to write a complex pipeline

Get-SomeData -param1 abc -param2 xyz | % {
    $temp1 = $_
    1..100 | % {
      Process-somehow $temp1 $_
    }
  } | % {
    Process-Again $_
  } |
  Sort-Object -desc

or (name of cmdlet on new line)

Get-SomeData -param1 abc -param2 xyz |
  % {
    $temp1 = $_
    1..100 |
      % {
        Process-somehow $temp1 $_
      }
  } |
  % {
    Process-Again $_
  } |
  Sort-Object -desc |

And what if there are -begin, -process, and -end parameters? How do I make it the most readable?

Get-SomeData -param1 abc -param2 xyz |
  % -begin {
     init
  } -process {
     Process-somehow2 ...
  } -end {
     Process-somehow3 ...
  } |
  % -begin {
  } ....

or

Get-SomeData -param1 abc -param2 xyz |
  %  `
    -begin {
      init
    } `
    -process {
      Process-somehow2 ...
    } `
    -end {
      Process-somehow3 ...
    } |
  % -begin {
  } ....

The indentation is important here and what element is put on new line as well.


I have covered only questions that come on my mind very frequently. There are some others, but I’d like to keep this Stack Overflow question ‘short’.

Any other suggestions are welcome.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-13T10:29:41+00:00Added an answer on May 13, 2026 at 10:29 am

    After spending a couple of years diving pretty deep into PowerShell v2.0, here’s what I’ve settled on:

    <#
    .SYNOPSIS
    Cmdlet help is awesome.  Autogenerate via a template so I never forget.
    
    .DESCRIPTION
    .PARAMETER
    .PARAMETER
    .INPUTS
    .OUTPUTS
    .EXAMPLE
    .EXAMPLE
    .LINK
    #>
    function Get-Widget
    {
        [CmdletBinding()]
        param (
            # Think about which parameters users might loop over.  If there is a clear
            # favorite (80/20 rule), make it ValueFromPipeline and name it InputObject.
            [parameter(ValueFromPipeline=$True)]
            [alias("Server")]
            [string]$InputObject,
    
            # All other loop candidates are marked pipeline-able by property name.  Use Aliases to ensure the most 
            # common objects users want to feed in will "just work".
            [parameter(Mandatory=$true, Position=0, ValueFromPipelineByPropertyName=$True)]
            [alias("FullName")]
            [alias("Path")]
            [string[]]$Name,
    
            # Provide and document defaults for optional parameters whenever possible.
            [parameter(Position=1)]
            [int]$Minimum = 0,
    
            [parameter(Position=2)]
            [int]$ComputerName = "localhost",
    
            # Stick to standardized parameter names when possible.  *Especially* with switches.  Use Aliases to support 
            # domain-specific terminology and/or when you want to expose the parameter name of the .Net API you're wrapping.
            [parameter()]
            [Alias("IncludeFlibbles")]
            [switch]$All,
        )
    
        # The three main function blocks use this format if & only if they are short one-liners    
        begin { $buf = new-list string }
    
        # Otherwise they use spacing comparable to a C# method
        process    
        {
            # Likewise, control flow statements have a special style for one-liners
            try
            {
                # Side Note: internal variables (which may be inherited from a parent scope)  
                # are lowerCamelCase.  Direct parameters are UpperCamelCase.
                if ($All)
                    { $flibbles = $Name | Get-Flibble }   
                elseif ($Minimum -eq 0)          
                    { $flibbles = @() }
                else
                    { return }                       
    
                $path = $Name |
                    ? { $_.Length -gt $Minimum } |
                    % { $InputObject.InvokeGetAPI($_, $flibbles) } |
                    ConvertTo-FullPath
            }
            finally { Cleanup }
    
            # In general, though, control flow statements also stick to the C# style guidelines
            while($true)
            {
                Do-Something
                if ($true)
                {
                    try
                    {
                        Do-Something
                        Do-Something
                        $buf.Add("abc")
                    }
                    catch
                    {
                        Do-Something
                        Do-Something
                    }
                }            
            }    
        }    
    }
    
    <# 
    Pipelines are a form of control flow, of course, and in my opinion the most important.  Let's go 
    into more detail.
    
    I find my code looks more consistent when I use the pipeline to nudge all of PowerShell's supported 
    language constructs (within reason) toward an "infix" style, regardless of their legacy origin.  At the 
    same time, I get really strict about avoiding complexity within each line.  My style encourages a long,
    consistent "flow" of command-to-command-to-command, so we can ensure ample whitespace while remaining
    quite compact for a .NET language. 
    
    Note - from here on out I use aliases for the most common pipeline-aware cmdlets in my stable of 
    tools.  Quick extract from my "meta-script" module definition:
    sal ?? Invoke-Coalescing
    sal ?: Invoke-Ternary
    sal im Invoke-Method
    sal gpv Get-PropertyValue
    sal spv Set-PropertyValue
    sal tp Test-Path2
    sal so Select-Object2        
    sal eo Expand-Object        
    
    % and ? are your familiar friends.
    Anything else that begins with a ? is a pseudo-infix operator autogenerated from the Posh syntax reference.
    #>        
    function PipelineExamples
    {
        # Only the very simplest pipes get to be one-liners:
        $profileInfo = dir $profile | so @{Path="fullname"; KBs={$_.length/1kb}}
        $notNull = $someString | ?? ""        
        $type = $InputObject -is [Type] | ?: $InputObject $InputObject.GetType()        
        $ComObject | spv Enabled $true
        $foo | im PrivateAPI($param1, $param2)
        if ($path | tp -Unc)
            { Do-Something }
    
        # Any time the LHS is a collection (i.e. we're going to loop), the pipe character ends the line, even 
        # when the expression looks simple.
        $verySlowConcat = ""            
        $buf |
            % { $verySlowConcat += $_ }
        # Always put a comment on pipelines that have uncaptured output [destined for the caller's pipeline]
        $buf |
            ? { $_ -like "*a*" }
    
    
        # Multi-line blocks inside a pipeline:
        $orders |
            ? { 
                $_.SaleDate -gt $thisQuarter -and
                ($_ | Get-Customer | Test-Profitable) -and
                $_.TastesGreat -and
                $_.LessFilling
            } |
            so Widgets |        
            % {                
                if ($ReviewCompetition)
                {
                    $otherFirms |
                        Get-Factory |
                        Get-ManufactureHistory -Filter $_ |
                        so HistoryEntry.Items.Widgets                     
                }
                else
                {
                    $_
                }
            } |            
            Publish-WidgetReport -Format HTML
    
    
        # Mix COM, reflection, native commands, etc. seamlessly
        $flibble = Get-WmiObject SomethingReallyOpaque |
            spv AuthFlags 0xf -PassThru |
            im Put() -PassThru |
            gpv Flibbles |
            select -first 1
    
        # The coalescing operator is particularly well suited to this sort of thing
        $initializeMe = $OptionalParam |
            ?? $MandatoryParam.PropertyThatMightBeNullOrEmpty |
            ?? { pwd | Get-Something -Mode Expensive } |
            ?? { throw "Unable to determine your blahblah" }           
        $uncFolderPath = $someInput |
            Convert-Path -ea 0 |
            ?? $fallback { tp -Unc -Folder }
    
        # String manipulation        
        $myName = "First{0}   Last{1}   " |
            ?+ "Suffix{2}" |
            ?replace "{", ": {" |
            ?f {eo richard berg jr | im ToUpper}            
    
        # Math algorithms written in this style start to approach the elegance of functional languages
        $weightedAvg = $values |
            Linq-Zip $weights {$args[0] * $args[1]} |
            Linq-Sum |
            ?/ ($weights | Linq-Sum)
    }
    
    # Don't be afraid to define helper functions.  Thanks to the script:Name syntax, you don't have to cram them into 
    # the begin{} block or anything like that.  Name, parameters, etc don't always need to follow the cmdlet guidelines.
    # Note that variables from outer scopes are automatically available.  (even if we're in another file!)
    function script:Cleanup { $buf.Clear() }
    
    # In these small helpers where the logic is straightforward and the correct behavior well known, I occasionally 
    # condense the indentation to something in between the "one liner" and "Microsoft C# guideline" styles
    filter script:FixComputerName
    {
        if ($ComputerName -and $_) {            
            # Handle UNC paths 
            if ($_[1] -eq "\") {   
                $uncHost = ($_ -split "\\")[2]
                $_.Replace($uncHost, $ComputerName)
            } else {
                $drive = $_[0]
                $pathUnderDrive = $_.Remove(0,3)            
                "\\$ComputerName\$drive`$\$pathUnderDrive"
            }
        } else {
            $_
        }
    }
    

    Stack Overflow’s syntax highlighter is giving up on me completely. Paste it into the ISE.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Is there any recommended way with WPF to create a common window style to
Are there any recommended libraries, patterns or examples on how to implement Prefetching and/or
Is there any recommended Java application profiling tutorial? I am now using JProfiler and
Are there any wiki syntax like rdoc, markdown, ... recommended in the ruby world?
I guess my questions are not well described. Is this coding style (like the
Is there any recommended way to call a Set.union if I know one of
Beyond the official documentation, are there any recommended resources for learning to build jQuery
Are there any free Mac OSX IDEs for SQLite that you would recommend? I've
Is there any functional difference in Python between a try statement and an if
Is there any way in Notepad++ (or even with another tool) to change the

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.