I need a line of script that does something like this:
if (results from PowerShell command not empty) do something
The PowerShell command is basically
powershell -command "GetInstalledFoo"
I tried if (powershell -command "GetInstalledFoo" != "") echo "yes" but get the error -command was unexpected at this time. Is this possible to accomplish? This command will eventually be run as the command to cmd /k.
BartekB's answer works as long as at least one line of output does not start with the FOR /F eol character (defaults to ;) and does not consist entirely of delimiter characters (defaults to space and tab). With appropriate FOR /F options it can be made to always work.
But here is a simpler (and I believe faster) way to handle multiple lines of output that should always work.
for /f %%A in ('powershell -noprofile -command gwmi win32_process ^| find /v /c ""') do if %%A gtr 0 echo yes
Another alternative is to use a temp file.
powershell -noprofile -command gwmi win32_process >temp.txt
for %%F in (temp.txt) if %%~zF gtr 0 echo yes
del temp.txt
Third way: set an environment variable from your PowerShell script and test it in your batch file?
I guess if won't be the best solution for that. I would use for /f instead:
for /f %R in ('powershell -noprofile -command echo foo') do #echo bar
That should give you 'bar', while this:
for /f %R in ('powershell -noprofile -command $null') do #echo bar
... should not. In actual .bat/ .cmd file you have to double % (%%R)
or better yet, if you don't want to many bar's returned...:
(for /f %R in ('powershell -noprofile -command gwmi win32_process') do #echo bar) | find "bar" > nul && echo worked
Related
The scope is running from the user's local computer.
You can use this to get the active user's SID.
Then you could use this with the HKU registry hive.
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
ECHO GET THE NAME OF THE ACTIVELY LOGGED ON USER
FOR /F "skip=1" %%G IN ('wmic computersystem get username') DO (
SET aUSER=%%G
GOTO EXITLOOP1
)
:EXITLOOP1
ECHO %aUSER%
ECHO[
REM ECHO TRIM THE USERNAME
SET tUSER=%aUSER:~4%
REM ECHO %tUSER%
ECHO[
ECHO GET SID FOR USER: %tUSER%
FOR /F "usebackq skip=1" %%a IN (`WMIC USERACCOUNT WHERE NAME^='%%tUSER%%' GET SID`) DO (
SET SID=%%a
GOTO EXITLOOP2
)
:EXITLOOP2
ECHO %SID%
BTW, if you wanted to do it without a For loop, you could ask powershell to assist:
%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -Command "(%SystemRoot%\System32\whoami.exe /User /Fo CSV | ConvertFrom-Csv).SID"
Or even without whoami.exe:
%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -Command "Add-Type -AssemblyName System.DirectoryServices.AccountManagement;$([System.DirectoryServices.AccountManagement.UserPrincipal]::Current).SID.Value"
In a cmd.exe console the following command can be used.
powershell -NoLogo -NoProfile -Command ^
"Add-Type -AssemblyName System.DirectoryServices.AccountManagement;" ^
"([System.DirectoryServices.AccountManagement.UserPrincipal]::Current).Sid.AccountDomainSid.Value"
To get the result into a variable, use a FOR loop. (Yeah, I know, it's crazy, right?)
FOR /F "delims=" %%A IN ('powershell -NoLogo -NoProfile -Command ^
"Add-Type -AssemblyName System.DirectoryServices.AccountManagement;" ^
"([System.DirectoryServices.AccountManagement.UserPrincipal]::Current).Sid.AccountDomainSid.Value"') DO (
SET "USER_SID=%%~A"
)
ECHO USER_SID is set to %USER_SID%
There are many other things that can be accessed in this way.
powershell -NoLogo -NoProfile -Command ^
"Add-Type -AssemblyName System.DirectoryServices.AccountManagement;" ^
"[System.DirectoryServices.AccountManagement.UserPrincipal]::Current |" ^
"Format-List * -Force"
As you've raised a question, and in it decided to post some code, I'll offer a quicker and more simple alternative, regardless of whether you decide to post yours as a solution:
From cmd:
For /F Tokens^=3^ Delims^=^" %G In ('%SystemRoot%\System32\whoami.exe /User /Fo CSV /NH') Do #Echo %G
From a batch-file:
#For /F Tokens^=3^ Delims^=^" %%G In ('%SystemRoot%\System32\whoami.exe /User /Fo CSV /NH') Do #Echo %%G
I have a text file where the contents have a lot of NUL or spaces between data:
[nul][nul][nul][nul]Name [nul][nul][nul][nul][nul][nul]surname
The data inside of the text file is always different.
I have searched and tested many similar questions using for /F "usebackq delims=" %%a in ("%file%") do echo %%a and similar commands, but i always get empty results.
Please can anyone help?
If you truly have a text file with, for example, the following content:
External image link
And you just want to omit the NUL characters as part of a normal For /F loop file read, then you could ask powershell for help from your batch-file:
#For /F "Delims=" %%G In (
'%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe ^
-Nologo -NoProfile -Command "(Get-Content 'sourcefile.txt')" ^
" -replace '\x00',''"') Do #Echo(%%G
#Pause
I have split that long line up into multiple for easier reading, but you could also have it as a single line batch-file:
#(For /F "Delims=" %%G In ('%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -Nologo -NoProfile -Command "(Get-Content 'sourcefile.txt') -replace '\x00',''"') Do #Echo(%%G) & Pause
And to do it in simple terms directly from the Command Prompt cmd:
For /F "Delims=" %G In ('powershell -NoP "(GC 'sourcefile.txt') -replace '\x00',''"') Do #Echo(%G
[Edit /]
If you wanted to add a single comma, between those two specific words in the exact example you provided, and which I used in my linked image above, then yes, it would be possible.
For example you could do it within the PowerShell part, by changing:
-replace '\x00','' to -replace ' ',', ' -replace '\x00',''
Or, you could do it by changing the For loop option:
"Delims=" to "Tokens=1*"
and then change either:
#Echo(%%G, or #Echo(%G
to:
#Echo(%%G, %%H or #Echo(%G, %H respectively.
I have an hard coded windows command line with dates (from: yesterday until today)
I want to replace the hard coded dates with an expression like date.add(-1) for yesterday.
I know how to get current date: %date:~10,4%-%date:~4,2%-%date:~7,2%
but how can I do this for yesterday?
thanks!
You can do exactly that in cmd using PowerShell. PowerShell is available for Windows from Windows 7. Are you running Windows 98 or something earlier?
FOR /F %a IN ('powershell -NoProfile -Command "(Get-Date).AddDays(-1).ToString('yyyy-MM-dd')"') do (SET "YD=%a")
ECHO %YD%
Here is a .bat file equivalent.
#ECHO OFF
FOR /F %%a IN ('powershell -NoProfile -Command "(Get-Date).AddDays(-1).ToString('yyyy-MM-dd')"') do (SET "YD=%%a")
ECHO %YD%
EXIT /B 0
Can anyone please advise how to use Windows Command Prompt to read last 10 lines of a text file?
One way is to use PowerShell.
powershell -NoProfile -Command "Get-Content .\rrreg.ps1 | Select-Object -Last 3"
Iterating across each line can also be done.
FOR /F "usebackq tokens=*" %%s IN (`powershell -NoProfile -Command "Get-Content .\rrreg.ps1 | Select-Object -Last 3"`) DO (
ECHO %%s
)
Of course, having a tail command on your system would make tail -10 thefile.txt possible. How much easier can it be than that?
Is there a way to extract/copy the fist X number of lines from a file and input them into another file with a single command using the windows command prompt?
I can delete the first X number of lines using:
more +X [file_containing data] > [file_to_export_data_to]
If the head command would work I think I could just do this:
head -X [file_containing data] > [file_to_export_data_to]
But that unfortunately does not work.
It would be great if Windows had a "less" command but again no luck.
I'm a complete novice when it comes to this stuff so I'm sure I'm missing something obvious. I don't want to install anything or use something other than the command prompt.
Thanks
the simplest one-command solution is to use Powershell Get-Content.
N - number of lines.
From the begining of file:
Get-Content -Head N file.txt
From the end of file:
Get-Content -Tail N file.txt
You can use PowerShell from the cmd.exe console:
powershell -command "& {get-content input.txt|select-object -first 10}" >output.txt
You could create a DOSKEY macro to make it easier to use from the command line:
doskey head=powershell -command "& {get-content $1|select-object -first $2}"
Usage:
head input.txt 10 >output.txt
But you cannot use a DOSKEY macro within a batch script.
You could create a head.bat script instead and place it in a folder that is included in your PATH:
head.bat
#powershell -command "& {get-content %1|select-object -first %2}"
From the command line, you would use head input.txt 10 >output.txt
From within a batch script, you would use call head input.txt 10 >output.txt
I chose not to have the output file as a parameter in case you want to simply display the result to the screen instead of writing to a file.
In order to get correct utf8 output, do the following in powershell
chcp 65001
$OutputEncoding = New-Object -typename System.Text.UTF8Encoding
get-content input.txt -encoding UTF8 |select-object -first 10000 > output.txt
This will get first 10000 lines of input.txt (file in utf8 format) to output.txt with correct encoding.
(#FOR /f "tokens=1* delims=:" %a IN ('findstr /n "^" "standardwaffle.txt"') DO #IF %a leq 7 ECHO(%b)>u:\junk.txt
would extract the first 7 lines of standardwaffle.txt to u:\junk.txt so here it is in one cmd line - but I'd defy you to enter that reliably.
It would also remove any leading : on a source line.
#ECHO OFF
SETLOCAL
IF %1 lss 0 (SET /a line=-%1) ELSE (SET /a line=%1)
FOR /f "tokens=1* delims=:" %%a IN ('findstr /n "^" "%~2"') DO IF %%a leq %line% ECHO(%%b
GOTO :EOF
This batch, saved as head.bat placed anywhere on your path would allow you to use
head -n standardwaffle.txt >junk.txt
to extract the first n lines of standardwaffle.txt to junk.txt
the - would be optional
but this involves installing the batch on your machine. Is that banned by your "no installing" requirement, or is "installing" meant only for 3rd party utilities?
Set Inp = WScript.Stdin
Set Outp = Wscript.Stdout
x = 0
Do Until Inp.AtEndOfStream
x = x + 1
OutP.WriteLine Inp.Readline
If x = 5 then Exit Do
Loop
This prints lines 1 to 5. To use
cscript //nologo <path to script.vbs> <inputfile >outputfile
you can use this:
break>"%temp%\empty"&&fc "%temp%\empty" "%file_to_process%" /lb X /t |more +4 | findstr /B /E /V "*****"
where you should replace the X with the lines you want.Or name this head.bat :
break>"%temp%\empty"&&fc "%temp%\empty" "%file_to_process%" /lb %~1 /t |more +4 | findstr /B /E /V "*****"
If you wanted to stick to simple Windows commands you could use this but would be a little slow for large files ;-) (I've added a second solution below that works better :-) this extracts the last 100 records of any length of file)
find /n " " <test.txt >test.tmp
for /l %%i in (1,1,100) do find "[%%i]" <test.tmp >test.tmp2
for /f "delims=] tokens=2" %%i in (test.tmp2) do echo %%i >>test.new
del test.tmp
del test.tmp2
move /y test.new test.txt
find /v /n "" <test.txt >test.tmp
for /f "delims=: tokens=2 %%i in ('find /v /c "" test.txt') do set /a NR=%%i
set /a NS=%NR%-100
for /l %%i in (%NS%, 1, %NR%) do find "[%%i]" <test.tmp >>test.tmp2
for /f %%i "delims=] tokens=2 %%i in (test.tmp2) do echo %%i >>test.new
move /y test.new test.txt
No need to read whole file; just extract the required lines (head) from beginning of file:
set file=<file>
set line=<required first few lines>
type nul > tmp & fc tmp "%file%" /lb %line% /t | find /v "*****" | more +2
A single line example to extract first 9 lines from file.txt & write into nine.txt
for /f "tokens=* delims=[" %i in ('type "file.txt" ^| find /v /n "" ^| findstr /b /r \[[1-9]\]') do set a=%i& set a=!a:*]=]!& echo:!a:~1!>> nine.txt
Preserves blank lines, lines starting with semicolon, leading spaces and preserves delimiter and whitespaces.
Tested on Win 10 x64 CMD