Error "TerminatorExpectedAtEndOfString" when execute a powershell code from a batch file?

I want to execute a powershell code with a batch file to take a screenshot from my desktop that i found it here Take a Screenshot of a User’s Desktop with PowerShell.

So,When i execute it as powershell script it works without any error and works for me 5/5 but when i take it as batch file like this i got this type of error that i don't know how to debug it correctly ?

Error "TerminatorExpectedAtEndOfString"

So if someone can explain me why and where this error comes from ?

Here is my batch code :

@echo off
Title Get a ScreenShot with Batch and Powershell
Call :ScreenShot
pause
::----------------------------------------------------------------------------------------------------------------------------
:ScreenShot
Powershell ^
$Path = "E:\ScreenCapture\";^
Add-Type -AssemblyName System.Windows.Forms;^
$screen = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds;^
$image = New-Object System.Drawing.Bitmap($screen.Width, $screen.Height);^
$graphic = [System.Drawing.Graphics]::FromImage($image);^
$point = New-Object System.Drawing.Point(0,0);^
$graphic.CopyFromScreen($point, $point, $image.Size);^
$cursorBounds = New-Object System.Drawing.Rectangle([System.Windows.Forms.Cursor]::Position,[System.Windows.Forms.Cursor]::Current.Size);^
[System.Windows.Forms.Cursors]::Default.Draw($graphic, $cursorBounds);^
$FileName = (Get-Date -F dd-MM-yyyy_HH_mm_ss)+".jpg";^
$FilePath = $Path$FileName;^
$FormatJPEG = [System.Drawing.Imaging.ImageFormat]::jpeg;^
$image.Save($FilePath,$FormatJPEG)
Exit /B
::------------------------------------------------------------------------------------------------------------------------

Solution 1:

May be you need:

  1. Use ^ in )

  2. Replace " to ' in $var='value'

  3. Use To.String in $((Get-Date).ToString('dd-MM-yyyy_HH_mm_ss')+'.jpg')


Test it in your command line:

Powershell $Path='E:\ScreenCapture\'; Add-Type -AssemblyName System.Windows.Forms;$screen = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds;$image = New-Object System.Drawing.Bitmap($screen.Width, $screen.Height^);$graphic = [System.Drawing.Graphics]::FromImage($image^);$point = New-Object System.Drawing.Point(0,0^);$graphic.CopyFromScreen($point, $point, $image.Size^);$cursorBounds = New-Object System.Drawing.Rectangle([System.Windows.Forms.Cursor]::Position,[System.Windows.Forms.Cursor]::Current.Size^);[System.Windows.Forms.Cursors]::Default.Draw($graphic, $cursorBounds^);$FileName = $((Get-Date^).ToString('dd-MM-yyyy_HH_mm_ss'^)+'.jpg'^);$FilePath = $Path+$FileName;$FormatJPEG = [System.Drawing.Imaging.ImageFormat]::jpeg;$image.Save($FilePath,$FormatJPEG^)

Test it in your bat file:

@echo off
Title Get a ScreenShot with Batch and Powershell
Call :ScreenShot
pause 
goto :eof
::----------------------------------------------------------------------------------------------------------------------------
:ScreenShot
Powershell $Path='E:\ScreenCapture\';^
Add-Type -AssemblyName System.Windows.Forms;^
$screen = [System.Windows.Forms.Screen]::PrimaryScreen.Bounds;^
$image = New-Object System.Drawing.Bitmap($screen.Width, $screen.Height^);^
$graphic = [System.Drawing.Graphics]::FromImage($image^);^
$point = New-Object System.Drawing.Point(0,0^);^
$graphic.CopyFromScreen($point, $point, $image.Size^);^
$cursorBounds = New-Object System.Drawing.Rectangle([System.Windows.Forms.Cursor]::Position,[System.Windows.Forms.Cursor]::Current.Size^);^
[System.Windows.Forms.Cursors]::Default.Draw($graphic, $cursorBounds^);^
$FileName = $((Get-Date^).ToString('dd-MM-yyyy_HH_mm_ss'^)+'.jpg'^);^
$FilePath = $Path+$FileName;$FormatJPEG = [System.Drawing.Imaging.ImageFormat]::jpeg;^
$image.Save($FilePath,$FormatJPEG^)

Solution 2:

The error comes from this line:

$FilePath = $Path$FileName;^

You should not concatenate variables to form a file path like that.
It would work if you surround it with double-quotes like this: $FilePath = "$Path$FileName";^, but far, FAR better is to use the Join-Path cmdlet:

$FilePath = Join-Path -Path $Path -ChildPath $FileName;^

or if you rather use .Net directly:

$FilePath = [System.IO.Path]::Combine($Path, $FileName);^