Edit previous output to use in next command in batch - windows

I need to pull a certain string from a command output in a batch file, I am trying to get the GUID of the active power scheme to query the settings.
Currently, my code looks like this:
FOR /F "delims=" %%i IN ('powercfg /getactivescheme') DO set scheme=%%i
powercfg /query %scheme%
but of course the powercfg /getactivescheme command adds other useless junk to the output, so I end up with
C:\Users\Richard\Desktop>FOR /F "delims=" %i IN ('powercfg /getactivescheme') DO
set scheme=%i
C:\Users\Richard\Desktop>set scheme=Power Scheme GUID: c0ea6ad3-6145-4447-a15e-5
fb97be69b98 (Energy Star)
Now, all I want to pull is: c0ea6ad3-6145-4447-a15e-5fb97be69b98 and truncate the Power Scheme GUID: and (Energy Star)
for input into the next command which is powercfg /query %scheme%
Any suggestions are welcome.
Thanks!

This gets the 4th token, separated by space/tabs
FOR /F "tokens=4" %%i IN ('powercfg /getactivescheme') DO set scheme=%%i

Related

Run multiple commands and log output as one row on Windows batch

i am trying to run a command 1 (wmic diskdrive get status) and command 2(wmic OS GET LocalDateTime /VALUE) and write output as one row to a file.
background information
I need to monitor SMART status with zabbix agent active. Windows version is one without powershell and i have very limited user rights there. I have about 50 machines that i need to monitor with it and a .bat skript is the most viable solution i have
background information ends
#echo off
setlocal EnableExtensions EnableDelayedExpansion
set "INTEXTFILE=c:\zabbix\smart_log.txt"
set "OUTTEXTFILE=c:\zabbix\smart_log_out.txt"
(wmic diskdrive get status
wmic OS GET LocalDateTime /VALUE) 1> %INTEXTFILE%
so far so good. I get a smart_log.txt with information:
Status
OK
LocalDateTime=20200114155453.199000+120
From here on i try to edit this file, to get all of this data as one row, but here i run into trouble.
i tried this answer but no luck.
setlocal EnableDelayedExpansion
set row=
for /f %%x in (%INTEXTFILE%) do set "row=!row! %%x"
>%OUTTEXTFILE% echo %row%
All i get there is :
ECHO is off.
My goal is to get a file with row:
Status OK (*maybe multiple OK OK OK if there are many disks) LocalDateTime=20200114155453.199000+120
#echo off
setlocal enabledelayedexpansion
set "line="
for /f "delims=" %%a in ('wmic diskdrive get status^|more') do set "line=!line!%%a,"
for /f "delims=" %%a in ('wmic OS GET LocalDateTime /value ^| more') do set line=!line!%%a
set "line=%line: =%"
echo %line:,= %
The output of wmic as an usual line ending (CRCRLF instead of CRLF) which complicates things. Piping it to more "corrects" those line endings. Then just concatenate the lines. To beautify (and adapt to your required format) build the strings with another delimiter (comma here),remove any spaces, and change the commas back to spaces.
Output on my system:
Status OK OK OK LocalDateTime=20200114165152.456000+060
Hint: changing to delims=. for the second for loop (the date), changes the output to:
Status OK OK OK LocalDateTime=20200114165555

How to run an action/command based on a result of a previous command

I have a deployment that installs a driver and I want to provide the ability to uninstall.
Im leveraging the PNPUTIL.exe tool.
I know the syntax to delete and uninstall the driver, ex:
pnputil.exe /delete-driver oem103.inf /uninstall /force
But my issue, is the oem*.inf number designation is random on each machine, so I can't hard code the .inf into the command and call it a day.
pnputil has /enum-driver switch that will give you details of all the drivers in the DriverStore. Among the line items is the original name of .inf (something I can work with) and the oem# associated with it.
So what I need help with is scripting something that will enumerate the drivers pipe the results to the command to be able the run /delete-drive and /uninstall switches
I tried messing with the Find and FindSTR commands, but it only returned the one line which was the name of the original .inf. I need the OEM# associated with original name of the .inf to be piped to the command.
In the output of pnputil, the desired oemXX.inf is one line above the Original Name.
So numerate the output, look for the original name and subtract one from the line number. This is the line number where you find the oemXX.inf.
Then find that line and extract the oemXX string. (the for %%b is to get rid of the leading spaces)
#echo off
setlocal
set "Orig=rt640x64.inf"
pnputil /enum-drivers |findstr /n "^" > pnputil.txt
for /f "delims=:" %%a in ('findstr /c:" %Orig%" pnputil.txt') do set /a line=%%a-1
for /f "tokens=3 delims=:" %%a in ('findstr /b "%line%:" pnputil.txt') do for %%b in (%%a) do set "oem=%%b"
echo "%oem%"
Note: the output of pnputil is language-dependent, but this code doesn't look for words (except the "Original name" of course) but for line numbers, so it should work on all languages.

capture result of wmic command to variable [duplicate]

This question already has answers here:
Set the value of a variable with the result of a command in a Windows batch file [duplicate]
(6 answers)
Assign command output to variable in batch file [duplicate]
(5 answers)
Closed 3 years ago.
I am trying to write a small batch script to install an app from a thumb drive. The problem is the drive letter changes when plugged into different machines depending on the available drive letters. I have the script to run the installation but would like to add a script to the beginning that would detect the assigned drive letter of my inserted thumb drive and store it in a variable that I could then substitute in the rest of the script for the drive letter to complete the installation.
I got the command to identify the assigned drive letter of the thumb drive which works on its own.
wmic logicaldisk where volumename="StacelandFlash" get name
Result: D: (correct)
But I can't seem to assign it to a variable.
set X=wmic logicaldisk where volumename="StacelandFlash" get name
echo X
Result: X
set X=wmic logicaldisk where volumename="StacelandFlash" get name
echo %X%
Result: wmic logicaldisk where volumename="StacelandFlash" get name
Firstly, to capture the output of a command to a variable use for /F. See for /? in a cmd console for full details. Example:
for /f "tokens=2 delims=:" %%I in ('find /c /v "" "notes.txt"') do (
set /a "linecount=%%I"
)
rem // %linecount% now contains the number of lines in notes.txt
Now, there are a couple of complications unique to capturing WMI query results. Firstly, your wmic command includes an equals sign, which will break a for /f. That part's easy enough to fix: either escape the = with a caret (e.g. ^=), or just surround the equation in quotation marks.
The next hurdle is a bit trickier. WMI results are encoded in a non-ANSI encoding (UCS-2 LE). Capturing the output of wmic also captures the output's encoding, resulting in the last character being moved to the beginning of the line or other unexpected behavior. The workaround for that is to use a second nested for /f to sanitize the value.
With all that in mind, I think this is what you're looking for:
#echo off
setlocal
for /f "tokens=2 delims==" %%I in (
'wmic logicaldisk where "volumename='StacelandFlash'" get name /value'
) do for /f "delims=" %%# in ("%%I") do set "driveletter=%%~#"
echo %driveletter%
Note: credit #Dave Benham for discovering this workaround.
You need to run the command within a For Loop.
#Echo Off
For /F "Skip=1 Delims=" %%A In ('
"WMIC LogicalDisk Where (VolumeName='StacelandFlash') Get Name"
') Do For %%B In (%%A) Do Set "USB=%%B"
Echo(%USB%
Timeout -1
I suppose the batch file executed is stored on the thumb drive. And this batch file is executed with a double click. Therefore all you need is:
set "DriveLetter=%~d0"
%~d0 references the drive of argument 0 which is the batch file name. Run in a command prompt window call /? for details on how to reference arguments of a batch file. %~d0 expands to D:, E:, ...

Redirecting appcmd output to a variable

I am trying to run the following:
FOR /F "tokens=* delims=" %A IN ('C:\windows\system32\inetsrv\appcmd.exe list app /site.name:"car" /xml | C:\windows\system32\inetsrv\appcmd.exe list vdir /vdir.name:"car/" /text:physicalPath') DO SET Variable=%A
But get the following error:
| was unxepected at this time
If the data must be piped from a process to the other, you need to escape the pipe character. It should be ^|
If what you need to do is execute both commands, replace the pipe character with ^&, the command concatenation operator, also escaped
For anyone reaches this, following is working example of batch file to get physical path of iis site , stored in a variable named 'physicalPath'.
This is based on #StuHarper explanations in comments.
#echo off
set site=stackoverflow.com
set site=%site:https://=%
set site=%site:http://=%
set site=%site: =%
set appcmd=%systemroot%\system32\inetsrv\AppCmd.exe
set xmlOutput=%appcmd% list app /site.name:%site% /path:"/" /xml
for /f "tokens=*" %%A in ('%xmlOutput% ^| %appcmd% list vdir /in /text:physicalPath') DO SET physcalPath=%%A
echo physcalPath: %physcalPath%
#echo on

Batch file to remove first 10 chars from txt file

I'm trying to remove the first 10 characters from multiple lines inside a text file using a batch script, then output the results to a new file. I ran across this and it got me pointed in the right direction but the final output isn't working.
Here's what I've got so far:
setLocal EnableDelayedExpansion
CSCRIPT /nologo %windir%\System32\prnport.vbs -l > c:\IPPorts.txt
type c:\IPPorts.txt | findstr IP_ > c:\IPPorts2.txt
for /f "tokens=*" %%a in (c:\IPPorts2.txt) do (set line=%%a set chars=!line:~10! > c:\IPPorts3.txt)
for /f "delims=" %%x in (c:\IPPorts3.txt) do CSCRIPT /nologo %windir%\System32\prnport.vbs -d -r %%x
The 2nd line exports a list of printer ports to a file named IPPorts.txt. The 3rd finds the lines with "IP_" in them and exports to IPPorts2.txt. The 4th line is supposed to remove unneeded text (which it isn't doing) and export to IPPorts3.txt. And the last line will take the results from IPPorts3.txt and then delete those ports.
IPPorts.txt is as follows:
Server name
Port name IP_172.20.51.11
Host address 172.20.51.11
Protocol RAW
Port number 9100
SNMP Disabled
These lines are repeated for every port, of which there are several. Since I only need the line containing the port name, IPPorts2.txt looks like this:
Port name IP_172.20.51.11
Port name IP_172.20.52.58
Port name IP_172.20.53.16
Port name IP_172.20.54.19
Port name IP_172.20.55.15-1
Port name IP_172.20.55.15
Port name IP_172.20.55.11
Where I'm having trouble is removing the "Port name " portion of the lines (the first 10 characters). I want the output to read on each line as "IP_X.X.X.X". The problem is the 3rd file is always empty.
Where am I going wrong? Any help is greatly appreciated.
EDIT:
This is further down under Endoro's answer, but I thought it might be nice to post the answer here. Here's what I changed the 4th line to:
for /f "tokens=* delims=" %%c in ('type c:\IPPorts2.txt') do (
set LINE=%%c
>> c:\IPPorts3.txt echo !LINE:~10!
)
This has corrected my problems. Thanks everyone!
try this:
(for /f "tokens=3" %%i in (IPPorts2.txt) do #echo %%i)>IPPorts3.txt
Script to get directory name out of DIR command output :
...
20/09/2014 01:23 [DIR] some1
21/09/2014 02:34 [DIR] some2
22/09/2014 03:45 [DIR] some3
23/09/2014 11:22 [DIR] some4
...
We want it to be:
some1
some2
some3
some4
...
Code :
#FOR /f "tokens=4" %%D IN (i:\test.txt) DO #( echo %%D ) >> result.txt
In your case tokens=3, not perfect but does the job with few lines manually edited in the result.
(For /f "tokens=3delims= " %%i in (ipports2.txt) do echo %%i) >ipports3.txt
should do it for you.
The paretheses are important - ensure that the file is created anew. If omitted, will only generate the last line.
Simply uses the delimiter [space] to tokenise the string on each line into token1=Port, token2=Name and sets %%i to each token3 in turn.
The following isn't really a different solution but merely a suggestion to simplify your script by reducing the number of output files.
In fact, it is possible to exclude all of them from the script, unless you need to keep them for history.
Basically, the idea is first to apply FINDSTR directly to the output of prnport.vbs:
CSCRIPT /nologo %windir%\System32\prnport.vbs -l | FINDSTR "IP_"
then apply a loop directly to the output of FINDSTR (note the single quotation marks around the piped command line, as well as the escaped |):
FOR /F "tokens=3" %%A IN (
'CSCRIPT /nologo %windir%\System32\prnport.vbs -l ^| FINDSTR "IP_"'
) DO …
and call prnport.vbs with another set of arguments in that same loop:
FOR /F "tokens=3" %%A IN (
'CSCRIPT /nologo %windir%\System32\prnport.vbs -l ^| FINDSTR "IP_"'
) DO (
CSCRIPT /nologo %windir%\System32\prnport.vbs -d -r %%A
)
The tokens option of a FOR /F loop specifies which token (or field) to take based on a specific delimiter or set of delimiters. The default set of delimiters is a space, a comma, a tab. Your Port name IP_whatever lines conveniently consist of exactly three tokens and the third one is what you are after, hence "tokens=3" in the options.
So, as you can see, no output files, the necessary value is extracted and passed to the target command in the same iteration.

Resources