How to run scheduled job - cmd

I am struggling to find a way to run a scheduled job that has a special datestamp into it's name.
The name always starts with "OS_HOUSEKEEP_", followed by the datestamp - e.g.
OS_HOUSEKEEP_2018022616171014980.job
Also, no other jobs having "OS_HOUSEKEEP_" in their names are present on the machine.
Could someone advise easiest way to target it and run it once with MS-DOS command(s)?
In addition, I thought to list the current jobs with the following command:
schtasks /query /v /fo LIST | findstr "OS_HOUSEKEEP_".
Unfortunately it only comes as a result and I am unable to cache it then to process it by sections (devided with space).
No other solutions has come to my mind..

for /f "tokens=2 delims=," %%a in ('schtasks /query /v /fo csv^|find "OS_HOUSEKEEP_"') do set "task=%%~a"
set "task=%task:~1%"
echo taskname is:%task%.
the tilde in %%~a removes the quotes, the second set command removes the first character.

Related

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.

Windows batch command to create backup folder and replace folder

I need to backup an existing folder with date-time stamp and replace it (delete and recreate) with new content inside the folder.
Does anyone have a script to do this?
I tried the following code, where %ApplicationDeploymentFolderPath% = \\servername\foldername
IF EXIST %ApplicationDeploymentFolderPath%\Release (
REM Get current date time
#echo off
For /f "tokens=1-3 delims=/ " %%a in ('date /t') do (set mydate=%%c_%%b_%%a)
For /f "tokens=1-2 delims=/:" %%a in ('time /t') do (set mytime=%%a%%b)
set backup_folder=%mydate%_%mytime%
MD %ApplicationDeploymentFolderPath%\%backup_folder%
REM Copy current folder to backup folder
Copy %ApplicationDeploymentFolderPath%\Release %ApplicationDeploymentFolderPath%\%backup_folder%
REM Delete Existing Release folder
RD %ApplicationDeploymentFolderPath%\Release /S /Q
)
MD %ApplicationDeploymentFolderPath%\Release
The command date with parameter /T outputs the current date in format defined by configured country for current user account. Exactly the same date string can be accessed by referencing dynamic environment variable DATE for example with %DATE%.
The command time with parameter /T outputs the current time in format defined by configured country for current user account. Exactly the same time string can be accessed by referencing dynamic environment variable TIME for example with %TIME%.
What happens on execution of this command line?
For /f "tokens=1-3 delims=/ " %%a in ('date /t') do (set mydate=%%c_%%b_%%a)
for respectively cmd.exe processing the batch file starts in background one more command process using %ComSpec% /c with the command line between '. So executed in background is following with Windows installed in C:\Windows:
C:\Windows\System32\cmd.exe /c date /t
The output of command date to handle STDOUT of this command process in background is captured by FOR respectively Windows command processor instance executing the batch file.
The captured line is split up into three substrings using / as string delimiter assigned to the loop variables a, b and c which are concatenated together in reverse order with underscore as delimiter.
This task can be done much faster by replacing 'date /t' by "%DATE%". In this case FOR processes the date string expanded by already running cmd.exe on parsing this command line before executing FOR. So there is no starting of one more cmd.exe in background and capturing its output just to process the same date string which makes batch file execution a bit faster.
The same is true for 'time /t' which can be replaced by "%TIME%".
But the two FOR loops could be completely optimized away by using string substitution as described for example by answer on What does %date:~-4,4%%date:~-10,2%%date:~-7,2%_%time:~0,2%%time:~3,2% mean? and region dependent date and time format is well known for example by running in a command prompt window:
echo %DATE% %TIME%
This command outputs on my computer with German date/time format according to configured country:
24.07.2019 20:15:29,90
It can be seen on this output that the original code would not work on my Windows computer with my account because of date string contains . and not / and time string contains a comma.
So better would be using a region independent solution as explained very detailed in answer on Why does %date% produce a different result in batch file executed as scheduled task? The disadvantage is that execution of wmic.exe takes much longer than cmd.exe needs to reformat date and time string to yyyy_MM_dd_HHmm. However, the batch file is executed most likely not very often per day, and so it does not really matter if execution to get date/time in this format takes some milliseconds or about one second.
Copying the entire folder is not really necessary in this case. It should be enough to rename it with:
ren "%ApplicationDeploymentFolderPath%\release" "%backup_folder%"
The command move could be also used if command ren cannot be used for unknown reasons.
However, the main problem is missing knowledge about how and when to use delayed expansion. Open a command prompt, run set /? and read the output help explaining on an IF and a FOR example delayed environment variable expansion.
The issue here is that backup_folder is not defined on executing the command lines referencing it with %backup_folder% because of all occurrences of %variable% are replaced by Windows command processor already on parsing entire command block starting here with ( on IF condition at top by current value of the referenced environment variable before executing the command IF.
So executed on existing release folder is:
set backup_folder=
MD \\servername\foldername\
REM Copy current folder to backup folder
Copy \\servername\foldername\Release \\servername\foldername\
REM Delete Existing Release folder
RD \\servername\foldername\Release /S /Q
This can be seen by debugging the batch file.
See also: How does the Windows Command Interpreter (CMD.EXE) parse scripts?
The solution is here avoiding the command block by changing the first IF condition.
Fast region dependent solution:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "ApplicationDeploymentFolderPath=\\servername\foldername"
if not exist "%ApplicationDeploymentFolderPath%\Release\" goto CreateFolder
ren "%ApplicationDeploymentFolderPath%\Release" "%DATE:~-4%_%DATE:~-7,2%_%DATE:~-10,2%_%TIME:~0,2%%TIME:~3,2%"
:CreateFolder
md "%ApplicationDeploymentFolderPath%\Release"
endlocal
Slower region independent solution:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "ApplicationDeploymentFolderPath=\\servername\foldername"
if not exist "%ApplicationDeploymentFolderPath%\Release\" goto CreateFolder
for /F "tokens=2 delims==." %%I in ('%SystemRoot%\System32\wbem\wmic.exe OS GET LocalDateTime /VALUE') do set "BackupDateTime=%%I"
set "BackupDateTime=%BackupDateTime:~0,4%_%BackupDateTime:~4,2%_%BackupDateTime:~6,2%_%BackupDateTime:~8,4%"
ren "%ApplicationDeploymentFolderPath%\Release" "%BackupDateTime%"
:CreateFolder
md "%ApplicationDeploymentFolderPath%\Release"
endlocal
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
endlocal /?
for /?
goto /?
if /?
md /?
ren /?
set /?
setlocal /?
wmic /?
wmic os /?
wmic os get /?
wmic os get localdatetime /?

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

Edit previous output to use in next command in batch

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

Windows batch file : PID of last process?

I am launching a browser from batch file.
START "www.google.com"
I would like to know the PID of this browser window launched.
There can be many browser windows launched on a single machine. I need to find the PID of the process which was launched by my batch file only. I tried with WINDOWTITLE filter. But its not a good idea as titles may change in future. I am using Windows XP/7
Any help would be appreciated.
Thanks.
For what it worth (question is more than 2 years old) this code do the trick, just change variable according to default browser exe
set "browser=palemoon.exe"
tasklist /FI "imagename eq %browser%" /NH /FO csv > task-before.txt
start www.google.com
tasklist /FI "imagename eq %browser%" /NH /FO csv > task-after.txt
:: fc /L /LB1 test4-Before.txt test4-After.txt | find /I "%browser%"
for /f "delims=, tokens=2,*" %%A in ('"fc /L /LB1 task-before.txt task-after.txt | find /I "%browser%""') do set pid=%%A
SETLOCAL enabledelayedexpansion
pid=!pid:"=!
ENDLOCAL
echo pid is %pid%
This is just an idea, to get you maybe on the way
there is a command called Tasklist
there is a switch called filter /FI with lets you decide what filter parameters you want to output, f.e PID. Output this to a > 1.TXT
start your proces
recheck the watchlist and output to 2.TXT
Then you would have to get creative. COmpare 1 to 2,
maybe remove the processes in 1 from the 2.TXT
The remainig PID is what you wanted?
If you have some programming experience, you could create your own console application that accepts command-line parameters and passes them to the Win32 API CreateProcess() function. One of its output values is the spawned process ID, which your app could then return. Then just update your batch file to call your app instead of using START directly.
I'm trying to do the same thing. Though there must be some way of doing it, but all my Googling suggests not.
Check out robvanderwoude.com to see a list of 3rd party tools and examples. Also check out the full list of Sysinternal's process utilities here.
I've been looking at this for about 2 hours now and I think that there is a way to do this, but it requires some more insight on how windows handles iexplore.exe for PID...
I have a working version of a batch file I wrote that will get you what you want, BUT only if its the FIRST AND ONLY Internet Explorer Window open.
For some reason I can't get the PID to change when I open new browsers, but I can get results if there is no window open (obviously because there is no PID)
Anyhow, this is what I have... you should be able to run this on your system and it will tell you that there are no differences and it might actually produce results if your default browser is Firefox or Chrome or something... just need to make the changes to what I'm providing.
#echo off
IF EXIST c:\temp\pshell.txt del c:\temp\pshell.txt
IF EXIST C:\temp\PID1.txt del C:\temp\PID1.txt
IF EXIST C:\temp\PID2.txt del C:\temp\PID2.txt
IF EXIST C:\temp\PowerFormat.txt del C:\temp\PowerFormat.txt
powershell.exe Get-Process iexplore>C:\temp\pshell.txt
FOR /F "skip=3 tokens=7 delims= " %%1 IN ( c:\temp\pshell.txt ) DO #echo %%1>> C:\temp\PID1.txt
start "title" "www.google.com"
powershell.exe Get-Process iexplore>C:\temp\pshell.txt
FOR /F "skip=3 tokens=7 delims= " %%2 IN ( c:\temp\pshell.txt ) DO #echo %%2>> C:\temp\PID2.txt
FC /L c:\temp\pid1.txt c:\temp\pid2.txt> C:\temp\FileComparison.txt
FOR /F "tokens=7 delims=" %%3 IN (c:\temp\FileComparison.txt) DO #echo %%3>C:\temp\DiffPID.txt
FINDSTR "FC: no differences encountered" c:\temp\FileComparison.txt
IF '%ERRORLEVEL%'=='0' del C:\temp\FileComparison.txt & echo.No PID Found
IF NOT '%ERRORLEVEL%'=='0' type c:\temp\FileComparison.txt
pause
exit
Let me know if this helps...

Resources