Page 1 of 2
Powershell2/bat hybrid?
Posted: 16 Apr 2014 03:51
by npocmaka_
(UPDATE-Just to ease search here)Here's best way to achieve this according to me:Code: Select all
<# :
@echo off
echo start ps
:: $cmdargs variable will contain the command line.
powershell $cmdargs="""%*""";$exp=$(Get-Content '%~f0') -replace """`n""",""";""" ;invoke-expression """$exp"""
exit /b 0
#>
Write-Host "Hello from PowerShell";
Write-Host "Hello from PowerShell"
(end of update.)Does anybody else have tried something in this direction?
The main impediment are the extension restrictions for both - cmd.exe and powershell.
I haven't find a way to drive the powershell to run a file with extension different from .ps1 .psc1 .psd1 .psm1 . One way is to use a temporary file and additional calling:
Code: Select all
@echo off
rem "installing" a caller.A files with .psc1 extension will be able to execute batch code but is not perfect as the %0 argument is lost
if not exist "c:\caller.bat" (
echo @echo off
echo copy "%%~nx1" "%%temp%%\%%~nx1.bat" /Y ^>nul
echo "%%temp%%\%%~nx1.bat" %%*
) > c:\caller.bat
:: to restore use assoc .psc1=Microsoft.PowerShellConsole.1
assoc .psc1=batps
ftype batps=c:\caller "%1" %*
and a test .psc1 file:
Code: Select all
set dummy="
goto :pscomment
"
<#
:pscomment
echo echo from bat
PowerShell -NoProfile -ExecutionPolicy Bypass -file "%~dpfnx1"
exit /b 0
#>
echo "echo from powershell"
Probably it can be done with temporary powershell caller . Any idea how powershell manages its extensions? And ideas for a better way to hybrid them?
Re: Powershell2/bat hybrid?
Posted: 16 Apr 2014 07:19
by siberia-man
Code: Select all
type filename.bat | powershell -c -
Re: Powershell2/bat hybrid?
Posted: 16 Apr 2014 08:15
by einstein1969
Hi,
I don't know... Little brainstorm on graphical managment too:
- But we can add %* to parameter of powershell?
[HKEY_CLASSES_ROOT\Microsoft.PowerShellScript.1\Shell\0\Command]
@="\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe\" \"-file\" \"%1\" %*"
- Or use the
"DropHandler" of wsh. Adding an shellext?
- Then Dinamic rotate the verb? 0->open etc.
einstein1969
Re: Powershell2/bat hybrid?
Posted: 16 Apr 2014 09:14
by Squashman
Gosh I wish I could remember all of this. Back in 2008 I got heavily into PowerShell and we added the drag and drop capability with a registry edit. I might have the REG files somewhere.
I am not sure about creating a hybrid file with batch and powershell in the same file.
Re: Powershell2/bat hybrid?
Posted: 18 Apr 2014 01:35
by npocmaka_
I think I've found a way I like - without tickling the registry and no temp/calling files (and inspirited from the siberia-man reply )
Code: Select all
@echo off
powershell "$cmdllineargs="""%*""";$expression=""""";$flag=0;$reader=[System.IO.File]::OpenText("""%~dpsnx0""");try{for(;;){$line=$reader.ReadLine();if($line -eq $null -or $line -eq """###end powershell###"""){break};if($flag -eq 1){$expression=$expression+""";"""+$line}if($line -eq """###start powershell###"""){$flag=1};}}finally{$reader.Close()};Invoke-Expression -Command $expression"
echo echo from bat
exit /b 0
###start powershell###
$a=1
$b=1
$a+$b
"is the sum of 1 and 1"
###end powershell###
still I'm not sure how robust and fast it is.And need to think about command line arguments.
Re: Powershell2/bat hybrid?
Posted: 18 Apr 2014 02:01
by npocmaka_
And my chimera script (because hybrid is too weak word ) [ jff ]
batch/jscript/powershell/vbscript script:
Code: Select all
@if (@X)==(@Y) @end/*JScript comment
@echo off
echo produced from bat
mshta vbscript:execute("CreateObject(""Scripting.FileSystemObject"").GetStandardStream(1).Write(""produced from vbscript""):Close") |findstr "^"
powershell "$expression=""""";$flag=0;$reader=[System.IO.File]::OpenText("""%~dpsnx0""");try{for(;;){$line=$reader.ReadLine();if($line -eq $null -or $line -eq """###end powershell###"""){break};if($flag -eq 1){$expression=$expression+""";"""+$line}if($line -eq """###start powershell###"""){$flag=1};}}finally{$reader.Close()};Invoke-Expression -Command $expression"
cscript /E:JScript /nologo "%~f0"
exit /b 0
###start powershell###
"produced from powershell"
###end powershell###
**/
WScript.Echo("Produced from jscript")
Re: Powershell2/bat hybrid?
Posted: 21 Apr 2014 14:44
by siberia-man
Hi
npocmaka_, could you test this code below with more complex scenarios? Does it work properly? Does it support command line arguments?
I have googled this issue and found few good ideas that inspired me to produce the following ugly but working code:
Code: Select all
@echo off
powershell -Command Invoke-Expression $( $i = ( $s = Get-Content '%~f0' ) ^| Select-String -Pattern '^^-=- POWERSHELL -=-$' ^| %% { $_.LineNumber }; if ( -not $i -or $i.length -gt 1 ) { Write-Host 'PoSH-in-CMD Embedding Error' -Foreground Red; exit 255; } [String]::Join( [Environment]::NewLine, $s[$i..$s.length] ) ) %*
goto :EOF
-=- POWERSHELL -=-
Write-Host "Hello from PowerShell"
The same code but the powershell invocation part has broken into several lines for better readability.
Code: Select all
@echo off
powershell -Command Invoke-Expression $( ^
$i = ( $s = Get-Content '%~f0' ) ^
^| Select-String -Pattern '^^-=- POWERSHELL -=-$' ^
^| %% { $_.LineNumber }; ^
if ( -not $i -or $i.length -gt 1 ) { ^
Write-Host 'PoSH-in-CMD Embedding Error' -Foreground Red; ^
exit 255; ^
} ^
[String]::Join( [Environment]::NewLine, $s[$i..$s.length] ) ^
) %*
goto :EOF
-=- POWERSHELL -=-
Write-Host "Hello from PowerShell"
The main goal was to make the resulting code simpler as much as possible. POSH is far from my favorite languages. Hope, if someone could improve the code above I would have added it to my collection for possible future usage.
connect.microsoft.com/PowerShell/feedback/details/724524/make-it-easier-to-wrap-powershell-scripts-in-batch-fileswww.daveamenta.com/2013-03/embed-powershell-inside-a-batch-file/www.daveamenta.com/2013-03/embed-powershell-inside-a-batch-file/UPDATE: Little improvement for more controlling of the code parsing to avoid some possible errors and make the script closer to humans.
Re: Powershell2/bat hybrid?
Posted: 21 Apr 2014 23:27
by npocmaka_
Hi siberia-man,
Here's more simplified method inspired from the embedded-in-batch-html that you've shown
:
Code: Select all
<# :
@echo off
echo start ps
powershell $cmdargs="""%*""";$exp=$(Get-Content '%~f0') -replace """`n""",""";""" ;invoke-expression """$exp"""
exit /b 0
#>
Write-Host "Hello from PowerShell";
Write-Host "Hello from PowerShell"
As for the command line - for now I'm defining additional variable cmdline -
$cmdline="""*%"""; that later can be used somehow in powershell part.
I've tested the
-=- POWERSHELL -=- script and it brokes every time when command line parameters are passed
Re: Powershell2/bat hybrid?
Posted: 22 Apr 2014 03:23
by siberia-man
Thanks for updates, npocmaka_. I knew that suggestion had problems.
Re: Powershell2/bat hybrid?
Posted: 25 Apr 2014 00:49
by npocmaka_
and with self-rename (I consider this as a risky technique):
Code: Select all
<# :
@echo off
echo start ps
( del /q /f "%0.ps1" >nul 2>&1
ren "%~dpfnx0" "%0.ps1"
call PowerShell -NoProfile -ExecutionPolicy Bypass -file "%~dpfnx0.ps1" %*
ren "%~dpfnx0.ps1" "%~nx0" )
exit /b 0
#>
Write-Host "Hello from PowerShell";
Write-Host "Hello from PowerShell"
Re: Powershell2/bat hybrid?
Posted: 03 Nov 2014 17:02
by siberia-man
Found few hours ago:
blogs.msdn.com/b/jaybaz_ms/archive/2007/04/26/powershell-polyglot.aspxstackoverflow.com/a/2611487/3627676In my opinions this solution is the best of known. Also you can find my attempt to compile all available solutions in one script. See this thread:
viewtopic.php?p=37780#p37780
Re: Powershell2/bat hybrid?
Posted: 04 Nov 2014 05:45
by npocmaka_
siberia-man wrote:Found few hours ago:
blogs.msdn.com/b/jaybaz_ms/archive/2007/04/26/powershell-polyglot.aspxstackoverflow.com/a/2611487/3627676In my opinions this solution is the best of known. Also you can find my attempt to compile all available solutions in one script. See this thread:
viewtopic.php?p=37780#p37780
Interesting indeed ,but the the main advantage according to me is the compatibility with powershell version 1.
the "@@"s make the code harder for reading and it again uses again the same idea -Invoke-Expression and new lines replaced with ";"
Re: Powershell2/bat hybrid?
Posted: 04 Nov 2014 06:16
by siberia-man
Yep. Seems there are no better ways to hybridize cmd and powershell (or embed powershell into a batch file). Anyway this solution keeps ability for piping and allows using of command lines arguments through $args (I guess this is standard variable in powershell).
Re: Powershell2/bat hybrid?
Posted: 22 Mar 2015 17:40
by siberia-man
siberia-man wrote:Seems there are no better ways to hybridize cmd and powershell (or embed powershell into a batch file).
I am glad to say that I have been wrong. One man from Russian
Gray forum and I have had private discussion regarding ps1+bat hybrid. This discussion gave birth the better solution how to hybridize powershell scripts within batch file.
there is list of advantage
1. the code is little bit shorter now (approx. on 50-60 bytes)
2. the trick with $input variable has been removed because scriptblock allows to pass data from STDIN directly (invoke-expression doesn't allow).
3. with scriptblock it is possible to describe input arguments within "param()" block.
4. it is possible to wrap arguments with double quotes " (there is only option in dos) and single quotes ' (that is possible in powershell)
There is example for tests (just save it as batch file):
Code: Select all
<# :
@echo off
setlocal
set "POWERSHELL_BAT_ARGS=%*"
if defined POWERSHELL_BAT_ARGS set "POWERSHELL_BAT_ARGS=%POWERSHELL_BAT_ARGS:"="""%"
endlocal & powershell -NoLogo -NoProfile -Command "$input | &{ [ScriptBlock]::Create( ( Get-Content \"%~f0\" ) -join [char]10 ).Invoke( @( &{ $args } %POWERSHELL_BAT_ARGS% ) ) }"
goto :EOF
#>
$args;
Re: Powershell2/bat hybrid?
Posted: 25 Mar 2015 02:09
by npocmaka_
Never heard of scriptblock before.Nice feature and pretty useful in this case.
A little bit more info:
http://www.padisetty.com/2014/05/all-ab ... block.html