Windows double click not executing correct Powershell Script - windows

In my directory I have a file called "t1.ps1" and a second file called "t1 - something.ps1".
Both of them run fine when run fine, when executed via right click run with PowerShell or when executed directly in PowerShell, but when executed via double click or cmd it seems to always execute the first script.
For me it seems like the dash is the problem, but I was kinda surprised that windows did not just throw an error or just did nothing, but instead executed a different script.
Maybe this is a well known phenomena or i just have some jank settings, that made this happen, but I was kinda surprised about it.

By default, .ps1 files are NOT executed when you double-click them in File Explorer / on the Desktop - instead, they're opened for editing.
The fact that they are executed for you implies that you modified the default configuration:
However, the fact that double-clicking t1 - something.ps1 executes t1.ps1 instead implies that your configuration is flawed:
Specifically, it suggests that the file-name argument in the underlying powershell.exe command used for invocation lacks (effective) enclosing "..." quoting - as would happen if you had used File Explorer to interactively associate .ps1 files with powershell.exe.
See this answer for more information and a fix.

Related

Converting .ps1 to .bat doesn't cause cmd.exe to hit max character length - but why?

Based on a related question and some Googling/testing, it is pretty clear that the maximum length of a command line in cmd.exe is 8,191 characters. However...my script seems to successfully exceed that length, and I can't figure out why it works.
So I have:
A script written/saved as a .ps1
I'm converting it to a .bat using the method from Converting PowerShell to Batch
If I run the .bat - there don't seem to be any issues
If I try to echo the $encoded command or just remove #echo off before running the .bat - it is easy to see that the length/content of $encoded has been truncated...yet it works as expected
I realize this is a bit of a strange question since I'm trying to ascertain some kind of hidden truth about something that works vs. something that is broken, but I'd like to understand why it is working!
Note:
The primary reason I'm creating a .bat for my script is because I have a number of small 'programs' that I need to run on my work computer and share with others. Our company's execution policies don't allow running scripts, and it is much easier for others to use something I've written if it is a .bat since they won't need to understand/use PowerShell. They can just place the .bat in the right place, give it two clicks, and then sit back and relax until something happens.
EDIT: Here's the truncated command in the cmd.exe window. If I convert from Base64 back to readable text, it is clearly missing about half of the script. Yet - I'm not noticing any problems
The 8191-character limit applies to the interactive command line and calls to cmd.exe's CLI (via cmd /c)
It does not apply to commands invoked from batch files - there the limit is close to[1] 32KiB (32,768) characters.
However, it still seems to apply selectively to cmd.exe's internal commands, such as echo; by contrast, a call to an external program such as powershell.exe is not affected (though it is possible for specific external programs to have their own, lower limits).
As an aside:
As clever as the linked method of converting PowerShell scripts to batch files is, the resulting batch files lack support for arguments to be passed through to the PowerShell code, and adding support for that would be impractical (it would require Base64-encoding the arguments too, at invocation time, which isn't possible from a batch file except with the help of non-built-in utilities).
If your script / batch file is written to either require no arguments on invocation or to prompt for them interactively (as in your case), this limitation is not a concern.
However, you may want argument support for any of the following reasons:
To allow calling the batch file from cmd.exe (Command Prompt) with arguments.
To allow calling with arguments from other environments that support passing arguments, notably Task Scheduler and the Windows Run dialog (WinKey-R).
To make the batch file support drag-and-drop (which implicitly passes the dropped files' paths as arguments).
As for the overall reason to wrap PowerShell code in batch files:
Batch files (.cmd, .bat) can be launched directly, as if they were executables, system-wide.
By contrast, this is not supported for PowerShell scripts (.ps1), which from outside PowerShell must be invoked via an explicit call to the PowerShell CLI; note that systems may be configured to categorically prevent execution of .ps1 scripts - see next section.
If you do need argument support in your batch file, the best - but inconvenient - solution is to distribute two files:
the original *.ps1 file...
and a companion batch file, with the same base file name, to be placed in the same directory - which can be invoked from outside PowerShell - whose sole purpose is to invoke the *.ps1 file via powershell.exe with pass-through arguments.
E.g. foo.cmd would accompany foo.ps1, with the following - invariant - content:
#powershell.exe -NoProfile -File "%~dpn0.ps1" %*
Note:
Important: The above assumes that the effective PowerShell execution policy allows execution of script files (.ps1).
If you cannot make this assumption, place -ExecutionPolicy RemoteSigned before -NoProfile above (or, to deactivate all checks, -ExecutionPolicy Bypass), but note that an execution policy based on GPO (Group Policy Objects) may still prevent script execution.
To call PowerShell (Core) 7+ instead, use pwsh.exe instead of powershell.exe.
%~dpn0 expands to the full path of the enclosing batch file itself without its filename extension; appending .ps1 therefore targets the companion PowerShell script in the same directory; run cmd /c call /? for an explanation of the syntax.
%* passes any and all arguments received by the batch file on.
[1] In practice, the limits appear to be: 32,767 characters in batch files, and - lower by 3 chars. - 32,764 for Powershell (both on the command line / via the CLI and in *.ps1 scripts). In PowerShell, the limit may in practice be even lower than that, because PowerShell expands the names of executables it locates via $env:PATH to their full paths in the command lines constructed behind the scenes, which cmd.exe doesn't do.

How are commands on run dialog executed?

I have read somewhere, that the commands entered in the run dialog box are executed as if they are executed using the start command in CMD. Which I believed was the case (as i could executed applications registered at app paths key just by their name using run).
But i noticed a little bit of deviation from this behavior when I tried to run a command on run without extensions. To illustrate this behavior:-
I added .msc and .MSC (i am unaware of extension case sensitivity/insensitivity on windows) to the PATHEXT environment variable, such that it became like this:-
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.msc
After this I executed the following command in CMD, to start the Device Manager:-
start devmgmt
Which lead to execution of Device Manager.
But when i typed in the following command in run dialog box:-
devmgmt
it prompted me with an error stating:-
Well, If my statement in the first paragraph is correct, then why did I ended up with an error in the second case?
P.S.:- Upon googling about this issue before, i read several article which stated run prompt inherits PATHEXT values of CMD, for extension resolution. And if it doesn't, then there exists an policy (in gpedit or something) which makes the run prompt only possess the default PATHEXT values!! (correct me if i was wrong here)

Powershell Script converted to EXE via Win-PS2EXE can be run manually but errors out when run as a scheduled task

The application moves files from one directory to another, runs an exe, and then moves files from one directory to another.
When I run the application manually it works as expected.
However, when trying to run it as a scheduled task I get the following error: 3762504530
I did some researching and it appears it may have to do with the application trying to run interactively even when there is no user actually logged in.
I have tried to suppress outputs but that didn't seem to have any effect.
Without seeing the code i guess u use console output or similar...
If so change write-host to write-output or alias "echo" pipe it to log file if u want...
Also be sure that your script run "non interactive" (no prompts etc.)
Unchecking compile a graphic windows program (parameter -noConsole), remedied the error.

Run .exe anywhere in cmd without PATH variable

This works (Notepad++):
C:\Anywhere> start notepad++ hello.txt
And this works (SoX for removing silence in sounds):
C:\Anywhere> sox in.wav out1.wav silence 1 0.1 1%
Yet, my PATH variable includes neither (would send on request).
How can I do this with my program?
To run from everywhere.
Also, why doesn't Notepad++ work without the start command?
(I did this workaround by putting the .exe in C:\ and then simply calling C:\Anywhere> /myprogram but I'm still curious about the above.)
To get the indicated scenario where
you can start applications from anywhere using the start command (or the windows Run dialog) without including its parent folder in path variable,
but you can not start the application without the start command from any directory whithout including the full path to reach it (it is not in the path) or being located in the adecuated directory
the applications are included in the registry under the key
HKEY_CLASSES_ROOT\Applications
note: It is a "merged" view showing the combined contents of
HKEY_LOCAL_MACHINE\Software\Classes\Applications
HKEY_CURRENT_USER\Software\Classes\Applications
If you are not administrator to change the local machine configuration, you can always modify your user registry information to include the applications you need.
edited There is a second place in registry that will allow to include an application in the registry to be executed using start command, Run dialog or from anything that uses the ShellExecute or ShellExecuteEx API calls.
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\

batch file commands in powershell execute in a different command prompt

I'm using this new machine, so as usual I go and set the execution policy so that I can use my profile script, after doing that however powershell now opens all batch files in a new cmd.exe window.
I tried undoing this step but it's still the same so I think it has nothing to do with the script execution policy, also I still have the powershell window in which I originally set the execution policy and this one behaves normally, only new windows have this problem.
I may have installed some software, but nothing is related to windows, and I tried setting the PATH variable to its exact value in the working window but it does not work.
Batch files will open in a new window if the PATHEXT environment variable does not contain '.BAT' as one of the executable extensions.
To check the variable, enter the following at the PowerShell prompt: $env:PATHEXT

Resources