Windows Shell. Restoring Orig Files - powershell

After a quick google search I found this link: Mercurial: simple way to revert .orig files?, with the following line of code in the comment:
for /f %i in ('dir /s /b *.orig') do #copy %i %~dpni
In powershell, I tried running it, but I got the following error: Missing opening ( after kyeword for.
Is powershell not the correct way to run this code or is the syntax incorrect?
I am trying to revert my orig files back to their original version (get rid of the .orig extension). I am using windows so BASH is not an easy option.

The comment that snippet came from suggests that the environment you can run that line in is the "Windows command prompt with Command Extensions."
You can create that environment like so: cmd /e:on. It didn't seem like using powershell was the intention, but you could type cmd /e:on into the powershell console and get that environment.
PS C:\> cmd /e:on
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\> Command Prompt Input is Valid Here
You received that error because that syntax is incorrect for powershell -- for statements expect parameters in parenthesis. It should work once you're in the appropriate shell, though.

Related

Can't get ssh-keygen to complete using Powershell [duplicate]

I have recently started working with Kubernetes and Docker and still new with how it all works. I have made a ps1 script to run all the steps I need to do to build image and execute image on Kubernetes.
What I see is all steps work fine on ISE (except this one: "kubectl exec -it test-runner pwsh"). For this step alone, I have to run it on another PowerShell window.
When I run this step in ISE, the script keeps running without ever giving any error or stopping.
Does anyone know if its a limitation with Kubernetes working on ISE or if there is a workaround to make it work?
Working with ISE is quick and saves me tons of time, so this really makes a difference when I have to copy, paste, enter this each time in a separate PowerShell window.
Thanks in advance for your help!
P.S: I looked at other suggested similar questions/answers and none of them seem to be related to Kubernetes not working on ISE. Hence this question.
command:
kubectl exec -it test-runner pwsh
Expected (and actual when running from PowerShell console):
----------------------
PS C:\windows\system32> kubectl exec -it test-runner pwsh
PowerShell 6.2.2
Copyright (c) Microsoft Corporation. All rights reserved.
https://aka.ms/pscore6-docs
Type 'help' to get help.
PS /test>
-----------------------------
Actual (when running from PowerShell ISE):
PS C:\SourceCodeTLM\Apollo> kubectl exec -it test-runner pwsh
PowerShell 6.2.2
Copyright (c) Microsoft Corporation. All rights reserved.
https://aka.ms/pscore6-docs
Type 'help' to get help.
(with a blinking cursor and script running without breaking and changing to the new path)...
-----------------------------------------------
The PowerShell ISE doesn't support interactive console applications, which notably means that you cannot start other shells from it.
The ISE tries to anticipate that problem by refusing to start well-known shells.
For instance, trying to start cmd.exe fails with the following error message:
Cannot start "cmd". Interactive console applications are not supported.
To run the application, use the Start-Process cmdlet or use
"Start PowerShell.exe" from the File menu.
Note:
pwsh.exe, the CLI of PowerShell (Core) 7+, is not among the well-known shells, which indicates the ISE's obsolescent status. It is being superseded by Visual Studio Code with the PowerShell extension. Obsolesence aside, there are other pitfalls - see the bottom section of this answer.
However, it is impossible for the ISE to detect all cases where a given command (ultimately) invokes an interactive console application; when it doesn't, invocation of the command is attempted, resulting in obscure error messages or, as in your case, hangs.
As the error message shown for cmd.exe implies, you must run interactive console applications outside the ISE, in a regular console window.
From the ISE you can use Start-Process to launch a program in a new, regular console window; in the case at hand:
Start-Process kubectl 'exec -it test-runner pwsh'
Alternatively, run your PowerShell sessions outside the ISE to begin with, such as in a regular console window, Windows Terminal, or in Visual Studio Code's integrated terminal.
After digging out, I found a way to interact with the interactive console applications.
we can use SendKeys('key_here') to specific application.
You could open a command window from PowerShell and send the command to open the shell.
Start-Process PowerShell -Wait "-NoProfile -ExecutionPolicy Bypass -Command `"kubectl exec helloworld-web-8495f4c888-jw2tg -n local-v1 -it -- /bin/bash`""

Why does my 7zip command now get a "Cannot find archive name" error

Without problems I've been using the following 7zip command on Appveyor CI in a .bat file using 7zip 21.07 running on Windows Server 2019, and also with earlier Windows Server & 7z versions:
7z -owin-oclcpuexp-2021.12.9.0.24_rel e win-oclcpuexp-2021.12.9.0.24_rel.zip
The identical command in a Powershell script on GitHub Actions CI using 7zip 22.01 running on Windows Server 2022 gets this error:
7-Zip 22.01 (x64) : Copyright (c) 1999-2022 Igor Pavlov : 2022-07-15
Command Line Error:
Cannot find archive name
I've tried running it from cmd.exe
cmd.exe /C 7z -owin-oclcpuexp-2021.12.9.0.24_rel e win-oclcpuexp-2021.12.9.0.24_rel.zip
and also tried putting the command before the switch
7z e win-oclcpuexp-2021.12.9.0.24_rel.zip -owin-oclcpuexp-2021.12.9.0.24_rel
but I still get the error. win-oclcpuexp-2021.12.9.0.24_rel.zip is present in the current directory and has the expected size.
EDIT: For the sake of completeness I should say that the name is taken from an environment variable. The actual command has $env:OPENCL_SDK_NAME instead of win-oclcpuexp-2021.12.9.0.24_rel. In the .bat file the reference was, of course, %OPENCL_SDK_NAME%. I have verified that the variable has the expected value.
Why did this command stop working?
I was able to reproduce the problem on my local Windows box so with the help of ProcessMonitor, thanks Lex Li, I figured out what was happening. It's all down to Powershell handling of variable expansion. As a relative newbie to PS and long time bash/sh user I find PS's behavior surprising.
The actual command I had was
7z -o$env:OPENCL_SDK_NAME e $env:OPENCL_SDK_NAME.zip
I also had a preceding curl command using the same env. var. Because this worked it helped mask the issue.
curl.exe -s -S -L -O $env:OPENCL_SDK_HOME/$env:OPENCL_SDK_NAME.zip
So what is it? There are actually 2 problems:
With -o$env:FOO the variable is not expanded so the application sees exactly -o$env:FOO.
When seeing $env:FOO.zip PS substitutes an empty string, hence the Cannot find archive name error. I would never have spotted this without ProcessMonitor as the similar expansion in thecurl command was working. It turns out that PS does expand the variable in the case of foo/$env:FOO.zip. Utterly bizarre.
My fix is to add quotes around the variables. For safety I added them to the curl command as well. I don't know if there are other better ways of fixing this.
curl.exe -s -S -L -O "$env:OPENCL_SDK_HOME/$env:OPENCL_SDK_NAME.zip"
7z -o"$env:OPENCL_SDK_NAME" e "$env:OPENCL_SDK_NAME.zip"

How do I include "x64" in path name when starting powershell with a CD command?

I'm trying to automatically change the directory when powershell starts from an application which provides the location to change to.
It works for most of the paths but when I have a path with "(x64)" (I imagine that "(x86)" would behave in the same way) it fails with this error message:
First error
# Using the -NoExit just to see if the code works correctly,
# will be removed when it does.
powershell -NoExit "CD ""D:\My (x64) path"""
I have tried changing it in different ways but always get the same error. Here is what I have tried (or at least all methods I can remember I've tried):
1. powershell -NoExit "CD `"D:\My (x64) path`""
2. powershell -NoExit "CD D:\My (x64) path"
3. powershell -NoExit "CD `"D:\My `(x64`) path`""
If I instead use:
powershell -NoExit "CD ""D:\My ('x64') path"""
or:
powershell -NoExit "CD ""D:\My '(x64)' path"""
The error I get changes to this:
Second error
All changes made in the path (D:\My (x64) path) as seen in the three latest examples are also impractical since the path is provided by another application and I don't know what it is in advanced (which means I would have to write a much longer code to search for those occasions in the path).
Hope you understand my problem and that you can help me, otherwise just ask and I will try to explain it more.

How to determine if I'm in powershell or cmd?

I've been playing with OpenSSH on Windows and it looks like the normal Unix aliases are missing. I'm not sure whether it's starting powershell or cmd when I log in to a Windows machine via SSH. What's the correct way to see the currently running shell on Windows?
All credit goes to PetSerAl, this had to be posted as an aswer:
(dir 2>&1 *`|echo CMD);&<# rem #>echo PowerShell
Within Win32-OpenSSH this command also works, and outputs CMD.
NB : Win32-OpenSSH seems a bit limited, cd is not recognized on my system.
I'd like to expand on #sodawillow's answer to also distinguish between using Powershell (powershell.exe) known as Desktop and PWSH (pwsh.exe) known as Core.
(dir 2>&1 *`|echo CMD);&<# rem #>echo ($PSVersionTable).PSEdition
# Returns one of: CMD, Core, Desktop
This works in all instances where a sub-shell is not instantiated. What that means is that it does not work from opening a default sub-process in Python, as it always uses CMD when interacting with windows. This is actually set by the Windows environment variable: ComSpec always pointing to C:\Windows\system32\cmd.exe.
For example:
(Starting the python interpreter from a pwsh shell.)
>>> import os, subprocess
>>> c="(dir 2>&1 *`|echo CMD);&<# rem #>echo($PSVersionTable).PSEdition"
>>> subprocess.call(c,shell=True)
CMD
For other Python shell detection schemes, please see this good post.
UPDATE: 2020-05-01
I managed to get the above working, but with the obnoxious side effect of always loading the powershell profile, before executing. The trick was to specify execute=<path-to-powershell-exe> like this:
(Start a python CLI.)
import os, subprocess
c="(dir 2>&1 *`|echo CMD);&<# rem #>echo($PSVersionTable).PSEdition"
e="C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"
subprocess.call(c, shell=True, executable=e)
# output:
# <blah blah from profile>
# Desktop
# 0
I have not been able to circumvent the powershell profile issue. But apparently it is something being worked on. See here and here.

Creating junctions in Windows for Hudson build

I have a job in Hudson that builds on a Windows XP slave. I know that symlinks are not possible (directly) in Windows XP, and so I am trying to use junctions instead. I wrote a batch script:
#echo off
if "%1" == "" goto ERROR1
if "%2" == "" goto ERROR2
goto create
:create
echo Creating junction for %1 at %2
if exist %2 junction -q -d %2
md %2
junction -q %2 %1
goto :eof
:ERROR1
echo Source directory not specified
goto :eof
:ERROR2
echo Destination directory not specified
goto :eof
In my job, when I call this script, it hangs at the line echo Creating junction for %1 at %2. This is my Hudson "Execute Windows Batch Command":
call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x64
copy C:\Data\Scripts\slink.bat .
call slink.bat C:\Data\3rdParty64 3rdParty
call slink.bat %WORKSPACE%\..\..\..\tds.core\label\%label% tds.core
...and this is the output:
C:\Data\Hudson\dev\workspace\Common_Windows\label\DFWW9202>call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x64
Setting environment for using Microsoft Visual Studio 2010 x64 tools.
1 file(s) copied.
Creating junction for C:\Data\3rdParty64 at 3rdParty
Any ideas? (if this is not the right site, please redirect..sorry and thanks!)
The best way to solve this is to: pass /accepteula command-line argument to the junction command.
eg:
junction -q %2 %1 /accepteula
This procedure did not work for me, but I did narrow down the real problem.
Some background: The very first time the "junction.exe" program is ever run by a user on a Windows machine, it throws up an End User License Agreement (EULA) with an Agree button. Once that user clicks on the "Agree" button, they can use the utility normally.
junction.exe was stalling for Hudson because the service was being run as "Default User", and "Default User" never clicked on the Agree button. This caused junction.exe to invisibly and indefinitely stall, waiting for that click, which of course will never arrive.
The way we fixed it was to configure the system to run the Hudson service as a well known account, instead of as Default User. Then we logged into the Windows machine as that account, ran junction.exe, clicked on the Agree button, then logged off.
junction.exe has worked nicely in Hudson ever since.
The other option is to move to Windows Server 2008. I'm told that version has the junction functionality in a new "mklink" utility that comes built into the OS itself, and does not have a EULA.
Never mind, found it if anyone else is looking - I changed the "call" to slink.bat to "start /B", and added full paths, so:
call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x64
start /B C:\Data\Scripts\slink.bat C:\Data\3rdParty64 3rdParty
start /B C:\Data\Scripts\slink.bat slink.bat %WORKSPACE%\..\..\..\tds.core\label\%label% tds.core