Powershell: Get-ChildItem -Path $null does not throw an error

Created on 21 Jan 2019  路  4Comments  路  Source: PowerShell/PowerShell

Steps to reproduce

Get-ChildItem -Path $vardoesnotexist
Get-ChildItem -Path $null

Expected behavior

Get-ChildItem : Cannot bind argument to parameter 'Path' because it is null.

Actual behavior

Get-ChildItem is ran against the current working directory

Environment data

Name                           Value
----                           -----
PSVersion                      6.1.2
PSEdition                      Core
GitCommitId                    6.1.2
OS                             Microsoft Windows 10.0.17763
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

This can cause expected results on a script based on whatever CWD happens to be at the time.
The problem also exists in 5.1

Area-Cmdlets Issue-Question Resolution-Answered

Most helpful comment

@BladeFireLight The default parameter -Path is not a mandatory parameter so there isn't an automatic check for null or empty path strings. (Note: if you use -LiteralPath, you will see the error you're expecting.) In fact there is explicit code in ProcessRecord for the cmdlet that sets the path list to examine to be an array containing a single empty string if the path is null. Keep in mind that that PowerShell is a _shell_ and so tries to do something useful if it can which in this case is to return the current directory. Finally the PowerShell behaviour is the same as bash or cmd.exe WRT empty strings - it displays the current directory (though for a different reason.)

All 4 comments

Never used V1. AFAIK, This is the same form v2.0 onwards.

@BladeFireLight The default parameter -Path is not a mandatory parameter so there isn't an automatic check for null or empty path strings. (Note: if you use -LiteralPath, you will see the error you're expecting.) In fact there is explicit code in ProcessRecord for the cmdlet that sets the path list to examine to be an array containing a single empty string if the path is null. Keep in mind that that PowerShell is a _shell_ and so tries to do something useful if it can which in this case is to return the current directory. Finally the PowerShell behaviour is the same as bash or cmd.exe WRT empty strings - it displays the current directory (though for a different reason.)

One of the side effects of this bug/feature could be to accidentally delete your system when you are using the output of this command piped to say a $_.Delete().

That is exactly what happened when I refactored my code to delete previous test runs; so
From :
Get-ChildItem -Path C:\SourceCodeTLMtestRunResults-Include * -File -Recurse | foreach { $_.Delete() }
To:
$testRunResults= "C:\SourceCodeTLMtestRunResults"
Get-ChildItem -Path $testRunResults-Include * -File -Recurse | foreach { $_.Delete() }
and forgot to initialize the variable while doing a debug.
In the worst case, I expected an error but instead, the cmd ran and started deleting my current dir content (Which by default was PS C:\windows\system32>).
Before I could understand what happened and pressed ctrl+c; enough files were deleted to corrupt my system. I had to restore and all of my stuff on my machine was lost. I learned this lesson the hard way but maybe others don't have to :). May be giving an error (when null) or keeping this parameter (mandatory) would be better from a risk standpoint :).

The parameter doesn't need to be mandatory to prevent null input.

We can tag it with [ValidateNotNullOrEmpty()] and PS should still allow no input to be provided. However, if a value is provided that is $null, an error will be thrown.

Also, if you used Remove-Item rather than the .NET method $_.Delete you would be given warnings pretty quickly as it started trying to remove _folders_ which by default it will refuse to do without confirmation or the -Recurse switch on Remove-Item itself, so you might have had another chance to catch that one at that point.

Was this page helpful?
0 / 5 - 0 ratings