Single Characters (And Other Newbie Questions Probably)

Good morning,

I am brand new to PowerShell. I am currently working through the Beginner and Advanced courses over PowerShell on the MVA site. I just got through the very first “Getting Started with Windows PowerShell” videos, and I moved onto the first DSC video.

However, I keep getting lost on what single character(s) mean in PowerShell. For instance we ran this basic code:

get-dscresource -ov r | measure

I understand that the get command is looking for the DSC resources on my local machine. And that the | into measure is getting the number of entries. But I am not sure what the -ov and r means. I am pretty bad at these single characters and remembering what all they mean. Is there a easy command (or resource) I can use to see all the examples of these characters?

-ov stands for ‘-OutVariable’, basically putting the ouput in a variable called ‘r’

you can call it later by using ‘$r’

It’s a common paramter. about CommonParameters - PowerShell | Microsoft Docs

It’s a very neat technique to help you saving intermediate results when you do some research to solve a particular problem or to accomplish a particular task.

Get-Process -OutVariable A |
Where-Object -Property Company -Match -Value Microsoft -OutVariable B |
Where-Object -Property WS -GT -Value 100000000 -OutVariable C

$A
$B
$C

$A.Count
$B.Count
$C.Count

What the others haven’t mentioned, and I don’t know if you’re aware of it, is that the single characters can be used when PowerShell “knows” that there is only one possible parameter it could be.

For Example:

Get-Help Get-ChildItem -Ful” is the same as “Get-Help Get-ChildItem -Full

But “Get-Help Get-ChildItem -Fu” wouldn’t work, because “-fu”, could be either “Full” or “Functionality

If in doubt, use Tab Complete, and always always ALWAYS type out commands in full.

 

The short hand stuff is fine for quick interactive one-liner stuff. Not for scripts, especially production and or shared scripts, modules, etc.

Always use descriptive variables / parameter names. Always be aware to not use built-in variable, or alias names. I recommend to prefix your variables, etc., with something unique so that you are more sure that you are not going to conflict with other things.

For example, any variable of mine would be –

My forum is postanote, so, my naming convention is…

$ponHost
$ponMyDate
$ponUserName
$ponDomainName

… or in your case, using the target

get-dscresource -ov l07R | measure

This way when you need to get back at your custom stuff, just type $YourPrefix and you’d get a popup / intelligence list of all you create that you can select from or clear as needed.

If you do not, you end up where you are now and make your script hard to read, maintain.

DSC specific best practice information

Question on variable naming convention he DSC resource style guide dictates that camel case notation should be used for variable names. https://github.com/PowerShell/DscResources/issues/109

See also:

Capitalization guidelines https://github.com/PoshCode/PowerShellPracticeAndStyle/issues/36
# PowerShell Best Practices

PowerShell Standard Library: Build single module that works across Windows PowerShell and PowerShell Core

Windows PowerShell
https://docs.microsoft.com/en-us/powershell/developer/windows-powershell

Windows PowerShell Best Practices

PowerShell scripting best practices
https://blogs.technet.microsoft.com/pstips/2014/06/17/powershell-scripting-best-practices

The Unofficial PowerShell Best Practices and Style Guide
https://blogs.technet.microsoft.com/pstips/2014/06/17/powershell-scripting-best-practices

Using PSScriptAnalyzer to check your PowerShell code for best practices

PowerShellPracticeAndStyle

PowerShell scripting best practices

Powershell - Recommended coding style

What is the recommended coding style for PowerShell?

PowerShell 4.0 Best Practices scripts
This is a place holder for all the scripts from my forthcoming Windows PowerShell 4.0 Best Practices book. Once the book releases, I will upload the 200 scripts to this location – which is currently referenced in my book. The idea is similiar to the one that I did for the Wi

Virtually all of PS has shorthand approaches, but even if you use those, again, that’s good for interactive stuff, not shared or production scripts. Always expand them before delivery to others.

Something I give my students, teammates, well part of a larger one.

# Help lookup options
# Get parameters, examples, full and Online help for a cmdlet or function

# Get a list of all functions
Get-Command -CommandType Function | 
Out-GridView -PassThru -Title 'Available functions'

# Get a list of all commandlets
Get-Command -CommandType Cmdlet | 
Out-GridView -PassThru -Title 'Available cmdlets'

# Get a list of all functions for the specified name
Get-Command -Name '*ADGroup*' -CommandType Function | 
Out-GridView -PassThru -Title 'Available named functions'

# Get a list of all commandlets for the specified name
Get-Command -Name '*ADGroup**'  -CommandType Cmdlet | 
Out-GridView -PassThru -Title 'Available named cmdlet'

# get function / cmdlet details
(Get-Command -Name Get-ADUser).Parameters
Get-help -Name Get-ADUser -Examples
Get-help -Name Get-ADUser -Full
Get-help -Name Get-ADUser -Online


# Get parameter that accepts pipeline input
Get-Help Get-ADUser -Parameter * | 
Where-Object {$_.pipelineInput -match 'true'} | 
Select * 


# List of all parameters that a given cmdlet supports along with a short description:
Get-Help dir -para * | 
Format-Table Name, { $_.Description[0].Text } -wrap


# Get Powershell Version info per cmdlet / function
# Errors displayed can be ignored
$TargetCmdlets = (Get-Command).Name -match 'process'
$CmdletSupportedPowerShellVersion = ForEach($Command in $TargetCmdlets) 
{
    $Command
    (Get-Module (Get-Command -Name $Command).Module) | 
    Select-Object -Property ModuleType,Name,PowerShellVersion,
    @{Name = 'CmdletName_FinctionName';Expression = {$Command}}
}
$CmdletSupportedPowerShellVersion | 
Select-Object -Property ModuleType,Name,CmdletName_FinctionName,PowerShellVersion | 
Sort-Object -Property Name,PowerShellVersion | 
Out-GridView -PassThru -Title 'Show list of supported PowerShel version for modules/cmdlet/functions'

Get-Help about_*
Get-Help about_Functions

# Find all cmdlets / functions with a target parameter
Get-Command -CommandType Function | 
Where-Object { $_.parameters.keys -match 'credential'} | 
Out-GridView -PassThru -Title 'Available functions which has a specific parameter'

Get-Command -CommandType Cmdlet | 
Where-Object { $_.parameters.keys -match 'credential'} | 
Out-GridView -PassThru -Title 'Results for cmdlets which has a specific parameter'

# Get named aliases 
Get-Alias | 
Out-GridView -PassThru -Title 'Available aliases'

# Get cmdlet / function parameter aliases
(Get-Command Get-ADUser).Parameters.Values | 
where aliases | 
select Name, Aliases | Out-GridView -PassThru -Title 'Alias results for a given cmdlet or function.'


# All Help topics locations
Get-Help about* | Select Name, Synopsis

Get-Help about* | 
  Select-Object -Property Name, Synopsis |
  Out-GridView -Title 'Select Topic' -OutputMode Multiple |
  ForEach-Object {
    Get-Help -Name $_.Name -ShowWindow
  }

### Query Powershell Data Types

[AppDomain]::CurrentDomain.GetAssemblies() `
| Foreach-Object {
    $_.GetExportedTypes()
}

# Or 

[psobject].Assembly.GetType("System.Management.Automation.TypeAccelerators")::Get.GetEnumerator() `
| Sort-Object -Property Key

# Or 

$Object.GetType().FullName, $Object.Property.GetType().FullName, $Object `
| Get-Member, or $Object `
| Get-Member -Static


<#
 Get any .NET types and their static methods from PowerShell. 
 Enumerate all that are currently loaded into your AppDomain.
#>  
[AppDomain]::CurrentDomain.GetAssemblies() `
| foreach { $_.GetTypes() } `
| foreach { $_.GetMethods() } `
| where { $_.IsStatic } `
| select DeclaringType, Name `
| Out-GridView -PassThru -Title '.NET types and their static methods'

The amount of best practices broken in this thread is astounding. I’m not entirely surprised to hear a DSC lesson broke a few, but it is a bit concerning.

And that script full of backticks… oh my. Try to avoid backticks in your script. I get it, pipes at the start of a line are really pretty. It’s one of the reasons I love F# so much. But PS isn’t there yet. Backticks make for very fragile code – a single trailing space can break the line, and then you have some pretty colourful behaviour.

Mark Kraus has a wonderful blog post on the topic.

In general, I tend to recommend people strongly avoid any use of aliases of command or parameter names in published or even shared scripts, for this very reason. It creates a lot of confusion for newer folks, and there’s really no reason to muddy a script with aliases. Someone’s gonna have to maintain that, sooner or later, and the clearer it can be written, the easier it is to maintain, both for yourself and the next person along the line.