how to pass variable from PowerShell to batch variable - powershell

I call the powershell command in batch and want to save the $tmpVersion to batch variable "version".
set version = powershell.exe -Command "$tmpVersion = (Get-ItemProperty 'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\myapp').DisplayVersion;"

You can use a For loop to save the result of a command as a variable:
powershell.exe example:
#Echo Off
Set "RegRoot=HKLM"
Set "RegKey=SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\myapp"
Set "RegVal=DisplayVersion"
Set "Version="
For /F %%A In (
'PowerShell -NoP -NoL "(GP '%RegRoot%:%RegKey%').%RegVal%" 2^>Nul'
) Do Set "Version=%%A"
If Not Defined Version Exit /B
Echo %Version%
Pause
reg.exe example:
#Echo Off
Set "RegRoot=HKLM"
Set "RegKey=SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\myapp"
Set "RegVal=DisplayVersion"
Set "Version="
For /F "Tokens=2*" %%A In ('Reg Query "%RegRoot%\%RegKey%" /V "%RegVal%" 2^>Nul'
) Do Set "Version=%%B"
If Not Defined Version Exit /B
Echo %Version%
Pause
WMIC.exe example:
#Echo Off
Set "RegRoot=&H80000002"
Set "RegKey=SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\myapp"
Set "RegVal=DisplayVersion"
Set "Version="
For /F Tokens^=2Delims^=^" %%A In ('WMIC Class StdRegProv
Call GetStringValue hDefKey^="%RegRoot%" sSubKeyName^="%RegKey%"
sValueName^="%RegVal%" 2^>Nul') Do Set "Version=%%A"
If Not Defined Version Exit /B
Echo %Version%
Pause

Related

Batch file to rename based on size on disk

I was going to make a batch script to share for ex-Dropbox account holders that will go through and rename a file OR folder if the size on disk is > 1 byte.
Using other forums I've managed to come up with the below.
#ECHO OFF
setlocal
set maxbytesize=1
FOR /F %%i IN ('PowerShell -ExecutionPolicy Bypass -File "FileSizeOnDisk.ps1" "E:\Desktop\Folder"') DO set SizeonDisk=%%i AND if %SizeonDisk% LSS %maxbytesize% (ren *.* *.*-DELETED)
EXIT
I just need help to loop the powershell command for every file, folder and files in a folder. I don't know how to properly place 2 commands after a DO and can't figure out the code to get it to work on multiple files.
#ECHO OFF
setlocal ENABLEDELAYEDEXPANSION
for /f "delims=" %%o in ('dir /b /a-d "nameofdirectorytoscan\filemask"') do
FOR /F %%i IN ('PowerShell -ExecutionPolicy Bypass -File "FileSizeOnDisk.ps1" "nameofdirectorytoscan\%%o"') DO set "Jumba#%%o=%%i"
set size#
pause
The result is a set of variables named Jumba#nameoffile with values of filesize as returned from Powersmell.
You can then scan the list using
for /f "tokens=2,3delims=#=" %%b in ('set Jumba#') do echo name=%%b, size=%%c

Windows / Powershell get Program Version into variable

I'm close but not there. I can get the version of my application via powershell, but it's got a bunch of text along with it.
This command:
powershell -NoLogo -NoProfile -Command ^
(get-item -Path 'c:\myapp.exe').VersionInfo ^| ^
Format-List -Force | findstr "ProductVersion" > c:\version.txt
produces (in a text file):
ProductVersion : 1.6.7.0
Is it possible via a single command in powershell to split it? I can't run ps scripts in my environment. But if I could, I would run this:
$mystr = (get-item -Path 'c:\myapp.exe').VersionInfo | Format-List -Force | findstr ProductVersion
$arr = $mystr -split ": "
$arr[1]
Is there a way to put this on a single line and put it into a environment (batch) variable?
Given your provided method, with some modification, perhaps this would do it?
#Echo Off
For /F "Delims=" %%A In ('Powershell -C^
"(GI 'C:\myapp.exe').VersionInfo.ProductVersion"') Do Set "PV=%%A"
Echo=%PV%
Pause
Mayhap
| for /f "tokens=3" %%a in ('findstr "ProductVersion"') do echo %%a>filename
or
| for /f "tokens=3" %%a in ('findstr "ProductVersion"') do set "prodver=%%a"
or
| for /f "tokens=3" %%a in ('findstr "ProductVersion"') do setx prodver "%%a"
but no guarantees. Note the setx version may establish a registry entry for future process instances, not for the current instance. /m would need to be added to make it a HKLM instead of a HKCU variable (if it works)
You can also use WMIC to get version of your application :
#echo off
Title Get File Version of any Application using WMIC
Set "Version="
Set "AppFullPath=%Windir%\notepad.exe"
Call :Get_AppName "%AppFullPath%" AppName
Call :Add_backSlash "%AppFullPath%"
Call :GetVersion %Application% Version
If defined Version (
echo Vesrion of %AppName% ==^> %Version%
)
pause>nul & Exit
::*******************************************************************
:Get_AppName <FullPath> <AppName>
Rem %1 = FullPath
Rem %2 = AppName
for %%i in (%1) do set "%2=%%~nxi"
exit /b
::*******************************************************************
:Add_backSlash <String>
Rem Subroutine to replace the simple "\" by a double "\\" into a String
Set "Application=%1"
Set "String=\"
Set "NewString=\\"
Call Set "Application=%%Application:%String%=%NewString%%%"
Exit /b
::*******************************************************************
:GetVersion <ApplicationPath> <Version>
Rem The argument %~1 represent the full path of the application
Rem without the double quotes
Rem The argument %2 represent the variable to be set (in our case %2=Version)
FOR /F "tokens=2 delims==" %%I IN (
'wmic datafile where "name='%~1'" get version /format:Textvaluelist 2^>^nul'
) DO FOR /F "delims=" %%A IN ("%%I") DO SET "%2=%%A"
Exit /b
::*******************************************************************
Just use the ProductVersion property on the VersionInfo object and assign the result to an environment variable:
$ENV:MyEnvVariable = (get-item -Path 'c:\myapp.exe').VersionInfo.ProductVersion

Batch Script - (Stop services, move log files to other directory, append date once move)

I'm a newbie in batch scripting. How can i add a currentdate on the filename once i move the files to other directory? Can you please check my code below? Thanks!
This is how it works:
-- I need to copy some files to other directory in order to kill the running processes which are (dsst)
-- once the dsst is not running, it should stop the GESWCPAServer and delete the copied files in c:temp
-- Next, copy the logfiles from C:\LOGFILES to C:\LOGFILES\Archive.
-- after the files has been copied. it will now start the services.
Thanks!
-------------------------------------------------------------------
#ECHO off
copy D:\fp_swenv\cg_fp\config\*.magik c:\temp
sc stop GESWCPAServer
:loop
echo checking for task list
tasklist /NH /FI "IMAGENAME eq dsst_writer_acp.exe" | find /I "dsst_writer_acp.exe"
rem tasklist /NH /FI "IMAGENAME eq textpad.exe" | find /I "textpad.exe"
if %ERRORLEVEL% == 0 goto sleeploop
goto finish_up
:sleeploop
echo Sleeping 10secs
sleep 10
goto loop
:finish_up
del c:\temp\*.magik
sc stop GESWDisptcher51
sc stop GESWCPAClient
sleep 10
set logpath1="C:\LOGFILES"
set arcpath1="C:\LOGFILES\Archive"
c:
cd %logpath1%
FORFILES /D -1 /M *.log /C "cmd /c move #path %arcpath1%"
cd /D %arcpath1%
sc start GESWCPAServer
sleep 10
echo checking for task list
tasklist /NH /FI "IMAGENAME eq dsst_writer_acp.exe" | find /I "dsst_writer_acp.exe"
rem tasklist /NH /FI "IMAGENAME eq textpad.exe" | find /I "textpad.exe"
if %ERRORLEVEL% == 1 goto sleeploop
sc start GESWDisptcher51
sc start GESWCPAClient
#ECHO ON
---------------------------------------------------------------------------
Please check if this works -
Replace your below code with my code.
set logpath1="C:\LOGFILES"
set arcpath1="C:\LOGFILES\Archive"
c:
cd %logpath1%
FORFILES /D -1 /M *.log /C "cmd /c move #path %arcpath1%"
My Code -
EDIT - Added the zip option as requested by OP in the comment.
#echo OFF
set logpath1=c:\Logfiles
set arcpath1=c:\Logfiles\archive
cd /d %logpath1%
for /f %%x in ('wmic os get localdatetime ^| findstr /b [0-9]') do set TS=%%x
set yyyy=%TS:~0,4%
set mm=%TS:~4,2%
set dd=%TS:~6,2%
set hh=%TS:~8,2%
set min=%TS:~10,2%
set timestamp=%dd%-%mm%-%yyyy%_%hh%-%min%
for /f %%i in ('dir /b *.log') do call :moveandrename "%%i"
goto :jump
:moveandrename
set filename=%~n1
set fileextn=%~x1
move /y %filename%%fileextn% %arcpath1%\%filename%-%timestamp%%fileextn% >nul 2>&1
goto :eof
:jump
cd %arcpath1%
C:\Program Files\WinZip\wzzip.exe -a Archive_%timestamp%.zip *.log
if not %errorlevel% EQU 0 echo.Zip operation failed on %timestamp% >>zipresult.txt & goto :eof
del *.log
:eof
Cheers, G

How to set variable with the result of findstr

I am trying to write a batch file which searches for pdf files and finds how many pages they have and loop all pages.
I wrote the following. I can find the files, I can even find the pagecounts with a tool named pdftk. The results is as below.
C:\Users\test\Documents\fishes\Fish_1.pdf
NumberOfPages: 5
How can I set a variable which has the value of 5?
#ECHO off
for /R %%i IN (*.pdf) DO (
ECHO %%i
"C:\Program Files (x86)\PDF Labs\PDFtk Server\bin\pdftk.exe" %%i dump_data | findstr NumberOfPages
set pagecount = findstr NumberOfPages ???
FOR /L %%j IN (1,1,%pagecount%) DO (
ECHO "page " + %%j
)
)
You were already 90% there. Use the FOR /F command to process the results of a command. Type HELP FOR from the command prompt for more info.
for /f "tokens=2" %%A in (
'"C:\Program Files (x86)\PDF Labs\PDFtk Server\bin\pdftk.exe" %%i dump_data ^| findstr NumberOfPages'
) do set numberOfPages=%%A

Problems finding the value of registry keys

I'm attempting to make a batch script to uninstall various programs with little involvement from the user (Only saying I want to uninstall Group A (Say, Google Chrome and Microsoft Office)), Partially for work and partially for fun and practice. This itself isn't impossible, I can already do this by calling msiexec and pointing it to the uninstall location in the registry (msiexec /x {xxxxx-xxxxx-xxxxxx-xxxx}).
The only problem with this is that this means that whenever the program changes registry keys, as will often happen with updates, I have to find the path again. So, I'm trying to run a piece of code that will search through the HKLM\SOFTWARE\Mincrosoft\Windows\CurrentVersion\Uninstall registry location, and whenever the DisplayName returns a certain value, not necessarily exact (Say "Chrome"), it stores the registry location?(The part that would be put in {xxxxxxx-xxxxxxx-xxxxxxx-xxxxxx}).
This way, the program simply finds the programs and stores their locations so that they can be uninstalled with it as a variable. I have tried, but as far as I know using reg query requires the full location. using reg query HKLM /f returns no results. I've tried a whole range of different workarounds, but nothing seems to work.
Here is a basic version of my code (I am neglecting to post the full version because much of it is repeated. It's mostly just case where's and if then statements)
#echo off
:start
echo Hello
echo.
1: Uninstall Chrome
set /p choice="Enter Choice: "
if "%choice%"=="1" goto uninstall_chrome
:uninstall_chrome
reg query HKLM /f Chrome /t REG_SZ
::msiexec /x{uninstall location for the program}
Thanks.
::UPDATE::
I figured it out. By using some of Rob van der Woude's code, I am now able to do it. The code to do so is:
CALL :Uninstall "Program Name"
:Uninstall
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "tokens=* %%A IN ('REG QUERY HKLM\SOFWARE\Microsoft\Windows\CurrentVersion\Uninstall /F "%~1" /D /S 2^>NUL ^| FINDSTR /R /B /C:"HKEY_"') DO (
REG QUERY "%%~A" /F DisplayName /V /E | FINDSTR /R /I /C:" DisplayName .* .*%~1" >NUL 2>&1
FOR /F "tokens=2*" %%B IN ('REG QUERY "%%~A" /F DisplayName /V /E 2^>NUL ^| FIND /I " DisplayName "') DO ECHO Program Name = %%C
FOR /F "tokens=7 delims=\" %%B IN ("%%~A") DO ECHO Unique Identifier = %%B
FOR /F "tokens=2*" %%B IN ('REG QUERY "%%~A" /F UninstallString /V /E ^| FIND /I " UninstallString "') DO %%C /qb
)
ENDLOCAL
This will output the programs name and unique identifier, then uninstall the program, without user input ("Do you want to uninstall x?")
I figured it out. By using some of Rob van der Woude's code, I am now able to do it. The code to do so is:
CALL :Uninstall "Program Name"
:Uninstall
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "tokens=* %%A IN ('REG QUERY HKLM\SOFWARE\Microsoft\Windows\CurrentVersion\Uninstall /F "%~1" /D /S 2^>NUL ^| FINDSTR /R /B /C:"HKEY_"') DO (
REG QUERY "%%~A" /F DisplayName /V /E | FINDSTR /R /I /C:" DisplayName .* .*%~1" >NUL 2>&1
FOR /F "tokens=2*" %%B IN ('REG QUERY "%%~A" /F DisplayName /V /E 2^>NUL ^| FIND /I " DisplayName "') DO ECHO Program Name = %%C
FOR /F "tokens=7 delims=\" %%B IN ("%%~A") DO ECHO Unique Identifier = %%B
FOR /F "tokens=2*" %%B IN ('REG QUERY "%%~A" /F UninstallString /V /E ^| FIND /I " UninstallString "') DO %%C /qb
)
ENDLOCAL
This will output the programs name and unique identifier, then uninstall the program, without user input ("Do you want to uninstall x?")