Chapter 5 - Formatting, aliases, providers, comparison
Prerequisites
The SqlServer PowerShell module is required by some examples shown in this chapter. For more information about the SqlServer PowerShell module and installation instructions, see SQL Server PowerShell overview. It's also used in subsequent chapters. Download and install it on your Windows lab environment computer.
Format Right
In Chapter 4, you learned to filter as far to the left as possible. The rule for manually formatting a command's output is similar to that rule, except it needs to occur as far to the right as possible.
The most common format commands are Format-Table
and Format-List
. Format-Wide
and
Format-Custom
can also be used, but are less common.
As mentioned in Chapter 3, a command that returns more than four properties defaults to a list unless custom formatting is used.
Get-Service -Name w32time |
Select-Object -Property Status, DisplayName, Can*
Status : Running
DisplayName : Windows Time
CanPauseAndContinue : False
CanShutdown : True
CanStop : True
Use the Format-Table
cmdlet to manually override the formatting and show the output in a table
instead of a list.
Get-Service -Name w32time |
Select-Object -Property Status, DisplayName, Can* |
Format-Table
Status DisplayName CanPauseAndContinue CanShutdown CanStop
------ ----------- ------------------- ----------- -------
Running Windows Time False True True
The default output for Get-Service
is three properties in a table.
Get-Service -Name w32time
Status Name DisplayName
------ ---- -----------
Running w32time Windows Time
Use the Format-List
cmdlet to override the default formatting and return the results in a list.
Get-Service -Name w32time | Format-List
Notice that simply piping Get-Service
to Format-List
made it return additional properties. This
doesn't occur with every command because of how the format for that particular command is set up
behind the scenes.
Name : w32time
DisplayName : Windows Time
Status : Running
DependentServices : {}
ServicesDependedOn : {}
CanPauseAndContinue : False
CanShutdown : True
CanStop : True
ServiceType : Win32OwnProcess, Win32ShareProcess
The number one thing to be aware of with the format cmdlets is they produce format objects that are different than normal objects in PowerShell.
Get-Service -Name w32time | Format-List | Get-Member
TypeName: Microsoft.PowerShell.Commands.Internal.Format.FormatStartData
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Obj...
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
autosizeInfo Property Microsoft.PowerShell.C...
ClassId2e4f51ef21dd47e99d3c952918aff9cd Property string ClassId2e4f51ef...
groupingEntry Property Microsoft.PowerShell.C...
pageFooterEntry Property Microsoft.PowerShell.C...
pageHeaderEntry Property Microsoft.PowerShell.C...
shapeInfo Property Microsoft.PowerShell.C...
TypeName: Microsoft.PowerShell.Commands.Internal.Format.GroupStartData
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Obj...
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
ClassId2e4f51ef21dd47e99d3c952918aff9cd Property string ClassId2e4f51ef...
groupingEntry Property Microsoft.PowerShell.C...
shapeInfo Property Microsoft.PowerShell.C...
TypeName: Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Obj...
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
ClassId2e4f51ef21dd47e99d3c952918aff9cd Property string ClassId2e4f51ef...
formatEntryInfo Property Microsoft.PowerShell.C...
outOfBand Property bool outOfBand {get;set;}
writeStream Property Microsoft.PowerShell.C...
TypeName: Microsoft.PowerShell.Commands.Internal.Format.GroupEndData
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Obj...
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
ClassId2e4f51ef21dd47e99d3c952918aff9cd Property string ClassId2e4f51ef...
groupingEntry Property Microsoft.PowerShell.C...
TypeName: Microsoft.PowerShell.Commands.Internal.Format.FormatEndData
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Obj...
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
ClassId2e4f51ef21dd47e99d3c952918aff9cd Property string ClassId2e4f51ef...
groupingEntry Property Microsoft.PowerShell.C...
What this means is format commands can't be piped to most other commands. They can be piped to some
of the Out-*
commands, but that's about it. This is why you want to perform any formatting at the
very end of the line (format right).
Aliases
An alias in PowerShell is a shorter name for a command. PowerShell includes a set of built-in aliases and you can also define your own aliases.
The Get-Alias
cmdlet is used to find aliases. If you already know the alias for a command, the
Name parameter is used to determine what command the alias is associated with.
Get-Alias -Name gcm
CommandType Name Version
----------- ---- -------
Alias gcm -> Get-Command
Multiple aliases can be specified for the value of the Name parameter.
Get-Alias -Name gcm, gm
CommandType Name Version
----------- ---- -------
Alias gcm -> Get-Command
Alias gm -> Get-Member
You often see the Name parameter omitted since it's a positional parameter.
Get-Alias gm
CommandType Name Version
----------- ---- -------
Alias gm -> Get-Member
If you want to find aliases for a command, you need to use the Definition parameter.
Get-Alias -Definition Get-Command, Get-Member
CommandType Name Version
----------- ---- -------
Alias gcm -> Get-Command
Alias gm -> Get-Member
The Definition parameter can't be used positionally, so it must be specified.
Aliases can save you a few keystrokes, and they're fine when you type commands into the console. They shouldn't be used in scripts or any code that you're saving or sharing with others. As mentioned earlier in this book, using full cmdlet and parameter names is self-documenting and easier to understand.
Use caution when creating your own aliases because they only exist in your current PowerShell session on your computer.
Providers
A provider in PowerShell is an interface that allows file system-like access to a data store. There are several built-in providers in PowerShell.
Get-PSProvider
As you can see in the following results, there are built-in providers for the registry, aliases, environment variables, the file system, functions, variables, certificates, and WSMan.
Name Capabilities Drives
---- ------------ ------
Registry ShouldProcess, Transactions {HKLM, HKCU}
Alias ShouldProcess {Alias}
Environment ShouldProcess {Env}
FileSystem Filter, ShouldProcess, Cr... {C, D}
Function ShouldProcess {Function}
Variable ShouldProcess {Variable}
The actual drives that these providers use to expose their data store can be determined with the
Get-PSDrive
cmdlet. The Get-PSDrive
cmdlet not only displays drives exposed by providers but
also displays Windows logical drives, including drives mapped to network shares.
Get-PSDrive
Name Used (GB) Free (GB) Provider Root
---- --------- --------- -------- ----
Alias Alias
C 18.56 107.62 FileSystem C:\
Cert Certificate \
D FileSystem D:\
Env Environment
Function Function
HKCU Registry HKEY_CURRENT_USER
HKLM Registry HKEY_LOCAL_MACHINE
Variable Variable
WSMan WSMan
Third-party modules such as the ActiveDirectory PowerShell module and the SqlServer PowerShell module both add their own PowerShell provider and PSDrive.
Import the ActiveDirectory and SqlServer PowerShell modules.
Import-Module -Name ActiveDirectory, SQLServer
Check to see if any additional PowerShell providers were added.
Get-PSProvider
Notice that in the following set of results, two new PowerShell providers now exist, one for Active Directory and another one for SQL Server.
Name Capabilities Drives
---- ------------ ------
Registry ShouldProcess, Transactions {HKLM, HKCU}
Alias ShouldProcess {Alias}
Environment ShouldProcess {Env}
FileSystem Filter, ShouldProcess, Credentials {C, A, D}
Function ShouldProcess {Function}
Variable ShouldProcess {Variable}
ActiveDirectory Include, Exclude, Filter, Shoul... {AD}
SqlServer Credentials {SQLSERVER}
A PSDrive for each of those modules was also added.
Get-PSDrive
Name Used (GB) Free (GB) Provider Root
---- --------- --------- -------- ----
A FileSystem A:\
AD ActiveDire... //RootDSE/
Alias Alias
C 19.38 107.13 FileSystem C:\
Cert Certificate \
D FileSystem D:\
Env Environment
Function Function
HKCU Registry HKEY_CURRENT_USER
HKLM Registry HKEY_LOCAL_MACHINE
SQLSERVER SqlServer SQLSERVER:\
Variable Variable
WSMan WSMan
PSDrives can be accessed just like a traditional file system.
Get-ChildItem -Path Cert:\LocalMachine\CA
PSParentPath: Microsoft.PowerShell.Security\Certificate::LocalMachine\CA
Thumbprint Subject
---------- -------
FEE449EE0E3965A5246F000E87FDE2A065FD89D4 CN=Root Agency
D559A586669B08F46A30A133F8A9ED3D038E2EA8 OU=www.verisign.com/CPS Incorp....
109F1CAED645BB78B3EA2B94C0697C740733031C CN=Microsoft Windows Hardware C...
Comparison Operators
PowerShell contains various comparison operators that are used to compare values or find values that match certain patterns. The following table contains a list of comparison operators in PowerShell.
All the operators listed in the table are case-insensitive. To make them case-sensitive, place a c
in front of the operator. For example, -ceq
is the case-sensitive version of the equals (-eq
)
comparison operator.
Operator | Definition |
---|---|
-eq |
Equal to |
-ne |
Not equal to |
-gt |
Greater than |
-ge |
Greater than or equal to |
-lt |
Less than |
-le |
Less than or equal to |
-Like |
Match using the * wildcard character |
-NotLike |
Doesn't match using the * wildcard character |
-Match |
Matches the specified regular expression |
-NotMatch |
Doesn't match the specified regular expression |
-Contains |
Determines if a collection contains a specified value |
-NotContains |
Determines if a collection doesn't contain a specific value |
-In |
Determines if a specified value is in a collection |
-NotIn |
Determines if a specified value isn't in a collection |
-Replace |
Replaces the specified value |
Proper case "PowerShell" is equal to lower case "powershell" using the equals comparison operator.
'PowerShell' -eq 'powershell'
True
It's not equal using the case-sensitive version of the equals comparison operator.
'PowerShell' -ceq 'powershell'
False
The not equal comparison operator reverses the condition.
'PowerShell' -ne 'powershell'
False
Greater than, greater than or equal to, less than, and less than or equal all work with string or numeric values.
5 -gt 5
False
Using greater than or equal to instead of greater than with the previous example returns the Boolean true since five is equal to five.
5 -ge 5
True
Based on the results from the previous two examples, you can probably guess how both less than and less than or equal to work.
5 -lt 10
True
The -Like
and -Match
operators can be confusing, even for experienced PowerShell users. -Like
is used with the wildcard characters *
and ?
to perform "like" matches.
'PowerShell' -like '*shell'
True
-Match
uses a regular expression to perform the matching.
'PowerShell' -match '^.*shell$'
True
Use the range operator to store the numbers 1 through 10 in a variable.
$Numbers = 1..10
Determine if the $Numbers
variable includes 15.
$Numbers -contains 15
False
Determine if it includes the number 10.
$Numbers -contains 10
True
-NotContains
reverses the logic to see if the $Numbers
variable doesn't contain a value.
$Numbers -notcontains 15
The previous example returns the Boolean true because it's true that the $Numbers
variable
doesn't contain 15.
True
It does, however, contain the number 10, so it's false when tested.
$Numbers -notcontains 10
False
The -in
comparison operator was first introduced in PowerShell version 3.0. It's used to determine
if a value is in an array. The $Numbers
variable is an array since it contains multiple values.
15 -in $Numbers
False
In other words, -in
performs the same test as the contains comparison operator except from the
opposite direction.
10 -in $Numbers
True
Fifteen isn't in the $Numbers
array, so false is returned in the following example.
15 -in $Numbers
False
Just like the -contains
operator, not
reverses the logic for the -in
operator.
10 -notin $Numbers
The previous example returns false because the $Numbers
array does include 10 and the condition
tests to determine if it doesn't contain 10.
False
Determine if fifteen isn't in the $Numbers
array.
15 -notin $Numbers
15 is "not in" the $Numbers
array so it returns the Boolean true.
True
The -replace
operator does just want you would think. It's used to replace something. Specifying
one value replaces that value with nothing. In the following example, you replace "Shell" with
nothing.
'PowerShell' -replace 'Shell'
Power
If you want to replace a value with a different one, specify the new one after the pattern you want to replace. SQL Saturday in Baton Rouge is an event I try to speak at every year. In the following example, the word "Saturday" is replaced with the abbreviation "Sat".
'SQL Saturday - Baton Rouge' -Replace 'saturday','Sat'
SQL Sat - Baton Rouge
There are also methods like Replace() that can be used to replace things similar to how the
replace operator works. However, the -Replace
operator is case-insensitive by default, and the
Replace() method is case-sensitive.
'SQL Saturday - Baton Rouge'.Replace('saturday','Sat')
Notice that the word "Saturday" isn't replaced. This is because it's specified in a different case than the original.
SQL Saturday - Baton Rouge
When the word "Saturday" is specified in the same case as the original, the Replace() method performs the replacement as expected.
'SQL Saturday - Baton Rouge'.Replace('Saturday','Sat')
SQL Sat - Baton Rouge
Be careful when using methods to transform data because you can encounter unforeseen problems, such as failing the Turkey Test. For an example, see my blog article, Using Pester to Test PowerShell Code with Other Cultures. I recommend using operators instead of methods whenever possible to avoid these types of problems.
While the comparison operators can be used, as shown in the previous examples, I typically use them
with the Where-Object
cmdlet to perform filtering.
Summary
You learned several topics in this chapter, including Formatting Right, Aliases, Providers, and Comparison Operators.
Review
- Why is it necessary to perform formatting as far to the right as possible?
- How do you determine what the actual cmdlet is for the
%
alias? - Why shouldn't you use aliases in scripts you save or code you share with others?
- Perform a directory listing on the drives that are associated with one of the registry providers.
- What's one of the main benefits of using the replace operator instead of the replace method?
References
- Format-Table
- Format-List
- Format-Wide
- about_Aliases
- about_Providers
- about_Comparison_Operators
- about_Arrays
Next steps
In the next chapter, you'll learn about flow control, scripting, loops, and conditional logic.