1

The script below finds folders older than 30 days. I just want to add a simple IF statement to say "There are not folders older than 30 days" if there are not any. But I am not sure how to do that Thank you

$Test = Get-ChildItem "\\Server\XFER\Cory" -Directory | 
    Sort LastWriteTime -Descending |
    Where-Object {($_.LastWriteTime -lt (Get-Date).AddDays(-30))} |
    Select-Object Name, LastWriteTime 

mklement0
  • 382,024
  • 64
  • 607
  • 775
Miguel
  • 91
  • 1
  • 1
  • 11
  • 1
    If you want folders that are just older than 30 days, you should use `CreationTime`, `LastWriteTime` is for modification. Other than that you just need to check your `$Test` variable - `if ($null -eq $Test) { #do stuff }`. – Ash Jun 08 '21 at 20:55
  • 2
    `if(-not $Test){ "There are not folders older than 30 days" }` – Santiago Squarzon Jun 08 '21 at 20:55

1 Answers1

1

Your question boils down to this:
In PowerShell, how can I determine if a command or expression produced any output?

In almost all cases, the following is sufficient, as Ash suggests:

$Test = ...  # ... represents any command or expression
if ($null -eq $Test) { 'no output' }

If you know that the command or expression - when it does produce output - only ever emits non-numeric and non-Boolean objects, you can simplify to the following, as Santiago Squarzon suggests, relying on PowerShell's implicit to-Boolean coercion logic, summarized in the bottom section of this answer:

$Test = ...  # ... represents any command or expression
if (-not $Test) { 'no output' }

If you're dealing with an (unusual) command that outputs a collection (array) as a single object (as opposed to enumerating the collection and outputting each element separately, which is the normal pipeline behavior) and you want to treat an empty collection object as lack of output too:

$Test = ...  # ... represents any command or expression
# Caveat: Due to a bug, only works robustly with 
#         Set-StrictMode turned off (the default) 
#         or Set-StrictMode -Version 1 (not higher).
if ($Test.Count -eq 0) { 'no output' } 

Note that this works even with $null output and a scalar output object (a single, non-collection object). In the interest of unified treatment of scalars and collections (arrays), PowerShell adds a .Count property even to scalars that themselves do not have it, so that scalars can be treated as if they were a single-element collection, also with respect to indexing; e.g. (42).Count is 1, and (42)[0] is 42; however, note that $null.Count is 0. Such PowerShell engine-supplied type members are called intrinsic members.

Caveat: Due to a long-standing bug - reported in GitHub issue #2798 and still present as of PowerShell 7.2 - accessing the intrinsic .Count property on objects that don't natively have it causes a statement-terminating error if Set-StrictMode -Version 2 or higher is in effect.


However, the tests above do not allow you to distinguish between no output at all and a (single) $null value, which requires the following approach - though do note that actual $null output is unusual in PowerShell:[1]

$Test = ...  # ... represents any command or expression
if ($null -eq $Test -and @($Test).Length -eq 0) { 'no output' }

This obscure test is necessary, because no output in PowerShell is represented by the [System.Management.Automation.Internal.AutomationNull]::Value] singleton, which behaves like $null in expression contexts, but not in enumeration contexts such as in a pipeline, including with @(...), the array-subexpression operator, which returns an empty array for [System.Management.Automation.Internal.AutomationNull]::Value] (element count 0) and a single-element array for $null.

While making the distinction between $null and [System.Management.Automation.Internal.AutomationNull]::Value often isn't necessary, there are definitely cases when it is, given that their enumeration behavior differs. Being able to distinguish via a simple test such as $Test -is [AutomationNull] is the subject of GitHub proposal #13465.


[1] Returning $null from PowerShell commands (cmdlets, scripts, functions) is best avoided; instead, simply omit output commands. However, .NET API methods may still return $null and object properties may contain $null (even [string]-typed ones, and even in PowerShell class definitions - see GitHub issue #7294).

mklement0
  • 382,024
  • 64
  • 607
  • 775