Formatting date and time in batch file using Powershell - powershell

I want to name a file using the current date and time in a specific format.
To do so, I have the following code to set %datetime% to the format I want.
Example: 2017-06-19 05_00_00
for /f %%a in ('powershell -Command "Get-Date -format yyyy-MM-dd\ HH_mm_ss"') do set datetime=%%a
This isn't quite working. I'm 99% sure it is due to the space between the date and time, which I want.
What is the error, and how can it be fixed?
(Note that I cannot depend on WMIC being available, so calling Powershell is probably the best solution. Regardless, I'm interested in learning how to get this specific code to work.)

You can try with any of these
for /f "delims=" %%a in ('
powershell -Command "Get-Date -format 'yyyy-MM-dd HH_mm_ss'"
') do set "datetime=%%a"
for /f "tokens=*" %%a in ('
powershell -Command "Get-Date -format 'yyyy-MM-dd HH_mm_ss'"
') do set "datetime=%%a"
for /f "tokens=1,2" %%a in ('
powershell -Command "Get-Date -format 'yyyy-MM-dd HH_mm_ss'"
') do set "datetime=%%a %%b"
Changes from original code
The format string has been quoted
The for /f command tokenizes the lines being processed using spaces and tabs as delimiters, retrieving by default only the first token in the line (in your case, the date). As your output has two space separted tokens, we need to disable the tokenizer (first sample, by clearing the delimiters list), request all the tokens in the line (second sample) or request only the needed tokens (third sample)

Related

How to set a variable in cmd which is a string from powershell command result?

I want to store the result of powershell command in cmd variable as String : powershell -com "(ls | select -Last 1).FullName". How to do this?
CMD does not have a straightforward way of assigning command output to a variable. If the command produces just a single line you could use a for loop
for /f "delims=" %a in ('some_command /to /run') do #set "var=%a"
However, if the command produces multiple lines that will capture only the last line. A better approach would be redirecting the output of the command to a file and then reading that file into a variable:
set "tempfile=C:\temp\out.txt"
>"%tempfile%" some_command /to /run
set /p var=<"%tempfile%"
del /q "%tempfile%"
If you literally need only the last file in a directory you don't need to run PowerShell, though. That much CMD can do by itself:
for /f "delims=" %f in ('dir /a-d /b') do #set "var=%~ff"
Beware that you need to double the % characters when running this from a batch file.
A FOR loop can provide the path to the file. If the default directory sorting order is not the result needed, specify additional command line switches on the DIR command.
FOR /F "delims=" %F IN ('DIR /B') DO (SET "THE_FILE=%~fF")
ECHO THE_FILE is "%THE_FILE%"
In a .bat file script, double the percent characters on FOR loop variables.
FOR /F "delims=" %%F IN ('DIR /B') DO (SET "THE_FILE=%%~fF")
ECHO THE_FILE is "%THE_FILE%"
The .bat file scripts can also run PowerShell scripts. It is best practice to not use aliases such as ls in scripts.
FOR /F "delims=" %%F IN ('powershell -NoLogo -NoProfile -Command ^
"(Get-ChildItem -File | Select-Object -Last 1).FullName"') DO (SET "THE_FILE=%%~fF")
ECHO THE_FILE is "%THE_FILE%"
The problem with cmd here is that I want to get the full paths for
FOLDERs NOT recursive... this dir /ad /b doesn't give full paths and
this dir /ad /b /s does it recursively... – stakowerflol 2 hours ago
That's not a problem, you can return the full file path without recursing.
If you are changing directory to the path you need to check then it's stored in %CD%
If you need the path to whee the Script itself is it's stored in %~dp0
If you want to provide an argument to specify and arbitrary path and get all of the listings it will be that argument term (EG %~1)
With all three possible options you can do the same thing:
Either
Prepend the provided variable to the output of the chosen directory enumeration method
OR
Use a For loop to get the file names at that path and show the result with the full path.
IE
Jenkins_A_Dir.bat
#(
SETLOCAL
ECHO OFF
SET "_Last="
ECHO.%~1 | FIND /I ":\" > NUL && (
SET "_CheckHere=%~1"
)
IF NOT DEFINED _CheckHere (
SET "_CheckHere=C:\Default\Path\When\No Argument\Specified"
)
)
REM Use a For loop to get everything in one variable
FOR %%A IN (
"%_CheckHere%\*"
) DO (
SET "_Last=%%A"
)
ECHO.Found "%_Last%"
REM Use `FOR /F` with DIR, and append the path to Check:
SET "_Last="
FOR /F "Tokens=*" %%A IN ('
DIR /A-D /B "%_CheckHere%\*"
') DO (
SET "_Last=%_CheckHere%\%%A"
)
ECHO.Found "%_Last%"
Of course you don't NEED to have set a variable such as _CheckHere
Instead, you can just replace all of the instances of %_CheckHere% with `%~1 instead, that would work just fine in the above examples too.
Okay, what if you just wanted to check the location the script was running in.
Then either change the above to use SET "_CheckHere=%~dp0" or Replace %_CheckHere% with %~dp0 throughout.
Okay but what if you don't want to set a variable you want to it to use the current working directory.
When then, even easier:
Jenkins_Current_Dir.bat
#(
SETLOCAL
ECHO OFF
SET "_Last="
)
REM Use a For loop to get everything in one variable
FOR %%A IN (
"*"
) DO (
SET "_Last=%%~fA"
)
ECHO.Found "%_Last%"
REM Use `FOR /F` with DIR, and let it append the current working directory to the path:
SET "_Last="
FOR /F "Tokens=*" %%A IN ('
DIR /A-D /B "*"
') DO (
SET "_Last=%%~fA"
)
ECHO.Found "%_Last%"

How to replace the given line of text file in looping structure using windows batch file

set instance=3
for /L %%A in (1,1,%instance%) do (
set /p var=LogfileName: trial.txt
set rep=LogfileName: logfile.txt
echo %var%
powershell -Command "(gc InputFile.txt) -replace '%var%', '%rep%' | Out-File InputFile.txt"
)
I am not able to replace the line in text file using this commands. And also I am not getting how to take the line number and store the string in that particular lile in file into a batch file variable.
% variables in batch files are expanded at parse time (when the statement is read). Since the entire for statement, including the action block, is read as one statement, %var% and %rep% are expanded before the loop is executed, meaning they evaluate to empty strings.
To have the variables inside the loop expanded at execution time you need to enable delayed expansion and use ! notation:
setlocal EnableDelayedExpansion
set instance=3
for /L %%A in (1,1,%instance%) do (
set /p var=LogfileName: trial.txt
set rep=LogfileName: logfile.txt
echo !var!
powershell -Command "(gc InputFile.txt) -replace '!var!', '!rep!' | Out-File InputFile.txt"
)
For further explanation see Raymond Chen's blog.

How to use line continuation inside quoted string of FOR /F

I would like to be able to specify multiple lines for the command of a FOR /F loop. The first three (3) commands work as expected. However, the fourth (4th) command will never let me make a newline while inside the quoted command. I have tried the cmd.exe line continuation character caret, the PowerShell line continuation character backtick, and combined caret+backtick. It seems to simply skip over the fourth (4th) FOR /F loop without error or message.
Yes, I see that the fourth (4th) FOR /F loop is not in danger of overrunning the right side of the display. I am thinking of times when I have much longer commands. Is creating a .ps1 file the only answer? Can line continuation be made to work?
C:>type gd.bat
#ECHO OFF
FOR /F "usebackq tokens=*" %%d IN (`powershell -NoProfile -Command "get-date -format s"`) DO (SET "DT_STAMP=%%d")
ECHO DT_STAMP 1 is %DT_STAMP%
FOR /F %%d IN ('powershell -NoProfile -Command "Get-Date -Format s"') DO (SET "DT_STAMP=%%d")
ECHO DT_STAMP 2 is %DT_STAMP%
FOR /F %%d IN ('powershell -NoProfile -Command ^
"Get-Date -Format s"') DO (SET "DT_STAMP=%%d")
ECHO DT_STAMP 3 is %DT_STAMP%
FOR /F %%d IN ('powershell -NoProfile -Command ^
"Get-Date ^`
-Format s"') DO (SET "DT_STAMP=%%d")
ECHO DT_STAMP 4 is %DT_STAMP%
19:53:02.34 C:\src\t
C:>gd.bat
DT_STAMP 1 is 2018-01-07T19:53:10
DT_STAMP 2 is 2018-01-07T19:53:10
DT_STAMP 3 is 2018-01-07T19:53:10
20:01:39.37 C:\src\t
C:>echo %ERRORLEVEL%
0
You are attempting to do cmd.exe line continuation. The ^ has no special meaning if quoting is ON. You can escape the " as ^" so that the ^ line continuation works. You must also escape the second quote, else the closing ) will not be recognized.
FOR /F %%d IN ('powershell -NoProfile -Command ^
^"Get-Date ^
-Format s^"') DO (SET "DT_STAMP=%%d")
Note that the line breaks are purely cosmetic - Powershell still receives the entire command as a single line (without any line breaks).

How to insert date and time to a filename in a batch script? [duplicate]

This question already has answers here:
How do I get current date/time on the Windows command line in a suitable format for usage in a file/folder name?
(30 answers)
Closed 5 years ago.
I wrote a batch script for a Jenkins jobs which compiles a ".net" code and one of the steps there is to back up the current directory before extracting the new compiled code.
I'm using the these lines to extract the date and time which I want to insert into the backup file name:
for /F "tokens=2-4 delims=/ " %%i in ('date /t') do set date=%%k%%i%%j
for /f "tokens=1-2 delims=/:" %%a in ('time /t') do set time=%%a%%b
powershell.exe -nologo -noprofile -command "& { Add-Type -A System.IO.Compression.FileSystem; [IO.Compression.ZipFile]::CreateFromDirectory('bin', 'bin-%date%_%time%.zip'); }"
xcopy bin-%date%_%time%.zip c:\temp
The problem is with the output of time /t which looks like that:
01:00 AM
And that causes the filename to be:
bin-20170412-0100 AM.zip
which is a problem.
I want to omit the " AM" from the time variable, how can it be done?
Because you obviously have no issue with powershell usage, replace those first two lines with:
For /F %%A In ('Powershell -C "Get-Date -Format yyyyMMdd_HHmm"'
) Do Set "archive=bin-%%A.zip"
You then have your full archive file name set in the variable %archive% for use in your following commands.

Batch file assign returned values from a command into a variable (from powershell)

i am refering to this question
ASSIGN win XP commandline output to variable
i am trying to use it on a powershell code segment
so i typed
powershell date (get-date).AddDays(-1) -format yyyyMMdd
and confirm it returns like
20100601
but then if i tried to
for /f "tokens=*" %a in ('powershell date get-date -format yyyyMMdd
') do set var=%a
then it failed to work as expected. how can i transfer the date to a variable?
Maybe
for /f "tokens=*" %a in ('powershell "get-date; get-date -format yyyyMMdd"') do set var=%a
is what you wanted.