File path with spaces not working in batch file - powershell

I am trying to cat a text file containing a PowerShell script from a .bat file into PowerShell running within the command line.
It's kind of a workaround to start a PowerShell script on startup without having permission on the system.
It works perfectly fine until I try paths with spaces. Does someone know how to make this work?
I searched and tried many solutions (see 3,4,5,6) but either this is a very specific case, or I am doing something wrong. My knowledge of scripts in general is lacking some, but I'm trying my best. Please use simple language in your answer.
This works
#echo off
powershell "cat -raw C:\examplenospace\test.txt | invoke-expression"
This works
#echo off
set "file=C:\examplenospace\test.txt"
powershell "cat -raw %file% | invoke-expression"
Not working
#echo off
set "file=C:\example with space\test.txt"
powershell "cat -raw %file% | invoke-expression"
This also doesn't work of course
#echo off
powershell "cat -raw "C:\example with space\test.txt" | invoke-expression"
Also doesn't work
#echo off
powershell ""cat -raw "C:\example with space\test.txt" | invoke-expression"
I tried many variations, nothing seems to work
#echo off
powershell "cat -raw \"\"C:\example with space\test.txt" | invoke-expression"
How can I make it work?

#Compo thank your for your answer, this worked straight away, both of them!
#%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -Command "Get-Content -LiteralPath 'C:\example with space\test.txt' -Raw | Invoke-Expression"
#%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -Command "Get-Content -LiteralPath "C:\example with space\test.txt" -Raw | Invoke-Expression"

Related

Comments in a long-line PowerShell code in a Batch script

I have a large batch script to which I need to add some Powershell code for some regex capture which I am unable to do in batch. I was hoping to have this code integrated in my batch script using the method outlined in Link, but when adding comments I get a missing } error. I've simplified my code just to be able to replicate the issue.
This, without a comment, works:
#echo OFF
setlocal enabledelayedexpansion enableextensions
set "var=variable"
PowerShell ^
foreach ($file in Get-ChildItem -File -Include *.* -Recurse) ^
{ ^
Write-Host $file; ^
Write-Host $env:var; ^
}
%End PowerShell%
echo Test
pause > nul
This, with a comment, does not work:
#echo OFF
setlocal enabledelayedexpansion enableextensions
set "var=variable"
PowerShell ^
foreach ($file in Get-ChildItem -File -Include *.* -Recurse) ^
{ ^
#Comment ^
Write-Host $file; ^
Write-Host $env:var; ^
}
%End PowerShell%
echo Test
pause > nul
I have tried escaping the # in a few different ways, but no matter what I do, I get the error message
Missing closing '}' in statement block or type definition.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : MissingEndCurlyBrace
The only difference is the comment. Does anyone know how to get around this? (using this long-line method that is). If it's not at all possible I guess I will go for base64 encoding
What works for me if when I do the comment line in between <# and #> as if it were a comment block.
Then of course for cmd you need to escape the < and > characters with a ^:
^<# Comment #^> ^
P.S. Don't forget that using Get-ChildItem without a -Path or -LiteralPath, the cmdlet will use PowerShell's current working folder ($pwd), which is most probably not the same as the current working path cmd uses..
This an hybrid code Batch and Powershell exmaple is just to show you how to put a multiline comment block with powershell and how to execute Batch section and powershell section :
<# : Batch Script Section
#rem # The previous line does nothing in Batch, but begins a multiline comment block in PowerShell. This allows a single script to be executed by both interpreters.
#echo off
Title Wifi Passwords Recovery by Hackoo 2022 & Mode 70,3
setlocal
cd "%~dp0"
Color 0B & echo(
Echo( Please Wait a while ... Getting SSID and Wifi Keys ...
Powershell -executionpolicy bypass -Command "Invoke-Expression $([System.IO.File]::ReadAllText('%~f0'))"
EndLocal
goto:eof
#>
# Powershell Script Section begin here...
# here we execute our powershell commands...
$Var=netsh wlan show profiles|SLS "\:(.+)$"|%{$SSID=$_.Matches.Groups[1].Value.Trim(); $_}|%{(netsh wlan show profile name="$SSID" key=clear)}|SLS "Conte.*:(.+)$"|%{$pass=$_.Matches.Groups[1].Value.Trim(); $_}|%{[PSCustomObject]#{SSID=$SSID;PASSWORD=$pass}}
$var | Format-List | Out-File -FilePath ".\WifiKeys_List_Format.txt"
$var | ConvertTo-Json | Out-File -FilePath ".\WifiKeys_JSON_Format.txt"
$var | OGV -Title "Wifi Passwords Recovery by Hackoo 2022" -wait
ii ".\WifiKeys_JSON_Format.txt"
ii ".\WifiKeys_List_Format.txt"

Path issue with passing a command from Autohotkey to PowerShell

Mypath := "C:\temp\example1.txt"
Run, powershell -command "get-content -path %Mypath% | Set-Clipboard"
The above works just fine, content is copied to the clipboard by PowerShell but when I do the same thing but with a file that has a space in its file name it fails to run in PowerShell.
Running below
Mypath := "C:\temp\example 1.txt"
Run, powershell -command "get-content -path %Mypath% | Set-Clipboard"
I get this error in PowerShell
Get-Content : A positional parameter cannot be found that accepts argument '1.txt'.
I have also tried to use double quotes on each side and use Autohotkeys escape symbol like so:
Mypath = "`"C:\temp\example 1.txt`""
Run, powershell -command "get-content -path %Mypath% | Set-Clipboard"
As well as
Mypath = ""C:\temp\example 1.txt""
Run, powershell -command "get-content -path %Mypath% | Set-Clipboard"
But on both occasions, PowerShell throws this error;
The string is missing the terminator: ".
What am I doing wrong? any help would be appreciated.
This is quite weird but it is possible to get it working. It's really one escape hell.
Lets go through what's wrong with each of your attempts.
Mypath := "C:\temp\example 1.txt"
Run, powershell -command "get-content -path %Mypath% | Set-Clipboard"
Here you're not using the legacy syntax to assign a value to the variable Mypath, as you should.
It's a good thing to not be using the legacy syntax anymore.
However, since you're not using the legacy syntax, and are using the modern assigning operator :=(docs), you don't have any extra quotes " around the string.
So you're executing PowerShell with the following switches:
-command "get-content -path C:\temp\example 1.txt | Set-Clipboard".
And as you were able to guess, this is wrong because your filename is not quoted.
Mypath = "`"C:\temp\example 1.txt`""
Run, powershell -command "get-content -path %Mypath% | Set-Clipboard"
Here you're again using legacy syntax. So any string is interpreted literally. Therefore, firstly there is no reason to try to escape the quotes ", and secondly you don't escape quotes in AHK with `.
So, in this attempt you're executing PowerShell with the following switches:
-command "get-content -path ""C:\temp\example 1.txt"" | Set-Clipboard".
And this is no good, because first ""s get evaluated to a single ", and then you have
-command "get-content -path "C:\temp\example 1.txt" | Set-Clipboard"
which has unescaped quotes " inside another quotes, so that's no good.
Mypath = ""C:\temp\example 1.txt""
Run, powershell -command "get-content -path %Mypath% | Set-Clipboard"
And then here you have the exact same issue as in the previous one. Because, as we established, you don't escape quotes with `. This code is the exact same as the one above.
So, how should it be done?
You either need one more pair of escaped quotes " around the file path, or then just use a single quote for the inner quotes.
So in legacy syntax you'd want either:
Mypath = """"C:\temp\example 1.txt""""
Run, powershell -command "get-content -path %Mypath% | Set-Clipboard"
or
Mypath = 'C:\temp\example 1.txt'
Run, powershell -noexit -command "get-content -path %Mypath% | Set-Clipboard"
And in the modern expression syntax, you'd want either:
Mypath := """""""""C:\temp\example 1.txt"""""""""
Run, % "powershell -noexit -command ""get-content -path " Mypath " | Set-Clipboard"""
or
Mypath := "'C:\temp\example 1.txt'"
Run, % "powershell -noexit -command ""get-content -path " Mypath " | Set-Clipboard"""

Syntax error in powershell command in windows

I try to run two commands in a bat file using the powershell. My goal is to transform a file to a utf8 format. How can I achieve that?
Here is what I have so far:
PowerShell -Command (Get-Content 'ZipCode.csv' | Out-File 'ZipCode1.csv' -Encoding utf8)
I get the following error: "out-file is not recognized as an internal or external command"
The doublequotes seem sufficient to escape the pipe. Single quotes on the outside wouldn't work.
PowerShell "Get-Content ZipCode.csv | Out-File ZipCode1.csv -Encoding utf8"
If you're only using Out-File because your version of PowerShell doesn't include the -Encoding option with Set-Content, then it should read:
#"%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoProfile -Command "Get-Content -Path '.\ZipCode.csv' | Out-File -FilePath '.\ZipCode1.csv' -Encoding UTF8"
Obviously if you have a Version of PowerShell where Set-Content has the required -Encoding option, use it instead:
#"%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoProfile -Command "Get-Content -LiteralPath 'ZipCode.csv' | Set-Content -LiteralPath 'ZipCode1.csv' -Encoding UTF8"
These could obviously be shortened to remove the robustness and use aliases/shorthand:
#PowerShell -NoP "GC '.\ZipCode.csv'|Out-File '.\ZipCode1.csv' -E UTF8"
#PowerShell -NoP "GC -LP 'ZipCode.csv'|SC -LP 'ZipCode1.csv' -En UTF8"
I prefer to use -LiteralPath because I have a tendency to use [] in my file naming, and those can be problematic in filenames. Change the output file name to ZipCode[1], then try the -Set-Content version code with -Path or nothing instead of -LiteralPath/-LP option, and you should see what I mean.

Command to list all files in a folder and its sub-folders showing filenames only (no paths) using Win cmd.exe

I'm looking for a command using cmd.exe (Win 10) that will list all files in a folder and its sub-folders, alphabetically, irrespective of the paths, and that will show the filenames only (no paths).
The commands that I'm familiar with (including, for example, "dir ..\samplefolder /b /s /A-D /o:n > filelist.txt") all include the paths in the output, and so are not what I'm looking for.
Thank you.
(for /r "c:\startfolder" %%A in (*) do echo %%~nxA)|sort
(this is batch file syntax; for use directly on the command line, replace every %% with just %)
for /r loops recursively over all (non-hidden) files.
%%~nxA shows name and extension only (if you want just the name without extension, use %%~nA)
See for /? for more information on those modifiers.
If the machine is on the current PowerShell 5 or higher, you could use:
(Get-ChildItem -Recurse -File -Path '..\samplefolder').Name |
Sort-Object |
Out-File -PSPath 'filelist.txt' -Encoding ascii
In a .bat file script.
>"filelist.txt" powershell -NoLogo -NoProfile -Command ^
"(Get-ChildItem -Recurse -File -Path '..\samplefolder').Name | Sort-Object"
If the machine does not have a current PowerShell, it should be upgraded or use:
>"filelist.txt" powershell -NoLogo -NoProfile -Command ^
"(Get-ChildItem -Recurse -Path '..\samplefolder'|" ^
"Where-Object { -not $_.IsContainer}).Name |" ^
"Sort-Object"

Encode file with cmd

I have a bat file that performs some actions and I need to encode a text file with UTF-8 format.
Is there any way to perform this in windows command line??
Thanks in advance.
Only with other programs which may or may not be installed. If you're targetting Windows 7 and higher you could just use PowerShell:
powershell -Command "&{ param($Path); (Get-Content $Path) | Out-File $Path -Encoding UTF8 }" somefile.txt