To add to Mathias R. Jessen's helpful answer:
I’m not trying to retrieve the $dateTime
variable, I’m just declaring it.
PowerShell has no concept of mere variable declarations (the only exceptions are parameter variables - see the relevant section of about_Functions
).
You can only "declare" a variable by implicitly creating it via assigning a value to it. (If the variable already exists, it will be updated.)
Since you want to use a type constraint, i.e. to limit the values the variable can hold to a given type, the value you assign must be of that type or convertible to it; in the simplest case:
[datetime] $dateTime = 0
Using [int]
value 0
has the same effect as [datetime]::MinValue
, as shown in Mathias' answer, given that 0
can be converted to the latter, due to PowerShell's flexible automatic type conversions (see this answer).
If you either use no type constraint or you use a type constraint with a .NET reference type, you can use $null
for initialization; e.g.:
# No type constraint, same as [object]
$newVar = $null
# .NET reference-type type constraint
[regex] $newVar = $null
if $null
is allowed as a value in a given situation, you can also use the following single-statement idiom for initializing a variable with varying values, so as to guarantee the variable's existence, based on using an if
statement as an expression; it wouldn't work with [datetime]
, so I'm omitting the type constraint here:
# Assigns the output from the `if` statement.
$dateTime =
if ($null -ne $registryEntry) {
[datetime] $registryEntry
}
That is, the if
statement's output becomes the value of $datetime
, which means that if $null -ne $registryEntry
is true, [datetime] $registryEntry
is assigned, and $null
otherwise.[1]
Note that a PowerShell variable without a type constraint is free to not only be initialized with a value of an type (including $null
), but to also later be updated with a value of any other type.
As an aside:
- Another surprising aspect of variable assignments in PowerShell is that they implicitly create a local variable with the given name, even if a variable by that name already exists, but was defined in an ancestral scope - see this answer.
As for what you tried:
In isolation, [DateTime]$dateTime
does the following:
It is a type cast, i.e. it tries to convert an existing $dateTime
variable to type [datetime]
and outputs the result:
That is, you are trying to retrieve the value of variable $dateTime
If $dateTime
does not exist yet...
... and you have Set-StrictMode
-Version 1
or higher in effect, you'll get the error you saw.
... otherwise, given that referencing non-existent variables defaults to $null
, your cast will be the equivalent of [datetime] $null
, which fails with Cannot convert null to type "System.DateTime"
In the event that such a cast succeeds its result is sent to the success output stream, which - in the absence of assigning it to a variable or passing it to a command - prints to the display by default, due to PowerShell's implicit output behavior, explained in the bottom section of this answer.
[1] Strictly speaking, it is the "Automation null" value that is assigned, which is an "enumerable null" that behaves like $null
in expression contexts, and like an empty enumerable in enumeration contexts - see this answer for details.