Page 1 of 1
Powershell comment
Posted: 07 May 2020 21:12
by ImAhNoBoDy
Is there a way to write a comment in powershell, but in a batch script? Unfortunately I can't use polyglot for this.
Example that doesn't work, but to show the idea
Code: Select all
powershell -command "& {"^
#this is a comment
Get-service^
"}"
I can only get the comment to work if I use a comment block, but I don't really want to use it.
Code: Select all
powershell -command "& {"^
<#this is a comment#^>;^
Get-service^
"}"
Re: Powershell comment
Posted: 08 May 2020 07:23
by aGerman
The only other possibility that I can think of is to have the comment on the CMD side rather than on the PS side. Typically you would use a variable that expands to nothing in hybrid scripts like that.
Code: Select all
powershell -command "& {"^
%= this is a comment =%
Get-service^
"}"
Steffen
Re: Powershell comment
Posted: 08 May 2020 12:01
by jfl
The # comment does not work the way you did, because it's a line comment, and the PowerShell command you generated was all on one line for PowerShell.
To use such a line comment, you need to generate a PowerShell script that contains multiple lines.
This is akin to what we do for generating multi-line batch macros:
Code: Select all
@echo off
set LF=^
%# First empty line - Do not remove #%
%# Second empty line - Do not remove #%
set ^"LF1=^%LF%%LF%"
set ^"LF2=^^^%LF1%%LF1%^%LF1%%LF1%"
set ^"LF3=^^^^^^%LF2%%LF2%^^%LF2%%LF2%"
set ^"\n=%LF3%^^^" &:# Insert a LF and continue macro on next line
PowerShell -Command ^& { %\n%
# This is a comment %\n%
$PSVersionTable %\n%
}
exit /b
The %\n% macro above generates line feeds and continuation characters.
So as far as the batch is concerned, this is all a single command on one line; And for PowerShell this is a 4-line script.
And this way the # line comment works:
Code: Select all
C:\JFL\Temp>test.bat
Name Value
---- -----
PSVersion 5.1.19041.1
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.19041.1
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
C:\JFL\Temp>
Re: Powershell comment
Posted: 09 May 2020 11:10
by ImAhNoBoDy
jfl wrote: ↑08 May 2020 12:01
The # comment does not work the way you did, because it's a line comment, and the PowerShell command you generated was all on one line for PowerShell.
To use such a line comment, you need to generate a PowerShell script that contains multiple lines.
This is akin to what we do for generating multi-line batch macros:
Code: Select all
@echo off
set LF=^
%# First empty line - Do not remove #%
%# Second empty line - Do not remove #%
set ^"LF1=^%LF%%LF%"
set ^"LF2=^^^%LF1%%LF1%^%LF1%%LF1%"
set ^"LF3=^^^^^^%LF2%%LF2%^^%LF2%%LF2%"
set ^"\n=%LF3%^^^" &:# Insert a LF and continue macro on next line
PowerShell -Command ^& { %\n%
# This is a comment %\n%
$PSVersionTable %\n%
}
exit /b
The %\n% macro above generates line feeds and continuation characters.
So as far as the batch is concerned, this is all a single command on one line; And for PowerShell this is a 4-line script.
And this way the # line comment works:
Code: Select all
C:\JFL\Temp>test.bat
Name Value
---- -----
PSVersion 5.1.19041.1
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.19041.1
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
C:\JFL\Temp>
So how is this interpreted and why does it work? Is there an article I can read about this? I've never seen anything like this hack before.
I think when \n is expanded it would be 4 or 8 line feeds?
Re: Powershell comment
Posted: 09 May 2020 17:58
by aGerman
Indeed the creation of the necessary escaped line feed can be simplified.
Code: Select all
@echo off
(set \n=^^^
%= This creates an escaped Line Feed - DO NOT ALTER =%
)
PowerShell -Command ^& { %\n%
# This is a comment %\n%
Get-Service %\n%
}
pause
You can read up in this thread
viewtopic.php?f=3&t=8769#p57659
Steffen
Re: Powershell comment
Posted: 09 May 2020 18:39
by Eureka!
"Plan B" (or C?):
Code: Select all
(
echo Get-Service
echo #this is a comment
echo ls
) | powershell -command -
Notes:
- Get-Service without the trailing S
- The & should be inside the scriptblock
- I doubt if scriptblocks are even supported from a CMD prompt.
Re: Powershell comment
Posted: 09 May 2020 21:07
by ImAhNoBoDy
aGerman wrote: ↑09 May 2020 17:58
Indeed the creation of the necessary escaped line feed can be simplified.
Code: Select all
@echo off
(set \n=^^^
%= This creates an escaped Line Feed - DO NOT ALTER =%
)
PowerShell -Command ^& { %\n%
# This is a comment %\n%
Get-Service %\n%
}
pause
You can read up in this thread
viewtopic.php?f=3&t=8769#p57659
Steffen
At first I was skeptical that this would work cause I thought I had tried this already, but looking closely at your code I see you used three carets instead of my attempted one:
Code: Select all
set LF=^
powershell -command "& {"%lf%
#this is a comment%lf%
Get-service%lf%
"}"
Note: I'll be using [^& {] instead from now one.
Thank you everyone for all your help. Definitely made my work easier. I hate that I can't use polyglot/cmd & powershell hydrid cause fireeye flags it as malicious.
Re: Powershell comment
Posted: 13 May 2020 04:20
by jfl
@aGerman:
Hi Steffen,
There's an important difference between your %\n% macro and mine. (Beyond the fact that I generated mine with an overly complex sequence)
- Mine expands to <LF>^
- Yours expands to ^<LF>
Obviously both work for generating a one-line batch command, which in turn creates a multi-line PowerShell command.
But I don't understand how yours allows this, since the ^ continuation character does not end up being the last character on each batch line.
So why are the consecutive batch lines glued together with your macro too?
Jean-François