PowerShell Gotchas
Overview
The purpose of this page is to capture various PowerShell "gotchas," or cases where the PowerShell design of think -> type -> execute breaks down. Note that these do not constitute bugs or feature requests; this page is simply documentation of how to leverage the PowerShell language appropriately in these situations.
Contents
The Difference Between ~ and $home.
Some Job Types Require the Associated Module to be Imported in Order to See Them.
Gotchas
The Difference Between ~ and $home.
In PowerShell, there is a big difference between the “~” path shortcut and the value of the $home automatic variable:
- “~” is a shortcut to the home path for the PowerShell provider backing the current location. In other words, the value of “~” changes depending on what type of drive you’re currently working (e.g., File System, registry, etc).
- $home is set to the user’s home directory; e.g.: C:\users\yourusername. $home never changes.
This can be confusing because ~ in Linux is the semantic equivalent to $home in PowerShell.
The two are identical if you’re working on a file system drive. For example:
PS C:\> resolve-path ~
Path
----
C:\Users\beefarino
PS C:\> $home
C:\Users\beefarino
When you move to a drive for a different provider, the value of ~ changes, usually to an undefined value:
PS C:\> cd cert:
PS cert:\> resolve-path ~
Resolve-Path : Home location for this provider is not set. To set the home location, call "(get-psprovider 'Certificate').Home = 'path'". At line:1 char:13 + resolve-path <<<< ~ + CategoryInfo : InvalidOperation: (:) [Resolve-Path], PSInvalidOperationEx ception + FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.ResolvePath Command
In fact, the only core PowerShell provider that defines a value for ~ is the file system provider:
PS C:\> get-psprovider | where {$_.home}
Name Capabilities Drives
---- ------------ ------
FileSystem Filter, ShouldProcess {C, D}
In that respect, using ~ in scripts is fairly fragile unless you set-location to a file system path first. $home is a better choice since it’s an absolute path.
Some Job Types Require the Associated Module to be Imported in Order to See Them.
The Windows PowerShell jobs infrastructure supports four types of jobs in V3:
- BackgroundJob
- RemoteJob
- PSScheduledJob
- PSWorkflowJob
Both the PSScheduledJob and PSWorkflowJob types can exist across sessions. In order to examine the results of a scheduled task created using Register-ScheduledJob or a workflow ran using -AsJob from a different Windows PowerShell session, you need to ensure the appropriate module is imported. Say I registered a scheduled job a week ago and I need to check the output of the job. It is not likely that same PowerShell session is still hanging around. If I start a new Windows PowerShell session and execute "Get-Job" I will not see the job output from my scheduled job. In order to see job details for scheduled jobs I need to first execute :
PS C:\ import-module PSScheduledJob
After importing PSScheduledJob, the scheduled jobs provider gets integrated into the job infrastructure. The same applies for Workflows. In this case, you need to import PSWorkflow first before you can see the job output of workflows started in other Windows PowerShell sessions.
This was fixed in version 4.0: “You no longer need to explicitly load ScheduledJob or Workflow modules to work with their job types.”