PowerShell tips for building objects with custom properties and special formatting


 

I’ve been building a number of scripts that query information using PowerShell.

To create those, I used some PowerShell tricks to make the output look just like I wanted. This post is a compilation of these tricks.

The first few tricks are simple, but they grow increasingly complex towards the end.

The examples here are geared towards SMB Shares and Volumes, but you can apply these concepts in many, many other situations.

 

1) Using –AutoSize

 

I do not like the default way that PowerShell spaces out fields in a query. I prefer them packed on the left, which is what the AutoSize option of the Format-Table cmdlet (FT for short) does.

AutoSize, as the name implies, also adjusts to the size of the properties and avoids showing “…” at the end of the output.

 

PS C:> Get-SmbShare

Name                          ScopeName                     Path                          Description
—-                          ———                     —-                          ———–
ADMIN$                        *                             C:windows                    Remote Admin
BackupFiles                   *                             E:Backup                     Project backup files
C$                            *                             C:                           Default share
D$                            *                             D:                           Default share
F$                            *                             F:                           Default share
Images                        *                             D:Images                     Pictures to be used in pro…
IPC$                          *                                                           Remote IPC
print$                        *                             C:windowssystem32spool… Printer Drivers
Projects                      *                             C:Projects                   Recent project files

 

PS C:> Get-SmbShare | FT -AutoSize

Name        ScopeName Path                              Description
—-        ——— —-                              ———–
ADMIN$      *         C:windows                        Remote Admin
BackupFiles *         E:Backup                         Project backup files
C$          *         C:                               Default share
D$          *         D:                               Default share
F$          *         F:                               Default share
Images      *         D:Images                         Pictures to be used in projects
IPC$        *                                           Remote IPC
print$      *         C:windowssystem32spooldrivers Printer Drivers
Projects    *         C:Projects                       Recent project files

 

2) Selecting columns to show

 

Every object has a default view with a specific set of columns. If you don’t like those, you can select your own. To find out what fields you can use, you can use a “Select *” or a “Get-Member” to find out.

 

PS C:> Get-SmbShare | Select * -First 1

PresetPathAcl         :
ShareState            : Online
AvailabilityType      : NonClustered
ShareType             : FileSystemDirectory
FolderEnumerationMode : Unrestricted
CachingMode           : Manual
SmbInstance           : Default
CATimeout             : 0
ConcurrentUserLimit   : 0
ContinuouslyAvailable : False
CurrentUsers          : 0
Description           : Remote Admin
EncryptData           : False
Name                  : ADMIN$
Path                  : C:windows
Scoped                : False
ScopeName             : *
SecurityDescriptor    : O:SYG:SYD:(A;;GA;;;BA)(A;;GA;;;BO)(A;;GA;;;IU)
ShadowCopy            : False
Special               : True
Temporary             : False
Volume                : \?Volume{4304337d-6763-11e3-8255-806e6f6e6963}
PSComputerName        :
CimClass              : ROOT/Microsoft/Windows/SMB:MSFT_SmbShare
CimInstanceProperties : {AvailabilityType, CachingMode, CATimeout, ConcurrentUserLimit…}
CimSystemProperties   : Microsoft.Management.Infrastructure.CimSystemProperties

PS C:> Get-SmbShare | Get-Member

   TypeName: Microsoft.Management.Infrastructure.CimInstance#ROOT/Microsoft/Windows/SMB/MSFT_SmbShare

Name                      MemberType     Definition
—-                      ———-     ———-
Clone                     Method         System.Object ICloneable.Clone()
Dispose                   Method         void Dispose(), void IDisposable.Dispose()
Equals                    Method         bool Equals(System.Object obj)
GetCimSessionComputerName Method         string GetCimSessionComputerName()
GetCimSessionInstanceId   Method         guid GetCimSessionInstanceId()
GetHashCode               Method         int GetHashCode()
GetObjectData             Method         void GetObjectData(System.Runtime.Serialization.SerializationInfo info, Sys…
GetType                   Method         type GetType()
ToString                  Method         string ToString()
CATimeout                 Property       uint32 CATimeout {get;set;}
ConcurrentUserLimit       Property       uint32 ConcurrentUserLimit {get;set;}
ContinuouslyAvailable     Property       bool ContinuouslyAvailable {get;set;}
CurrentUsers              Property       uint32 CurrentUsers {get;set;}
Description               Property       string Description {get;set;}
EncryptData               Property       bool EncryptData {get;set;}
Name                      Property       string Name {get;}
Path                      Property       string Path {get;}
PSComputerName            Property       string PSComputerName {get;}
Scoped                    Property       bool Scoped {get;}
ScopeName                 Property       string ScopeName {get;}
SecurityDescriptor        Property       string SecurityDescriptor {get;set;}
ShadowCopy                Property       bool ShadowCopy {get;}
Special                   Property       bool Special {get;}
Temporary                 Property       bool Temporary {get;}
Volume                    Property       string Volume {get;}
AvailabilityType          ScriptProperty System.Object AvailabilityType {get=[Microsoft.PowerShell.Cmdletization.Gen…
CachingMode               ScriptProperty System.Object CachingMode {get=[Microsoft.PowerShell.Cmdletization.Generate…
FolderEnumerationMode     ScriptProperty System.Object FolderEnumerationMode {get=[Microsoft.PowerShell.Cmdletizatio…
PresetPathAcl             ScriptProperty System.Object PresetPathAcl {get=$acl = Get-Acl ($this.PSBase.CimInstancePr…
ShareState                ScriptProperty System.Object ShareState {get=[Microsoft.PowerShell.Cmdletization.Generated…
ShareType                 ScriptProperty System.Object ShareType {get=[Microsoft.PowerShell.Cmdletization.GeneratedT…
SmbInstance               ScriptProperty System.Object SmbInstance {get=[Microsoft.PowerShell.Cmdletization.Generate…

 

PS C:> Get-SmbShare | FT Name, Path, Special, AvailabilityType -AutoSize

Name        Path                              Special AvailabilityType
—-        —-                              ——- —————-
ADMIN$      C:windows                           True     NonClustered
BackupFiles E:Backup                           False     NonClustered
C$          C:                                  True     NonClustered
D$          D:                                  True     NonClustered
F$          F:                                  True     NonClustered
Images      D:Images                           False     NonClustered
IPC$                                             True     NonClustered
print$      C:windowssystem32spooldrivers   False     NonClustered
Projects    C:Projects                         False     NonClustered

 

3) Selecting rows to show

 

You can restrict the items to show based on any of its properties. You need to learn to use the many types of operators like equal (-eq), not equal (-ne), greater than (-gt), like (-like), not like (-not like) and many others.

The cmdlet used is Where-Object, but it can be abbreviated as Where or simply a question mark. There is a simple form for querying just one property and also a more complex form for using expressions.

For instance, to show all shares that are not special, you can one of these:
Get-SmbShare | Where-Object {$_.Special –ne $true}
Get-SmbShare | ? Special –ne $true

If you use the form with the expression in {}, you must specify $_.property, where $_ means “the current item we’re processing”. The simpler form without {} can be used with only one property.

Here’s a more complex example to show all shares that are not special and with a description starting with the letter P:
Get-SmbShare | ? { $_.Special -ne $true -and $_.Description -like “P*” }

 

PS C:> Get-SmbShare | Where-Object {$_.Special –ne $true} | FT -AutoSize

Name        ScopeName Path                              Description
—-        ——— —-                              ———–
BackupFiles *         E:Backup                         Project backup files
Images      *         D:Images                         Pictures to be used in projects
print$      *         C:windowssystem32spooldrivers Printer Drivers
Projects    *         C:Projects                       Recent project files

PS C:> Get-SmbShare | ? Special –ne $true| FT -AutoSize

Name        ScopeName Path                              Description
—-        ——— —-                              ———–
BackupFiles *         E:Backup                         Project backup files
Images      *         D:Images                         Pictures to be used in projects
print$      *         C:windowssystem32spooldrivers Printer Drivers
Projects    *         C:Projects                       Recent project files

PS C:> Get-SmbShare | ? Special | FT -AutoSize

Name   ScopeName Path       Description
—-   ——— —-       ———–
ADMIN$ *         C:windows Remote Admin
C$     *         C:        Default share
D$     *         D:        Default share
F$     *         F:        Default share
IPC$   *                    Remote IPC

PS C:> Get-SmbShare | ? { $_.Special -ne $true -and $_.Description -like “P*” } | FT -AutoSize

Name        ScopeName Path                              Description
—-        ——— —-                              ———–
BackupFiles *         E:Backup                         Project backup files
Images      *         D:Images                         Pictures to be used in projects
print$      *         C:windowssystem32spooldrivers Printer Drivers

 

4) Creating custom columns

 

In addition to the ability to select which columns to show, you can also create custom tables with any expression. This is useful for creating new calculated columns based on the existing ones.

You can also use this same process to rename existing properties (if you don’t like their default names) or customize the alignment/size of the column.

As with the full form of the “Where” filters, the expressions here must be enclosed in {} and references to existing properties must be preceded with $_.

The syntax uses a hash table, which is little unusual. You should include at least a “Label” (or “Name”) and an “Expression” item in the hash table. You can also specify “Alignment” (or “Align”) and “Width”.

Here’s an example to rename the “Path” property to “Folder”:
Get-SmbShare | FT Name, @{ Label=”Folder”; Expression={$_.Path} }, Description –AutoSize

Here’s another example showing only the drive letter of the path:
Get-SmbShare | FT Name, Description, @{ Name=”Drive”; Expression={$_.Path.Substring(0,1)}; Alignment=”Center” } –AutoSize

Lastly, a more complex example showing that shares ending with $ are hidden:
Get-SmbShare | FT Name, Path, @{ Align=”Center”; Expression={If ($_.Name –like “*$”) {“Yes”} else {“No”} }; Label=”Hidden” } –AutoSize

It’s a lot of curly braces, I know. Just make sure you keep good track of them.

 

PS C:> Get-SmbShare | FT Name, @{ Label=”Folder”; Expression={$_.Path} }, Description –AutoSize

Name        Folder                            Description
—-        ——                            ———–
ADMIN$      C:windows                        Remote Admin
BackupFiles E:Backup                         Project backup files
C$          C:                               Default share
D$          D:                               Default share
F$          F:                               Default share
Images      D:Images                         Pictures to be used in projects
IPC$                                          Remote IPC
print$      C:windowssystem32spooldrivers Printer Drivers
Projects    C:Projects         &nb

Comments (2)

  1. Me says:

    Very useful
    Thanks

  2. Anonymous says:

    I just published a PowerShell script to check the health and capacity of a Storage Cluster based on Windows Server 2012 R2 Scale-Out File Servers.