0

I made powershell script that [1] accepts 2 arguments (aka parameters), [2] changes a file's modified date & time, and [3] writes something to host. The following command line works just fine in the powershell console, but triggers an error message when I run the same command line in a Windows cmd prompt (DOS) Window:

E:\Apps\UtilitiesByMarc\Change_DateTime_for_test1.bat_and_Hello_world_with_2_named_args_aaa.ps1 -dateTimeVarArg "01/11/2005 06:01:36" -file_dateTimeMod_fullname "E:\Apps\Delete01\test1.bat"

The following is the coding for the powershell script to which I gave the long name, 'Change_DateTime_for_test1.bat_and_Hello_world_with_2_named_args_aaa.ps1':

param ( [string]$dateTimeVarArg,  [string]$file_dateTimeMod_fullname)
Get-ChildItem  $file_dateTimeMod_fullname | % {$_.LastWriteTime = $dateTimeVarArg}
#Get-ChildItem  "E:\Apps\Delete01\test1.bat" | % {$_.LastWriteTime = $dateTimeVarArg}
$strString = "Hello World"
write-host $strString


function ftest{
$test = "Test"
write-host $test
}

ftest

When I run the command line shown above in a Windows DOS command prompt setting, I get the following error message:

Exception setting "LastWriteTime": "Cannot convert null to type "System.DateTime"."
At E:\Apps\UtilitiesByMarc\Change_DateTime_for_test1.bat_and_Hello_world_with_1_named_arg_aaa.ps1:6 char:50
+ ... "E:\Apps\Delete01\test1.bat" | % {$_.LastWriteTime = $dateTimeVarArg}
+                                       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], SetValueInvocationException
    + FullyQualifiedErrorId : ExceptionWhenSetting

I would like to know [1] how to alter the command line shown above (which works fine in the powershell console) so that it works in a Windows DOS command prompt setting, and [2] where I can learn more about why my command line triggers errors, and how to avoid them.
According to the output from the command "Get-Host | Select-Object Version", I am running version. 5.1.19041.1682.

Any tips would be much appreciated.

Marc B. Hankin
  • 771
  • 3
  • 15
  • 31
  • 3
    instead of hoping that the automatic type conversion works the way you want ... EXPLICITLY do it. take a look at `[datetime]::ParseExact()` and the other method for converting a _date string_ to a _datetime object_. – Lee_Dailey May 14 '22 at 08:04
  • 1
    As an aside: I assume mean `cmd.exe`, the legacy shell also known as Command Prompt. (DOS hasn't been in the picture since the first version of Windows NT, which all Windows versions since derive from). – mklement0 May 14 '22 at 17:18

1 Answers1

2

By default, you can not directly execute PowerShell scripts (.ps1 files) from cmd.exe, the Windows legacy shell, or from outside PowerShell altogether.

  • Attempting to do so opens the script file for editing instead, as does double-clicking .ps1 files from File Explorer / the desktop.

Executing .ps1 scripts from outside PowerShell itself requires use of the PowerShell CLI (powershell.exe for Windows PowerShell, pwsh for PowerShell (Core) 7+), which in your case translates to a call such as (additional CLI parameters may be called for):

powershell.exe -File E:\Apps\UtilitiesByMarc\Change_DateTime_for_test1.bat_and_Hello_world_with_2_named_args_aaa.ps1 -dateTimeVarArg "01/11/2005 06:01:36" -file_dateTimeMod_fullname "E:\Apps\Delete01\test1.bat"

As for what you tried:

The fact that you were able to execute your .ps1 from cmd.exe suggests that you changed the file-type definition for such files to execute via powershell.exe instead.

The fact that the arguments you tried to pass to the script were ignored - as implied by the error message you got - suggests that you used File Explorer's Open with shortcut-menu command to choose to open all .ps1 files with powershell.exe; said method does not support argument-passing.

There is a way to change the file-type definition to support argument-passing too, and it is detailed in this answer (section "Programmatic method").

Generally, however, I suggest not applying this customization, especially in batch files that must also be run by other users / on other machines, which cannot be expected to have the same customization in place.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • Thank you so much for the answer and for the referral to the Programmatic method. I can't wait to look it up. I hope it explains the [datetime]::ParseExact() stuff that Lee_Daily was kind enough to mention (alas, I haven't been able to figure out yet what he was referring to). I tried to buy you a few cups of coffee, but I couldn't see the captcha that prevented me from doing it. Can you help me with that? Is it possible for me to give you my email address? – Marc B. Hankin May 17 '22 at 19:30
  • I'm glad it was helpful, @MarcB.Hankin; my pleasure. What Lee recommended was to validate the `$dateTimeVarArg` value up front, via `[datetime]::ParseExact()`, to ensure that it is recognized as a date. However, you can more simply ensure this by typing your parameters as `[datetime]`; that is, replace `[string] $dateTimeVarArg` with `[datetime] $dateTimeVarArg` – mklement0 May 17 '22 at 19:57
  • As for the CAPTCHA problem, @MarcB.Hankin: unfortunately, I have no idea what the problem is - perhaps trying with a different browser helps? But, no worries if you can't get it to work: donations are completely optional, and do I appreciate the thought. – mklement0 May 17 '22 at 20:00