### Comprehensive PowerShell Comment-Based Help Structure Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Documentation-and-Comments.md This example illustrates the full structure of comment-based help in PowerShell, detailing all standard sections such as `SYNOPSIS`, `DESCRIPTION`, `PARAMETER`, `INPUTS`, `OUTPUTS`, `EXAMPLE`, `LINK`, and `NOTES`. It emphasizes the importance of detailed documentation for each element. ```PowerShell function Get-Example { <# .SYNOPSIS A brief description of the function or script. .DESCRIPTION A longer description. .PARAMETER FirstParameter Description of each of the parameters. Note:        To make it easier to keep the comments synchronized with changes to the parameters, the preferred location for parameter documentation comments is not here, but within the param block, directly above each parameter. .PARAMETER SecondParameter Description of each of the parameters. .INPUTS Description of objects that can be piped to the script. .OUTPUTS Description of objects that are output by the script. .EXAMPLE Example of how to run the script. .LINK Links to further documentation. .NOTES Detail on what the script does, if this is needed. #> ``` -------------------------------- ### PowerShell: Using Single-Line and Multi-Line Block Comments Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Documentation-and-Comments.md This example demonstrates two forms of block comments in PowerShell: multiple single-line comments starting with '#' and the multi-line <# ... #> syntax. It advises using the multi-line syntax for extensive documentation, like help text for functions. ```PowerShell # Requiring a space makes things legible and prevents confusion. # Writing comments one-per line makes them stand out more in the console. <# .SYNOPSIS Really long comment blocks are tedious to keep commented in single-line mode. .DESCRIPTION Particularly when the comment must be frequently edited, as with the help and documentation for a function or script. #> ``` -------------------------------- ### Implementing SupportsShouldProcess and ShouldContinue in PowerShell Cmdlets Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/TODO.md This PowerShell cmdlet example demonstrates the use of `SupportsShouldProcess` for `-WhatIf` and `-Confirm` parameters, and `ShouldContinue` for an additional confirmation prompt, which can be bypassed with the `-Force` switch. The code iterates through files, prompting the user before performing a simulated removal, showcasing best practices for interactive and safe cmdlet design. ```powershell [CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = "Medium")] param([Switch]$Force) $RejectAll = $false $ConfirmAll = $false foreach ($file in ls) { if($PSCmdlet.ShouldProcess("Removed the file '$($file.Name)'", "Remove the file '$($file.Name)'?", "Removing Files") ) { if ($Force -Or $PSCmdlet.ShouldContinue("Are you REALLY sure you want to remove '$($file.Name)'?", "Removing '$($file.Name)'", [ref]$ConfirmAll, [ref]$RejectAll)) { "Removing $File" } } } ``` -------------------------------- ### PowerShell Function with Basic Comment-Based Help Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Documentation-and-Comments.md This snippet provides an example of a PowerShell function `Test-Help` that includes a basic comment-based help block with `SYNOPSIS` and `EXAMPLE` sections. It also demonstrates the definition of a mandatory parameter with an alias. ```PowerShell function Test-Help { <# .SYNOPSIS An example function to display how help should be written. .EXAMPLE Get-Help -Name Test-Help This shows the help for the example function. #> [CmdletBinding()] param ( # This parameter doesn't do anything. # Aliases: MP [Parameter(Mandatory = $true)] [Alias("MP")] [String]$MandatoryParameter ) <# code here ... #> } ``` -------------------------------- ### Basic PowerShell CmdletBinding Structure Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/TODO.md This snippet illustrates the fundamental structure for PowerShell scripts and functions that leverage `CmdletBinding`. It includes the `param`, `process`, and `end` blocks, which are crucial for handling pipeline input and adhering to PowerShell's cmdlet design patterns. Adopting this structure from the start is recommended for all scripts. ```PowerShell [CmdletBinding()] param() process{} end{} ``` -------------------------------- ### Basic PowerShell Script Structure with CmdletBinding Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Code-Layout-and-Formatting.md This snippet illustrates the recommended starting structure for all PowerShell scripts and functions, including `[CmdletBinding()]`, `param ()`, `process {}`, and `end {}` blocks. Using `CmdletBinding` is crucial for advanced function features, and this explicit structure enhances clarity and maintainability. ```powershell [CmdletBinding()] param () process { } end { } ``` -------------------------------- ### PowerShell: Documenting Parameters within the param Block Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Documentation-and-Comments.md This example shows the recommended practice of documenting function parameters directly within the `param` block using comment-based help. This placement helps ensure that parameter documentation stays synchronized with code changes and is easily accessible. ```PowerShell param ( # Param1 help description [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 0)] $Param1, # Param2 help description [int] $Param2 ) ``` -------------------------------- ### Defining a Mandatory PowerShell Parameter with HelpText and Aliases Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/TODO.md This example demonstrates how to define a mandatory parameter in PowerShell, incorporating attributes like `Position`, `ValueFromPipeline`, `ValueFromPipelineByPropertyName`, and `Alias`. Crucially, it shows the use of `HelpText`, which provides immediate context to users when prompted for the parameter, enhancing usability and reducing the need to consult full documentation. ```PowerShell [Parameter(Position = 1, Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpText = 'The name of the file to read')] [Alias('PSPath','FullName','Path')] [String]$File ``` -------------------------------- ### PowerShell Function Supporting WhatIf and Confirm Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Writing-Parameter-Blocks.md This example demonstrates how to implement `SupportsShouldProcess` in a PowerShell function's `CmdletBinding` to enable `-WhatIf` and `-Confirm` functionality. It shows the use of `$PSCmdlet.ShouldProcess` for actions and `$PSCmdlet.ShouldContinue` for conditional prompts, including handling the `-Force` parameter and the 'All' options for confirmation. ```PowerShell # NOTE: ConfirmImpact defaults to Medium # But I recommend setting ConfirmImpact explicitly as a reminder :) [CmdletBinding(SupportsShouldProcess, ConfirmImpact = "Medium")] param([switch]$Force) # You need to pre-define these (because they're passed by [ref]) $RejectAll = $false $ConfirmAll = $false # Note: please don't actually do this with services, restarting them in non-dependency order would be a nightmare... foreach ($service in Get-Service | Where Status -eq "Running") { # This will normally automatically be TRUE. It will only query if the user: # 1. Has their $ConfirmPreference (default High) set LOWER than or equal to the ConfirmImpact in the cmdlet binding (default Medium) # 2. Passes -Confirm, which sets the $ConfirmPreference in the function's scope to Low if ($PSCmdlet.ShouldProcess( "Restarted the service '$($service.Name)'", "Restart the '$($service.DisplayName)' service ($($service.Name))?", "Restarting Services" )) { # If you use ShouldContinue, have a -Force parameter that bypasses it # And if you know there may be multiple prompts, you should use this overload that supports the Confirm/Reject "All" option # In this example, we're only prompting when there are dependent services, and otherwise restart without additional prompting if ($Force -Or $service.DependentServices.Count -eq 0 -or $PSCmdlet.ShouldContinue( "$($service.Name) has $($service.DependentServices.Count) dependent services. Are you sure?", "Restarting the '$($service.DisplayName)' service", [ref]$ConfirmAll, [ref]$RejectAll)) { "(Not actually) restarting $($service.DisplayName)" } } } ``` -------------------------------- ### PowerShell Enum and Function with Conditional Logic Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Code-Layout-and-Formatting.md This example illustrates the definition of an enum in PowerShell and a function demonstrating the 'One True Brace Style'. The Test-Code function includes a conditional if-else statement, showcasing the recommended brace placement. ```PowerShell enum Color { Black, White } function Test-Code { [CmdletBinding()] param ( [int]$ParameterOne ) end { if (10 -gt $ParameterOne) { "Greater" } else { "Lesser" } } } ``` -------------------------------- ### Comparing PowerShell foreach loop and ForEach-Object cmdlet performance Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Performance.md This example demonstrates two common ways to iterate over results in PowerShell: using the 'foreach' language construct and piping to the 'ForEach-Object' cmdlet. It highlights the need to measure performance, as the 'foreach' construct is generally faster in this specific scenario. Performance should be tested on the target hardware and PowerShell version. ```PowerShell foreach ($result in Do-Something) { $result.PropertyOne + $result.PropertyTwo } Do-Something | ForEach-Object { $_.PropertyOne + $_.PropertyTwo } ``` -------------------------------- ### Correctly Returning Objects in Advanced PowerShell Functions Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Function-Structure.md This example illustrates the correct way to return objects in Advanced PowerShell Functions, contrasting a 'bad' practice that uses 'return' in the 'end' block with a 'good' practice that implicitly returns objects from the 'process' block. It highlights the importance of pipeline compatibility and proper object flow. ```PowerShell # Bad function Get-USCitizenCapability { [CmdletBinding()] [OutputType([psobject])] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 0)] [int16] $Age ) process { $Capabilities = @{ MilitaryService = $false DrinkAlcohol = $false Vote = $false } if ($Age -ge 18) { $Capabilities['MilitaryService'] = $true $Capabilities['Vote'] = $true } $Obj = New-Object -Property $Capabilities -TypeName psobject } end { return $Obj } } # Good function Get-USCitizenCapability { [CmdletBinding()] [OutputType([psobject])] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 0)] [int16] $Age ) process { $Capabilities = @{ MilitaryService = $false DrinkAlcohol = $false Vote = $false } if ($Age -ge 18) { $Capabilities['MilitaryService'] = $true $Capabilities['Vote'] = $true } New-Object -Property $Capabilities -TypeName psobject } } ``` -------------------------------- ### PowerShell Function Indentation with Four Spaces Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Code-Layout-and-Formatting.md This example demonstrates the recommended four-space indentation level for PowerShell code within functions and control structures. Consistent indentation improves code readability and is a common standard across many programming languages and editors. ```powershell function Test-Code { foreach ($exponent in 1..10) { [Math]::Pow(2, $exponent) } } ``` -------------------------------- ### Assigning Multiple Return Values from Internal PowerShell Function Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Output-and-Formatting.md This example demonstrates how to capture multiple return values from an internal PowerShell function into separate variables. This approach is acceptable for internal functions as their output is not directly exposed to the user/host, allowing for performance optimizations like reducing database calls. ```PowerShell $user, $group, $org = Get-UserGroupOrg ``` -------------------------------- ### PowerShell: Correct Spacing for Unary Operators Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Code-Layout-and-Formatting.md This example demonstrates the correct spacing for unary operators in PowerShell. It shows that unary operators like increment (++) or negation (-) should not have a space between the operator and the operand, contrasting with incorrect spacing that can reduce readability. ```powershell # Do not write: $yesterdaysDate = (Get-Date).AddDays( - 1) $i = 0 $i ++ # Instead write: $yesterdaysDate = (Get-Date).AddDays(-1) $i = 0 $i++ # Same principle should be applied when using a variable. $yesterdaysDate = (Get-Date).AddDays(-$i) ``` -------------------------------- ### PowerShell Path Handling: Avoid Tilde (~) for Home Folder Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/CONTRIBUTING.md This guideline advises against using the tilde character (`~`) to represent the home folder in PowerShell scripts due to its unreliable behavior, which depends on the current provider. It recommends using more robust and consistent alternatives like `${Env:UserProfile}` or `(Get-PSProvider FileSystem).Home` for reliable path resolution across different environments. ```PowerShell Avoid the use of `~` to represent the home folder. The meaning of ~ is unfortunately dependent on the "current" provider at the time of execution. This isn't really a style issue, but it's an important rule for code you intend to share anyway. Instead, use `${Env:UserProfile}` or `(Get-PSProvider FileSystem).Home` ``` -------------------------------- ### Using DefaultParameterSetName in PowerShell CmdletBinding Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Function-Structure.md This example illustrates how to use the 'DefaultParameterSetName' attribute within 'CmdletBinding' when a function utilizes parameter sets. It defines a 'Get-User' function with two parameter sets ('ID' and 'Name') and specifies 'ID' as the default, ensuring a fallback when no parameter set is explicitly chosen. ```PowerShell function Get-User { [CmdletBinding(DefaultParameterSetName = "ID")] [OutputType("System.Int32", ParameterSetName = "ID")] [OutputType([String], ParameterSetName = "Name")] param ( [parameter(Mandatory = $true, ParameterSetName = "ID")] [Int[]] $UserID, [parameter(Mandatory = $true, ParameterSetName = "Name")] [String[]] $UserName ) <# function body #> } ``` -------------------------------- ### Avoid null variable checks for PowerShell error conditions Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Error-Handling.md Shows an example of checking for a null variable as an error condition, which is generally discouraged. While sometimes necessary for non-terminating errors, it can complicate debugging and is less explicit than using try/catch with terminating exceptions. ```PowerShell $user = Get-ADUser -Identity DonJ if ($user) { $user | Do-Something } else { Write-Warning "Could not get user $user" } ``` -------------------------------- ### Declaring Lowest Supported PowerShell Version in Script Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Language-Interop-and-.NET.md Provides an example of using the #Requires -Version statement to explicitly declare the lowest PowerShell version a script supports. This is crucial in environments with multiple PowerShell versions to ensure the script's compatibility and prevent execution errors. ```PowerShell #Requires -Version 2.0 ``` -------------------------------- ### PowerShell: Using String Concatenation for Long Messages Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Code-Layout-and-Formatting.md This example demonstrates how to handle long string messages in PowerShell by using string concatenation across multiple lines. This approach avoids explicit line continuation characters (like backticks) and improves readability while ensuring the output remains a single long line. ```powershell Write-Host -Object ("This is an incredibly important, and extremely long message. " + "We cannot afford to leave any part of it out, " + "nor do we want line-breaks in the output. " + "Using string concatenation lets us use short lines here, " + "and still get a long line in the output") ``` -------------------------------- ### Securely Saving and Importing PSCredential Objects to Disk Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Security.md This example demonstrates how to persist PSCredential objects securely to disk using Export-CliXml and later import them with Import-CliXml. The password within the credential object is protected as a SecureString and can only be accessed by the same user on the same computer where it was originally generated, providing a secure storage mechanism. ```PowerShell # Save a credential to disk Get-Credential | Export-CliXml -Path c:\creds\credential.xml # Import the previously saved credential $Credential = Import-CliXml -Path c:\creds\credential.xml ``` -------------------------------- ### Encrypting and Decrypting Sensitive Strings with DPAPI in PowerShell Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Security.md This snippet shows how to encrypt and decrypt sensitive strings for disk storage using ConvertFrom-SecureString and ConvertTo-SecureString. These cmdlets leverage the Windows Data Protection API (DPAPI), meaning the encrypted data can only be decrypted by the same user on the same machine. The example also notes the option to use AES with a shared key for broader accessibility. ```PowerShell # Prompt for a Secure String (in automation, just accept it as a parameter) $Secure = Read-Host -Prompt "Enter the Secure String" -AsSecureString # Encrypt to Standard String and store on disk ConvertFrom-SecureString -SecureString $Secure | Out-File -Path "${Env:AppData}\Sec.bin" # Read the Standard String from disk and convert to a SecureString $Secure = Get-Content -Path "${Env:AppData}\Sec.bin" | ConvertTo-SecureString ``` -------------------------------- ### PowerShell Utility Function for Throwing Terminating Errors Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/TODO.md This utility function, `ThrowError`, provides a structured approach to throwing terminating errors in PowerShell using `PSCmdlet.ThrowTerminatingError`. It encapsulates the creation of a comprehensive `ErrorRecord`, allowing for consistent and detailed error reporting. This method is preferred over a simple `throw` statement for better error handling and debugging capabilities. ```PowerShell # Utility to throw an error record function ThrowError { param( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.Management.Automation.PSCmdlet] $CallerPSCmdlet, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] $ExceptionName, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] $ExceptionMessage, [System.Object] $ExceptionObject, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] $ErrorId, [Parameter(Mandatory = $true)] [ValidateNotNull()] [System.Management.Automation.ErrorCategory] $ErrorCategory ) $exception = New-Object -TypeName $ExceptionName -ArgumentList $ExceptionMessage $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $ErrorId, $ErrorCategory, $ExceptionObject $CallerPSCmdlet.ThrowTerminatingError($errorRecord) } ``` -------------------------------- ### Temporarily Decrypting PSCredential Password for .NET API Calls Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Security.md When interacting with .NET APIs or third-party libraries that require a plain string password, this example shows how to temporarily decrypt the password from a PSCredential object. It emphasizes passing the decrypted password directly to the method call without storing it in an intermediate variable to minimize exposure. ```PowerShell # Get the cleartext password for a method call: $Insecure.SetPassword($Credentials.GetNetworkCredential().Password) ``` -------------------------------- ### PowerShell Function with Comment-Based Help and Parameter Documentation Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Writing-Parameter-Blocks.md This snippet illustrates the recommended structure for a PowerShell function, incorporating comment-based help with .SYNOPSIS and .EXAMPLE sections. It also shows how to document individual parameters directly above their definitions within the `param` block, ensuring clarity and maintainability. ```PowerShell function Test-Help { <# .SYNOPSIS An example function to display how help should be written. .EXAMPLE Test-Help -Name Test-Help This tests the help for the Test-Help function. #> [CmdletBinding()] param ( # This parameter doesn't do anything, but you must provide a value # Aliases: MP [Parameter(Mandatory = $true)] [Alias("MP")] [String]$MandatoryParameter ) <# code here ... #> } ``` -------------------------------- ### PowerShell Function Definition with Comment-Based Help Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Code-Layout-and-Formatting.md This snippet demonstrates the structure of a PowerShell function, including CmdletBinding and parameter definitions. It also showcases the use of comment-based help (.SYNOPSIS, .DESCRIPTION) for documenting the function's purpose and parameters. ```PowerShell function Write-Host { <# .SYNOPSIS Writes customized output to a host. .DESCRIPTION The Write-Host cmdlet customizes output. You can specify the color of text by using the ForegroundColor parameter, and you can specify the background color by using the BackgroundColor parameter. The Separator parameter lets you specify a string to use to separate displayed objects. The particular result depends on the program that is hosting Windows PowerShell. #> [CmdletBinding()] param( [Parameter(Position = 0, ValueFromPipeline = $true, ValueFromRemainingArguments = $true)] [psobject]$Object, [switch]$NoNewline, [psobject]$Separator, [System.ConsoleColor]$ForegroundColor, [System.ConsoleColor]$BackgroundColor ) begin { ... ``` -------------------------------- ### PowerShell: Conceptual Wrapper Commands for .NET File Operations Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Performance.md This snippet illustrates a conceptual native PowerShell wrapper approach, where fictional commands like `Open-TextFile`, `Test-TextFile`, and `Read-TextFile` encapsulate underlying .NET Framework functionality. This method aims to combine the performance benefits of .NET with the aesthetic and readability advantages of native PowerShell commands. ```PowerShell $handle = Open-TextFile -Path file.txt while (-not (Test-TextFile -Handle $handle)) { Do-Something -Input (Read-TextFile -Handle $handle) } ``` -------------------------------- ### PowerShell: Accepting Pipeline Input by Property Name with Aliases Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Writing-Parameter-Blocks.md Explains how to enhance command flexibility by accepting parameters from the pipeline by property name using ValueFromPipelineByPropertyName. Also demonstrates adding aliases with [Alias()] to improve object matching. Reminds that pipeline values are processed in the 'process' block. ```PowerShell function Set-ConfigurationItem { param( [Parameter(ValueFromPipelineByPropertyName=$true)] [Alias('ConfigName', 'ItemName')] [string]$Name, [Parameter(ValueFromPipelineByPropertyName=$true)] [int]$Value ) process { Write-Host "Setting configuration item '$Name' to value '$Value'." } } # Example usage (conceptual): # @{ConfigName='LogLevel'; Value=3} | Set-ConfigurationItem # Get-Service | Set-ConfigurationItem -Name {$_.DisplayName} -Value {$_.Status.value__} ``` -------------------------------- ### Faster PowerShell v3 Service Filtering Syntax Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Language-Interop-and-.NET.md Illustrates a more efficient and modern syntax for filtering running services in PowerShell v3. This simplified syntax, using Where directly, offers significant performance improvements over older methods by being processed more efficiently under the hood. ```PowerShell Get-Service | Where Status -eq Running ``` -------------------------------- ### PowerShell: Explaining Reasoning in Line Comments Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Documentation-and-Comments.md This snippet contrasts ineffective comments that state the obvious with effective comments that explain the reasoning behind a code change. It highlights the importance of keeping comments up-to-date and focusing on 'why' rather than 'what'. ```PowerShell # Do not write: # Increment Margin by 2 $Margin = $Margin + 2 # Maybe write: # The rendering box obscures a couple of pixels. $Margin = $Margin + 2 ``` -------------------------------- ### PowerShell: Applying Inline Comments for Clarity Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Documentation-and-Comments.md This snippet illustrates the effective use of inline comments on the same line as code statements, particularly for short lines within a hashtable. It emphasizes separating comments from code by at least two spaces and aligning them for readability. ```PowerShell $Options = @{ Margin = 2 # The rendering box obscures a couple of pixels. Padding = 2 # We need space between the border and the text. FontSize = 24 # Keep this above 16 so it's readable in presentations. } ``` -------------------------------- ### PowerShell: Accepting Credentials with [PSCredential] Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Writing-Parameter-Blocks.md Illustrates the use of [System.Management.Automation.PSCredential] for securely accepting user credentials. PowerShell provides special support for this type, automatically prompting for passwords when a username is provided. ```PowerShell function Connect-MyService { param( [System.Management.Automation.PSCredential]$Credential ) Write-Host "Connecting with user: $($Credential.UserName)" # Example usage: Connect-MyService -Credential Jaykul (prompts for password) } ``` -------------------------------- ### PowerShell: Strongly Typing Parameters for Validation Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Writing-Parameter-Blocks.md Demonstrates the general concept of strong typing parameters in PowerShell to improve input validation, provide clear hints to users, and ensure early failure detection. This practice helps prevent issues like code injection. ```PowerShell function Get-ExampleData { param( [string]$Name, [int]$Id, [datetime]$StartDate ) # ... function logic ... } ``` -------------------------------- ### Declare Simple PowerShell Functions Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Function-Structure.md This snippet demonstrates the recommended style for declaring simple PowerShell functions, emphasizing a space between the function name and its parameters. It shows a basic function signature with two parameters. ```PowerShell function MyFunction ($param1, $param2) { ... } ``` -------------------------------- ### Specifying PowerShell Version in Module Manifest Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Language-Interop-and-.NET.md Demonstrates how to specify the minimum required PowerShell version for a module within its manifest (.psd1) file. This ensures that any module-specific cmdlets or syntax that are only present on a certain minimum version of PowerShell are supported when the module is loaded. ```PowerShell PowerShellVersion = '3.0' ``` -------------------------------- ### PowerShell If Statement Brace Styles Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Readability.md Illustrates two common brace placement styles for PowerShell `if` statements. Both styles are functionally equivalent, and the choice between them is often a matter of personal or team preference, with no functional difference in parsing. ```PowerShell if ($this -gt $that) { Do-Something -with $that } ``` ```PowerShell if ($this -gt $that) { Do-Something -with $that } ``` -------------------------------- ### Using PowerShell's Built-in Test-Connection Cmdlet Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Building-Reusable-Tools.md This snippet illustrates the preferred method for checking network connectivity in PowerShell v2 and later, using the `Test-Connection` cmdlet with the `-Quiet` parameter. It achieves the same result as a custom ping function with significantly less code and adheres to PowerShell best practices. ```PowerShell Test-Connection $computername -Quiet ``` -------------------------------- ### PowerShell: Reading File Content with Get-Content and Foreach Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Performance.md This snippet demonstrates a native PowerShell approach to reading a file, where `Get-Content` loads the entire file into memory before processing each line with a `foreach` loop. While aesthetically pleasing and easy to expand, this method can lead to poor performance and high memory consumption for large files. ```PowerShell $content = Get-Content -Path file.txt foreach ($line in $content) { Do-Something -Input $line } ``` -------------------------------- ### PowerShell: Implementing Switch Parameters Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Writing-Parameter-Blocks.md Details the characteristics and best practices for [switch] parameters. Switch parameters are boolean by nature, default to false, and should be used to enable less common or more complex command modes. Shows how to pass switch values to other commands. ```PowerShell function Invoke-MyAction { param( [switch]$Force, [switch]$Verbose ) if ($Force) { Write-Host "Forcing action..." -ForegroundColor Red } if ($Verbose) { Write-Host "Verbose output enabled." } # Example of passing a switch value to another command: # Invoke-AnotherCommand -TheirSwitch:$Force } ``` -------------------------------- ### Use Full Command Names in PowerShell Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Naming-Conventions.md Prefer using full Verb-Noun command names instead of aliases for better readability, universal understanding across different user backgrounds (e.g., Linux vs. DOS users), and proper syntax highlighting in tools like GitHub. ```PowerShell # Do not write: gps -Name Explorer # Instead write: Get-Process -Name Explorer ``` -------------------------------- ### PowerShell: Correct Spacing for Parameters and Operators Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Code-Layout-and-Formatting.md This snippet illustrates the preferred spacing conventions around parameters and operators in PowerShell. It contrasts incorrect spacing (e.g., $variable=Get-Content) with the recommended practice of using single spaces for improved readability, especially when dealing with switch parameters and arithmetic operations. ```powershell # Do not write: $variable=Get-Content $FilePath -Wait:($ReadCount-gt0) -First($ReadCount*5) # Instead write: $variable = Get-Content -Path $FilePath -Wait:($ReadCount -gt 0) -TotalCount ($ReadCount * 5) ``` -------------------------------- ### PowerShell Brace Placement for Script Blocks Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Code-Layout-and-Formatting.md This snippet demonstrates the recommended brace placement style for PowerShell script blocks, where the opening brace is on the same line as the statement. This style ensures consistency, especially with cmdlets like `Where-Object` and `ForEach-Object`, and prevents accidental code breakage when inserting new lines. ```powershell Get-ChildItem | Where-Object { $_.Length -gt 10mb } ``` -------------------------------- ### Custom PowerShell Function for Pinging a Computer Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Building-Reusable-Tools.md This PowerShell function, `Ping-Computer`, demonstrates a custom implementation for checking a computer's ping status using `Get-WmiObject`. While functional, it highlights opportunities for enhancement, such as using advanced functions and approved verbs, and is generally less preferred than built-in cmdlets. ```PowerShell function Ping-Computer ($computername) { $ping = Get-WmiObject Win32_PingStatus -filter "Address='$computername'" if ($ping.StatusCode -eq 0) { return $true } else { return $false } } ``` -------------------------------- ### PowerShell: Cautions with [string] and [object] Parameter Types Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Writing-Parameter-Blocks.md Explains the potential issues when using [string] or [object] for parameters intended to differentiate parameter sets or accept ValueFromPipeline, due to PowerShell's aggressive type coercion. Recommends using ValidateScript when these types are necessary for accepting multiple object types. ```PowerShell function Process-Item { param( # Avoid [string] or [object] for parameter set differentiation # unless combined with ValidateScript for specific types. [Parameter(ParameterSetName='StringInput')] [string]$InputString, [Parameter(ParameterSetName='ObjectInput')] [object]$InputObject ) # When accepting multiple types, use ValidateScript: # [object]$MyParameter = [ValidateScript({ $_ -is [string] -or $_ -is [int] })]$Value } ``` -------------------------------- ### PowerShell: Reading File Line by Line using .NET StreamReader Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Performance.md This snippet demonstrates a lower-level .NET Framework approach using `System.IO.StreamReader` to read a file one line at a time, significantly improving performance and memory efficiency for large files. While solving performance issues, it sacrifices some native PowerShell readability for a more C#-like syntax. ```PowerShell $sr = New-Object -TypeName System.IO.StreamReader -ArgumentList file.txt while ($sr.Peek() -ge 0) { $line = $sr.ReadLine() Do-Something -Input $line } ``` -------------------------------- ### Use Full Parameter Names in PowerShell Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Naming-Conventions.md Always use explicit, full parameter names for clarity. This helps readers unfamiliar with a command understand its usage and prevents potential bugs if command parameter sets change in the future. ```PowerShell # Do not write: Get-Process Explorer # Instead write: Get-Process -Name Explorer ``` -------------------------------- ### Accepting PSCredential Parameters in PowerShell Functions Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Security.md This snippet demonstrates the recommended way to accept credentials in PowerShell functions by using the PSCredential type and the Credential() attribute. This approach ensures that sensitive password information is handled securely as a SecureString and allows for secure prompting if only a username is provided, preventing exposure in history or to screen scrapers. ```PowerShell param ( [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credentials ) ``` -------------------------------- ### Encapsulate PowerShell transactions in Try-Catch blocks Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Error-Handling.md Illustrates the recommended approach for error handling by placing the entire logical 'transaction' within a try block. This improves readability and simplifies error management by centralizing the catch logic. ```PowerShell try { Do-Something -ErrorAction Stop Do-This Set-That Get-Those } catch { Handle-Error } ``` -------------------------------- ### PowerShell: Spacing for Subexpressions and Scriptblocks Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Code-Layout-and-Formatting.md This snippet illustrates the recommended spacing for subexpressions ($()) and scriptblocks ({}) in PowerShell. It emphasizes using a single space inside the braces or parentheses to enhance readability and distinguish them from variable delimiter braces (${}). ```powershell $Var = 1 "This is a string with one (${Var}) delimited variable." "There are $( (Get-ChildItem).Count ) files." ``` -------------------------------- ### PowerShell Line Continuation: Backticks vs. Splatting Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Readability.md Compares the use of backticks (`) for line continuation with the recommended splatting technique. While backticks can break lines, they are prone to errors and reduce readability. Splatting provides a cleaner, more robust method for managing multi-line commands, improving code clarity and maintainability. ```PowerShell Get-WmiObject -Class Win32_LogicalDisk ` `-Filter "DriveType=3" ` `-ComputerName SERVER2 ``` ```PowerShell $GetWmiObjectParams = @{ Class = "Win32_LogicalDisk" Filter = "DriveType=3" ComputerName = "SERVER2" } Get-WmiObject @GetWmiObjectParams ``` -------------------------------- ### Slower PowerShell v3 Service Filtering Syntax Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Language-Interop-and-.NET.md Demonstrates an older, less performant syntax for filtering running services in PowerShell v3. This method, using Where-Object with a FilterScript block, processes significantly slower due to underlying mechanisms compared to newer syntax. ```PowerShell Get-Service | Where-Object -FilterScript { $_.Status -eq 'Running' } ``` -------------------------------- ### PowerShell Indentation for Wrapped Lines and Parameters Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Code-Layout-and-Formatting.md This snippet illustrates flexible indentation for continuation lines in PowerShell, where more than four spaces can be used to align wrapped code, such as method calls or parameters. This practice enhances readability for long lines without breaking the overall four-space indentation standard. ```powershell function Test-Code { foreach ($base in 1,2,4,8,16) { foreach ($exponent in 1..10) { [System.Math]::Pow($base, $exponent) } } } ``` -------------------------------- ### Avoid Using Tilde (~) for Home Folder in PowerShell Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Naming-Conventions.md The meaning of `~` is dependent on the current PowerShell provider, leading to inconsistent behavior. For reliable home folder access, use `${Env:UserProfile}` or `(Get-PSProvider -PSProvider FileSystem).Home` instead. ```PowerShell PS C:\Windows\system32> cd ~ PS C:\Users\Name> cd HKCU:\Software PS HKCU:\Software> cd ~ cd : Home location for this provider is not set. To set the home location, call "(Get-PSProvider 'Registry').Home = 'path'". At line:1 char:1 + cd ~ + ~~~~ + CategoryInfo : InvalidOperation: (:) [Set-Location], PSInvalidOperationException + FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.SetLocationCommand ``` -------------------------------- ### PowerShell Indentation for Control Flow Constructs Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Readability.md Demonstrates the conventional practice of indenting code within control flow constructs like `foreach` loops. Proper indentation significantly enhances code readability by clearly indicating which statements belong to a specific construct, making the code structure easier to follow. ```PowerShell foreach ($computer in $computers) { Do-This Get-Those } ``` -------------------------------- ### PowerShell: Streaming File Content with Pipeline and ForEach-Object Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Performance.md This snippet utilizes the PowerShell pipeline to stream file content line by line using `Get-Content` and `ForEach-Object`. This approach is more memory-efficient for large files as it avoids loading the entire file into memory, though some in the community might find its aesthetics less appealing. ```PowerShell Get-Content -Path file.txt | ForEach-Object -Process { Do-Something -Input $_ } ``` -------------------------------- ### Converting SecureString to Plaintext in PowerShell Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Security.md This code illustrates how to convert a SecureString object back into a plain string. It uses System.Runtime.InteropServices.Marshal methods and is crucial to call ZeroFreeBSTR after use to properly free the memory and prevent potential memory leaks, ensuring sensitive data is not left exposed. ```PowerShell # Decrypt a secure string. $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($this) $plaintext = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) [System.Runtime.InteropServices.Marshal]::ZeroFreeBSTR($BSTR) $plaintext ``` -------------------------------- ### Avoid using flags for PowerShell error handling Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Error-Handling.md Demonstrates an anti-pattern where a boolean flag is used to control flow after a try/catch block. This approach makes the logic harder to follow and less robust than encapsulating the entire transaction within the try block. ```PowerShell try { $continue = $true Do-Something -ErrorAction Stop } catch { $continue = $false } if ($continue) { Do-This Set-That Get-Those } ``` -------------------------------- ### Specifying Minimum PowerShell Version with #requires Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Best-Practices/Language-Interop-and-.NET.md Shows how to use the #requires -version statement at the top of a PowerShell script. This statement prevents the script from running on incompatible, older versions of PowerShell, ensuring that the script's features and syntax are supported. ```PowerShell #requires -version 3.0 ``` -------------------------------- ### Declare Multi-line Hashtable in PowerShell Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Code-Layout-and-Formatting.md This snippet demonstrates the preferred method for declaring a PowerShell hashtable that spans multiple lines. This style enhances readability for complex configurations by aligning key-value pairs, making it easier to manage and understand. ```PowerShell $Options = @{ Margin = 2 Padding = 2 FontSize = 24 } ``` -------------------------------- ### Specify OutputType Attribute for PowerShell Functions Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Function-Structure.md This snippet demonstrates the syntax for using the 'OutputType' attribute in PowerShell, which specifies the type of object(s) a function returns. It shows how to define output types using both type literals and string names, optionally associating them with specific parameter sets. ```PowerShell [OutputType([], ParameterSetName = "")] [OutputType("", ParameterSetName = "")] ``` -------------------------------- ### Use Full, Explicit Paths in PowerShell Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Naming-Conventions.md Avoid using relative paths (`.` or `..`) in scripts, especially when interacting with .NET methods or native applications, as `[Environment]::CurrentDirectory` does not automatically update with PowerShell's `$PWD`. Instead, base paths off `$PSScriptRoot` and use `Join-Path` or string concatenation for robust and predictable path resolution. ```PowerShell # Do not write: Get-Content .\README.md # Especially do not write: [System.IO.File]::ReadAllText(".\README.md") # Although you can write: Push-Location $PSScriptRoot Get-Content README.md # It would be better to write: Get-Content -Path (Join-Path -Path $PSScriptRoot -ChildPath README.md) # Or to use string concatenation: Get-Content "$PSScriptRoot\README.md" # For calling .NET methods, pass full paths: [System.IO.File]::ReadAllText("$PSScriptRoot\README.md") # Optionally by calling Convert-Path Push-Location $PSScriptRoot [System.IO.File]::ReadAllText((Convert-Path README.md)) ``` -------------------------------- ### Allow Empty String for Mandatory PowerShell Parameters Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Function-Structure.md The AllowEmptyString attribute enables a mandatory parameter to accept an empty string ("") as a valid input. This is useful when an empty string is a legitimate value for a required parameter, preventing PowerShell from treating it as an invalid input. ```PowerShell param ( [Parameter(Mandatory = $true)] [AllowEmptyString()] [String] $ComputerName ) ``` -------------------------------- ### Validate PowerShell Parameter Against Predefined Set of Values Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Function-Structure.md The ValidateSet attribute specifies a fixed set of valid values for a parameter or variable. PowerShell generates an error if the input value does not match any value within this predefined set, ensuring only allowed options are used and providing tab-completion for users. ```PowerShell param ( [Parameter(Mandatory = $true)] [ValidateSet("Low", "Average", "High")] [String[]] $Detail ) ``` -------------------------------- ### Validate PowerShell Parameter Against Regex Pattern Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Function-Structure.md The ValidatePattern attribute compares a parameter or variable value against a specified regular expression. An error is generated if the value does not match the defined pattern, ensuring input adheres to a specific format like IP addresses or specific naming conventions. ```PowerShell param ( [Parameter(Mandatory = $true)] [ValidatePattern("[0-9][0-9][0-9][0-9]")] [String[]] $ComputerName ) ``` -------------------------------- ### Validate PowerShell Parameter for Null Values with AllowNull Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Function-Structure.md The AllowNull attribute permits a mandatory parameter to accept a null ($null) value. This is useful when null is a valid input for a required parameter, allowing explicit acceptance of null without throwing an error. ```PowerShell param ( [Parameter(Mandatory = $true)] [AllowNull()] [String] $ComputerName ) ``` -------------------------------- ### Permit Empty Collections for Mandatory PowerShell Parameters Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Function-Structure.md The AllowEmptyCollection attribute allows a mandatory parameter to accept an empty collection (@()) as a valid input. This is applicable when an empty collection is a legitimate value for a required parameter, ensuring flexibility in array-type inputs. ```PowerShell param ( [Parameter(Mandatory = $true)] [AllowEmptyCollection()] [String[]] $ComputerName ) ``` -------------------------------- ### Validate PowerShell Parameter Using Custom Script Block Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Function-Structure.md The ValidateScript attribute allows a custom script block to validate a parameter or variable value. The value is piped to the script (accessible via `$_`), and an error is generated if the script returns `false` or throws an exception, providing flexible and complex validation logic. ```PowerShell param ( [Parameter()] [ValidateScript({$_ -ge (get-date)})] [DateTime] $EventDate ) ``` -------------------------------- ### PowerShell: Avoiding Semicolons in Hashtable Declarations Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Code-Layout-and-Formatting.md This section advises against using semicolons as line terminators in PowerShell, especially when declaring hashtables with each element on its own line. Semicolons are often unnecessary and can complicate code editing and source control analysis. ```powershell $myHashtable = @{ "Key1" = "Value1" "Key2" = "Value2" } ``` -------------------------------- ### Ensure PowerShell Parameter is Not Null or Empty Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Function-Structure.md The ValidateNotNullOrEmpty attribute specifies that the parameter value cannot be null ($null), an empty string (""), or an empty array. PowerShell generates an error if the parameter receives any of these invalid empty states, ensuring meaningful input. ```PowerShell param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [String[]] $UserName ) ``` -------------------------------- ### Validate PowerShell Parameter Count with ValidateCount Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Function-Structure.md The ValidateCount attribute specifies the minimum and maximum number of values a parameter can accept. PowerShell generates an error if the number of values provided falls outside this defined range, ensuring that collections or arrays have an appropriate number of elements. ```PowerShell param ( [Parameter(Mandatory = $true)] [ValidateCount(1,5)] [String[]] $ComputerName ) ``` -------------------------------- ### Validate PowerShell Parameter String Length with ValidateLength Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Function-Structure.md The ValidateLength attribute defines the minimum and maximum character length for a parameter or variable value. PowerShell will throw an error if the input value's length is outside the specified range, enforcing string length constraints. ```PowerShell param ( [Parameter(Mandatory = $true)] [ValidateLength(1,10)] [String[]] $ComputerName ) ``` -------------------------------- ### Ensure PowerShell Parameter is Not Null with ValidateNotNull Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Function-Structure.md The ValidateNotNull attribute ensures that a parameter value cannot be null ($null). PowerShell generates an error if a null value is provided, especially useful when the parameter's type might otherwise accept null or when the type is not explicitly specified. ```PowerShell param ( [Parameter(Mandatory = $true)] [ValidateNotNull()] $ID ) ``` -------------------------------- ### Validate PowerShell Parameter Numeric Range with ValidateRange Source: https://github.com/poshcode/powershellpracticeandstyle/blob/master/Style-Guide/Function-Structure.md The ValidateRange attribute specifies an acceptable numeric range for a parameter or variable value. PowerShell generates an error if any input value falls outside this defined range, ensuring numerical integrity for integer or decimal inputs. ```PowerShell param ( [Parameter(Mandatory = $true)] [ValidateRange(0,10)] [Int] $Attempts ) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.