I have the following script I have cobbled together to help with backups for Autodesk Vault Professional:
#echo off
setlocal enableDelayedExpansion
echo setting up variables...
SET VAULTBACKUPPATH=C:\Users\alex.fielder\Dropbox\Graitec\Vault Backup
SET LOGFILEPATH=C:\Users\alex.fielder\Dropbox\Graitec\GRA0387AF_Vault_Backup.txt
SET SEVENZIPLOGFILEPATH=C:\Users\alex.fielder\Dropbox\Graitec\GRA0387AF_Zip_Log.txt
SET SEVENZIPPATH=C:\ProgramData\chocolatey\bin\7za.exe
SET ADMSCONSOLEPATH=C:\Program Files\Autodesk\ADMS Professional 2017\ADMS Console\Connectivity.ADMSConsole.exe
SET NUMDAYSBACKUPTOKEEP=-15
SET MINMEMVALUE=2000000
SET MINDRIVESPACE=10000000
echo testing available system resources
for /f "skip=1" %%p in ('wmic os get freephysicalmemory') do (SET AVAILABLESYSTEMMEMORY=%%p)
rem echo "%AVAILABLESYSTEMMEMORY%"
if !AVAILABLESYSTEMMEMORY! LSS %MINMEMVALUE% (
echo "%DATE% %TIME%: low available system memory, exiting" >> %LOGFILEPATH%
exit /b 1
) ELSE (
echo "%DATE% %TIME%: sufficient system memory, continuing" >> %LOGFILEPATH%
)
echo checking free disk space on C:\
FOR /F "usebackq tokens=3" %%s IN (`DIR C:\ /-C /-O /W`) DO (
SET FREE_SPACE=%%s
)
if !FREE_SPACE! LSS !MINDRIVESPACE! (
echo "%DATE% %TIME%: low space on C:, exiting" >> %LOGFILEPATH%
exit /b 1
) ELSE (
echo "%DATE% %TIME%: sufficient space on C:\, continuing" >> %LOGFILEPATH%
)
REM echo stopping and disabling Sophos
REM wmic service where "caption like 'Sophos%%'" call Stopservice
REM wmic service where "caption like 'Sophos%%' and Startmode<>'Disabled'" call ChangeStartmode Disabled
echo pausing Dropbox, Searchindexer, Everything using the sysinternals tool PSSuspend!
pssuspend dropbox
pssuspend searchindexer
pssuspend everything
echo changing to working folder
cd "C:\Users\alex.fielder\Dropbox\Graitec\Vault Backup"
echo removing existing backup directories if there are any present
for /f %%i in ('dir /a:d /b Vault*') do rd /s /q %%i
echo performing vault backup from Vault Professional 2017
REM -WA is short for Windows Authentication - does not work with Vault basic!
call "%ADMSCONSOLEPATH%" -Obackup -B"%VAULTBACKUPPATH%" -WA -VAL -DBSC -S -L"%LOGFILEPATH%"
echo Beginning zip and verification using 7zip %date% - %time% >> "%SEVENZIPLOGFILEPATH%"
for /f "Tokens=*" %%i in ('dir /a:d /b Vault*') do (
echo creating a .7z archive of latest backup using the 7zip command line.
call "%SEVENZIPPATH%" a -t7z "%%i.7z" "%%i" -mmt -mx1
echo testing the archive - results can be found in the Vault backup log file!
call "%SEVENZIPPATH%" t "%%i.7z" -mmt -r >> "%SEVENZIPLOGFILEPATH%"
)
echo completed zip and verification using 7zip %date% - %time% >> "%SEVENZIPLOGFILEPATH%"
REM for /f "Tokens=*" %%i in ('dir /b Vault*.7z') do call "%SEVENZIPPATH%" t "%%i" -mmt -r >> "%SEVENZIPLOGFILEPATH%"
echo removing backup directory to prevent Dropbox syncing it to the cloud.
for /f %%i in ('dir /a:d /b Vault*') do rd /s /q %%i
echo removing backups older than 30 days to prevent Dropbox space getting eaten up unecessarily.
forfiles /p "%VAULTBACKUPPATH%" /s /m *.* /d "%NUMDAYSBACKUPTOKEEP%" /c "cmd /c del #path"
echo resuming Dropbox, Searchindexer, Everything and Sophos
pssuspend -r dropbox
pssuspend -r searchindexer
pssuspend -r everything
REM wmic service where "caption like 'Sophos%%' and Startmode='Disabled'" call ChangeStartmode Automatic
REM wmic service where "caption like 'Sophos%%'" call Startservice
echo finished!
All of this was working fine except I added this section to check system resources/space on C: Drive and I can't get the syntax correct for it:
echo testing available system resources
for /f "skip=1" %%p in ('wmic os get freephysicalmemory') do (SET AVAILABLESYSTEMMEMORY=%%p)
rem echo "%AVAILABLESYSTEMMEMORY%"
if !AVAILABLESYSTEMMEMORY! LSS %MINMEMVALUE% (
echo "%DATE% %TIME%: low available system memory, exiting" >> %LOGFILEPATH%
exit /b 1
) ELSE (
echo "%DATE% %TIME%: sufficient system memory, continuing" >> %LOGFILEPATH%
)
echo checking free disk space on C:\
FOR /F "usebackq tokens=3" %%s IN (`DIR C:\ /-C /-O /W`) DO (
SET FREE_SPACE=%%s
)
if !FREE_SPACE! LSS !MINDRIVESPACE! (
echo "%DATE% %TIME%: low space on C:, exiting" >> %LOGFILEPATH%
exit /b 1
) ELSE (
echo "%DATE% %TIME%: sufficient space on C:\, continuing" >> %LOGFILEPATH%
)
Can anyone offer any pointers as to how I might correct this?
I did find this post:
Batch file :: if lss is not working properly
but as you can see above, I've tried several different variations and none have worked successfully.
Thanks,
Alex.
You could try a different approach and let WMI determine if below your minimum values.
#ECHO OFF
ECHO Setting up variables...
SET "LOGFILEPATH=C:\Users\alex.fielder\Dropbox\Graitec\GRA0387AF_Vault_Backup.txt"
SET "MINMEMVALUE=2000000"
SET "MINDRIVESPACE=10000000"
ECHO Testing available system resources
ECHO Checking free system memory
SET "FPM=sufficient system memory, continuing"
FOR /F "USEBACKQ EOL=F" %%A IN (`WMIC OS WHERE^
"FreePhysicalMemory < '%MINMEMVALUE%'" GET FreePhysicalMemory 2^>NUL`
) DO FOR %%B IN (%%A) DO SET "FPM=%%B"
IF NOT "%FPM%"=="sufficient system memory, continuing" (
SET "FPM=low available system memory, exiting")
ECHO "%DATE% %TIME%: %FPM%">>"%LOGFILEPATH%"
ECHO Checking free system drive space
SET "SFP=sufficient space on %SystemDrive%, continuing"
FOR /F "USEBACKQ EOL=F" %%A IN (`WMIC LOGICALDISK WHERE^
"DeviceID = '%SystemDrive%' AND FreeSpace < '%MINDRIVESPACE%'"^
GET FreeSpace 2^>NUL`) DO FOR %%B IN (%%A) DO SET "SFP=%%B"
IF NOT "%SFP%"=="sufficient space on %SystemDrive%, continuing" (
SET "SFP=low space on %SystemDrive%, exiting")
ECHO "%DATE% %TIME%: %SFP%">>"%LOGFILEPATH%"
PAUSE
Related
I am attempting to create a basic script that runs and checks for basic system info but I want the output to be formatted so the results are on the same line and easily readable.
#Echo Off
systeminfo | findstr /B /C:"OS Name" /C:"OS Version"
wmic cpu get name, status
systeminfo | findstr /C:"Total Physical Memory"
#echo off & setlocal ENABLEDELAYEDEXPANSION
SET "volume=C:"
FOR /f "tokens=1*delims=:" %%i IN ('fsutil volume diskfree %volume%') DO (
SET "diskfree=!disktotal!"
SET "disktotal=!diskavail!"
SET "diskavail=%%j"
)
FOR /f "tokens=1,2" %%i IN ("%disktotal% %diskavail%") DO SET "disktotal=%%i"& SET "diskavail=%%j"
ECHO(Total Space: %disktotal:~0,-9% GB
ECHO(Available Space: %diskavail:~0,-9% GB
systeminfo | find "System Boot Time:"
systeminfo | find "System Type:"
Echo Antivirus: & wmic /node:localhost /namespace:\\root\SecurityCenter2 path AntiVirusProduct Get DisplayName | findstr /V /B /C:displayName || echo No Antivirus installed
The main example of this would be the wmic command placing the result on the next line rather than the same line.
Also any tips of better ways of scripting what I currently have would be appreciated.
#echo off
setlocal
for /f "tokens=1,* delims=:" %%A in ('systeminfo') do (
if "%%~A" == "OS Name" (
call :print "%%~A" %%B
) else if "%%~A" == "OS Version" (
call :print "%%~A" %%B
call :cpu
) else if "%%~A" == "Total Physical Memory" (
call :print "%%~A" %%B
call :fsutil C:
) else if "%%~A" == "System Boot Time" (
call :print "%%~A" %%B
) else if "%%~A" == "System Type" (
call :print "%%~A" %%B
)
)
:next
call :antivirus
pause
exit /b
:print
setlocal enabledelayedexpansion
set "name=%~1"
if not defined name exit /b
set "name=%~1 "
set "full=%*"
set "full=!full:,=!"
set "data="
set "skip1="
for %%A in (!full!) do (
if not defined skip1 (
set "skip1=defined"
) else if not defined data (
set "data=%%~A"
) else (
set "data=!data! %%~A"
)
)
echo !name:~,30!: !data!
exit /b
:antivirus
setlocal enabledelayedexpansion
set "antivirus="
for /f "tokens=*" %%A in ('
2^>nul wmic /node:localhost
/namespace:\\root\SecurityCenter2 path AntiVirusProduct
Get DisplayName /value
^| findstr /i /b /c:"DisplayName" ^|^| echo No Antivirus installed
') do set "antivirus=%%~A"
if /i "!antivirus:~,12!" == "DisplayName=" set "antivirus=!antivirus:~12!"
call :print Antivirus "!antivirus!"
exit /b
:cpu
for /f "tokens=1,* delims==" %%A in ('wmic cpu get name^, status /value') do (
call :print "%%~A" %%B
)
exit /b
:fsutil
setlocal enabledelayedexpansion
2>nul >nul net session || exit /b
for /f "tokens=1,* delims=:" %%A in ('2^>nul fsutil volume diskfree %1') do (
set "name=%%~A"
set "value=%%~B"
call :print "!name:bytes=GBs!" !value:~,-9!
)
exit /b
The fsutil command outputs alittle different.
I chose an easy option if it is OK.
Unsure of antivirus output as you need both results of
installed or not to be sure.
It only runs systeminfo once to save time.
Look at set /? for information about substitution that
is used.
The net session command is used to test if script is run as Admin.
If not Admin, then fsutil will be skipped as it requires Admin.
Look at for /? for usage of the command that is used in the script.
Use of enabledelayedexpansion is used to prevent special
characters being exposed which may cause error otherwise.
And used in code blocks to delay expansion as needed.
Remove comma from value strings which get replaced with a space.
A comma is often used as thousands separator and numbers look odd
with a space instead. This occurs because of usage of a simple
for loop interpreting comma as a argument separator. Some other
chararters may also do this though perhaps a space maybe better
than none in their case.
The output of WMIC is unicode !
The trailing <CR> can be removed by passing the value through another FOR /F loop. This also removes the phantom "blank" line (actually a <CR>)
#Echo Off
Call :GET_CPU name CPU_Name
Set "WMIC_Antivirus=wmic /node:localhost /namespace:\\root\SecurityCenter2 path AntiVirusProduct Get DisplayName ^| findstr /V /B /C:displayName"
#For /F "delims=" %%I in ('%WMIC_Antivirus%') do (
for /f "delims=" %%A IN ("%%I") DO SET "Antivirus=%%A"
)
echo CPU : %CPU_Name%
echo Antivirus : %Antivirus%
pause & exit
::----------------------------------------------------
:GET_CPU
Set "WMIC_CPU=wmic cpu get name /Value"
FOR /F "tokens=2 delims==" %%I IN (
'%WMIC_CPU% ^| find /I "%~1" 2^>^nul'
) DO FOR /F "delims=" %%A IN ("%%I") DO SET "%2=%%A"
Exit /b
::----------------------------------------------------
You can try to save the output into a text file :
#Echo Off
:::::::::::::::::::::::::::::::::::::::::
:: Automatically check & get admin rights
:::::::::::::::::::::::::::::::::::::::::
REM --> Check for permissions
Reg query "HKU\S-1-5-19\Environment" >nul 2>&1
REM --> If error flag set, we do not have admin.
if '%errorlevel%' NEQ '0' (
Echo.
ECHO **************************************
ECHO Running Admin shell... Please wait...
ECHO **************************************
goto UACPrompt
) else ( goto gotAdmin )
:UACPrompt
echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
set params = %*:"=""
echo UAC.ShellExecute "cmd.exe", "/c ""%~s0"" %params%", "", "runas", 1 >> "%temp%\getadmin.vbs"
"%temp%\getadmin.vbs"
del "%temp%\getadmin.vbs"
exit /B
:gotAdmin
::::::::::::::::::::::::::::
::START
::::::::::::::::::::::::::::
SetLocal EnableDelayedExpansion
set "Log=%~dp0Log.txt"
If exist "%Log%" Del "%Log%"
Call :GET_CPU name CPU_Name
Set "WMIC_Antivirus=wmic /node:localhost /namespace:\\root\SecurityCenter2 path AntiVirusProduct Get DisplayName ^| findstr /V /B /C:displayName"
#For /F "delims=" %%I in ('%WMIC_Antivirus%') do (
for /f "delims=" %%A IN ("%%I") DO SET "Antivirus=%%A"
)
(
Echo.
Echo ***************************** General infos ***********************************
Echo.
Echo Running under: %username% on profile: %userprofile%
Echo Computer name: %computername%
Echo.
systeminfo
Echo Operating System:
Echo PROCESSOR ARCHITECTURE : %PROCESSOR_ARCHITECTURE%
echo NUMBER_OF_PROCESSORS : %NUMBER_OF_PROCESSORS%
echo PROCESSOR_IDENTIFIER : %PROCESSOR_IDENTIFIER%
echo PROCESSOR_LEVEL : %PROCESSOR_LEVEL%
echo PROCESSOR_REVISION : %PROCESSOR_REVISION%
echo OS TYPE : %OS%
echo(
echo Program files path : %Programfiles%
echo Program files(86^) path : %Programfiles(86^)%
echo ProgramW6432 path : %ProgramW6432%
echo PSModulePath : %PSModulePath%
echo SystemRoot : %SystemRoot%
echo Temp Folder : %Temp%
echo CPU : !CPU_Name!
echo Antivirus : !Antivirus!
Echo.
Echo **************************** Drives infos *************************************
Echo.
Echo Listing currently attached drives:
wmic logicaldisk get caption,description,volumename | find /v ""
Echo.
Echo Physical drives information:
for /F "tokens=1-3" %%A in ('fltmc volumes^|find ":"') do echo %%A %%B %%C
)>>"%Log%"
Start "" "%Log%" & exit
::----------------------------------------------------
:GET_CPU
Set "WMIC_CPU=wmic cpu get name /Value"
FOR /F "tokens=2 delims==" %%I IN (
'%WMIC_CPU% ^| find /I "%~1" 2^>^nul'
) DO FOR /F "delims=" %%A IN ("%%I") DO SET "%2=%%A"
Exit /b
::----------------------------------------------------
UPDATE
I removed the tokens=4 and it started outputting data. It is not skipping past the FOR LOOP. I was skipping too far ahead with the tokens. I am still a little confused as to why it works as a single batch and not from this batch but now at least I know what the issue was. Thank you to everyone that was looking into this for me.
I am writing a script to copy over data from one computer to another. The issue is that it is skipping over the FOR LOOP that I am calling from another FOR LOOP. If you are testing the script it requires two PC's and a mapped T: drive to somewhere on the second computer. I can write the script so it looks for an external drive if that is more helpful to someone.
FOR /F "tokens=4 skip=1" %%a in ('REG QUERY "%_regshell%" /v "%_regdesktop%"') DO (
SET _dt=%%a
echo robocopy "!_dt!" "!_NetworkDrive!\!_fndesktop!" !_params!
echo attrib -h -r "!_NetworkDrive!\!_fndesktop!"
)
If I write the FOR LOOP above in a batch by itself and just echo out %%a then it works without a problem. In this, I can see that it is indeed calling :_backup but it skips directly over the FOR Loop and I am not sure why. I have written scripts like this many times but never had any that just completely ignore the FOR Loop. Can anyone take a look and assist? Thank you.
#echo off
:: Set Variables
SET _driveID=T:
SET _params=/Z /E /COPY:DT /R:1 /W:0 /XD LocalService NetworkService temp "temporary internet files" winsxs Content.IE5 cache /XF ntuser.* *.tmp /XJ /FP /NC /NS /NP /NJH
SET _regshell=HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
SET _regdesktop=Desktop
:: Set Current Directory
pushd %SystemDrive%\
:: Start Menu - Create Choices and Options. Send to various places to perform the actions.
:_start
cls
ECHO Please type either option 2 or 3 and then press ENTER on the keyboard?
Echo 2. TRANSFER FILES FROM DESKTOP TO LAPTOP
Echo 3. EXIT THE PROGRAM
echo.
set /p choice=Enter Number:
if '%choice%'=='2' goto _desktopToLaptop
if '%choice%'=='3' goto :EOF
echo "%choice%" is not a valid option. Please try again
echo.
goto _start
:: Detect Drive Letters
:_desktopToLaptop
setlocal EnableDelayedExpansion
FOR /F "usebackq skip=1" %%a IN (`WMIC logicaldisk where DeviceID^="%_driveID%" get caption`) DO (
SET _NetworkDrive=%%a
if exist %%a (
CALL :_backup
goto :EOF
) else (
echo.
echo The laptop does not appear to be attached to the computer.
echo.
pause
goto :EOF
)
)
:_backup
:: Detect the folder locations and begin to backup each location to the laptop.
FOR /F "tokens=4 skip=1" %%a in ('REG QUERY "%_regshell%" /v "%_regdesktop%"') DO (
SET _dt=%%a
echo robocopy "!_dt!" "!_NetworkDrive!\!_fndesktop!" !_params!
echo attrib -h -r "!_NetworkDrive!\!_fndesktop!"
)
echo we are past the for loop
pause
:: Return to directory program was run from
popd
If anyone else runs into this issue or something similar, check your tokens and your skip. Mine worked just fine as a single batch but when I included as a call I had to change the options from tokens=4 skip=1 to tokens=3* skip=2 in order to get the correct output.
The correct tokens in that FOR LOOPS should be:
#echo off
:: Set Variables
SET _driveID=T:
SET _params=/Z /E /COPY:DT /R:1 /W:0 /XD LocalService NetworkService temp "temporary internet files" winsxs Content.IE5 cache /XF ntuser.* *.tmp /XJ /FP /NC /NS /NP /NJH
SET _regshell=HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
SET _regdesktop=Desktop
:: Set Current Directory
pushd %SystemDrive%\
:: Start Menu - Create Choices and Options. Send to various places to perform the actions.
:_start
cls
ECHO Please type either option 2 or 3 and then press ENTER on the keyboard?
Echo 2. TRANSFER FILES FROM DESKTOP TO LAPTOP
Echo 3. EXIT THE PROGRAM
echo.
set /p choice=Enter Number:
if '%choice%'=='2' goto _desktopToLaptop
if '%choice%'=='3' goto :EOF
echo "%choice%" is not a valid option. Please try again
echo.
goto _start
:: Detect Drive Letters
:_desktopToLaptop
setlocal EnableDelayedExpansion
FOR /F "usebackq skip=1" %%a IN (`WMIC logicaldisk where DeviceID^="%_driveID%" get caption`) DO (
SET _NetworkDrive=%%a
if exist %%a (
CALL :_backup
goto :EOF
) else (
echo.
echo The laptop does not appear to be attached to the computer.
echo.
pause
goto :EOF
)
)
:_backup
:: Detect the folder locations and begin to backup each location to the laptop.
FOR /F "tokens=3* skip=2" %%a in ('REG QUERY "%_regshell%" /v "%_regdesktop%"') DO (
SET _dt=%%a
echo robocopy "!_dt!" "!_NetworkDrive!\!_fndesktop!" !_params!
echo attrib -h -r "!_NetworkDrive!\!_fndesktop!"
)
echo we are past the for loop
pause
:: Return to directory program was run from
popd
Given that the main issue in your script appears to be the setting of a variable to the data within the defined registry key and value, you could use:
Set "_regshell=HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders"
Set "_regdesktop=Desktop"
Set "_dt="
For /F "EOL=H Tokens=2*" %%A In ('Reg Query "%_regshell%" /V "%_regdesktop%"'
) Do Set "_dt=%%~B"
If Not Defined _dt GoTo :EOF
Echo "%_dt%"
I have batch script that does check:
create log file with Date and Time format
oracle listener check
oracle db status check
disk space check
#echo off
set ORACLE_SID=equis01
REM set result_file = %Date:~4,2%.%Date:~7,2%.%Date:~10,4%
set HH=%TIME: =0%
set HH=%HH:~0,2%
set MI=%TIME:~3,2%
set SS=%TIME:~6,2%
REM for /F "tokens=2-4 delims=/ " %%i in ('date /t') do set result_file="%%j"."%%i"."%%k"_%HH%.%MI%.%SS%_"DBXXX".log
if exist %result_file% (
del %result_file%
)
>%result_file% (
echo Oracle Listener Status:
echo ========================================
echo.
lsnrctl status
echo.
echo.
echo.
echo Oracle Database Status:
echo ========================================
echo.
(
echo #monitoring.sql
) | sqlplus /
)
echo.
echo.
echo.
echo Disk Space:
echo ========================================
for /f "skip=1 usebackq delims==" %%i in (`wmic logicaldisk where "mediatype='12'" get caption`) do (
call :doit %%i >> "%result_file%"
)
goto :eof
:doit
set driveletter=%1
if {%driveletter%}=={} goto :EOF
for /f "usebackq delims== tokens=2" %%x in (`wmic logicaldisk where "DeviceID='%driveletter%'" get FreeSpace /format:value`) do set FreeSpace=%%x
for /f "usebackq delims== tokens=2" %%x in (`wmic logicaldisk where "DeviceID='%driveletter%'" get Size /format:value`) do set Size=%%x
set FreeMB=%FreeSpace:~0,-10%
set SizeMB=%Size:~0,-10%
set /a Percentage=100 * FreeMB / SizeMB
echo %driveletter% %FreeMB% GB out of %SizeMB% GB Total - %Percentage%%% free
rem echo exit
for %%a in (*.log*) do "C:\Program Files\7-Zip\7z.exe" a -tzip "%result_file%" "%%a"
Description of problem:
after running the code - it must archive the log file.
but the message says:
C: 25 GB out of 42 GB Total - 59% free
System ERROR:
The process cannot access the file because it is being used by another process.
ERROR: 11.10.2016_17.47.31_DBXXX.log
Can not open the file as archive
D: 88 GB out of 107 GB Total - 82% free
System ERROR:
The process cannot access the file because it is being used by another process.
ERROR: 11.10.2016_17.47.31_DBXXX.log
Can not open the file as archive
E: 415 GB out of 436 GB Total - 95% free
System ERROR:
The process cannot access the file because it is being used by another process.
ERROR: 11.10.2016_17.47.31_DBXXX.log
Can not open the file as archive
How to solve the problem?
For the WMICpart you can simplify your code like this :
#echo off
setlocal enabledelayedexpansion
for /f %%i in ('wmic logicaldisk where "mediatype=12" get caption ^| findstr ":"') do (
for /f %%x in ('wmic logicaldisk where "DeviceID='%%i'" get Size^,FreeSpace ^/format:value ^| findstr [0-9]') do set %%x
call:next %%i !Freespace:~0,-10! !Size:~0,-10!
)
exit/b
:next
set /a percentage=(%2 * 100) / %3
echo %1 - %2 Gb of %3 Gb [!Percentage!^% Free]
Then just add the other element, It will be easier to debug.
I have recently started diving into writing Batch files and I have a question. I'm trying to create a file that checks to see if my secondary monitor is connected and than if it is switches the primary display to the secondary screen. (Yes I do know about the windows+P shortcut)...
So far I have figured out that "DisplaySwitch.exe /external" sets the default display to the secondary monitor but I cannot find out how to detect whether the display is there first.
-Cheers, Luke
With Windows 10, may be just a call to:
wmic desktopmonitor get DeviceID
output:
DeviceID
DesktopMonitor1
DesktopMonitor2
More details about monitor with :
wmic desktopmonitor get
By calling a powershell from the cmd the following will get the number of monitors:
powershell -Command "exit (Get-CimInstance -Namespace root\wmi -ClassName WmiMonitorBasicDisplayParams | Select-String -Pattern 'InstanceName').length"
set nMons=%ERRORLEVEL%
One possible way is to use dxdiag though it is not the fastest way:
#echo off
del ~.txt /q /f >nul 2>nul
dxdiag /t ~
w32tm /stripchart /computer:localhost /period:1 /dataonly /samples:3 >nul 2>&1
setlocal enableDelayedExpansion
set currmon=1
for /f "tokens=2 delims=:" %%a in ('find "Current Mode:" ~.txt') do (
echo Monitor !currmon! : %%a
set /a currmon=currmon+1
)
endlocal
del ~.txt /q /f >nul 2>nul
this will print the resolutions of all monitors.
Update:
dxdiag prints info about all monitors so you can check if there are more than one monitors:
#echo off
del ~.txt /q /f >nul 2>nul
start "" /w dxdiag /t ~
for /f "tokens=1* delims=:" %%a in ('find /c "Current Mode:" "~.txt"') do (
set /a "number_of_monitors=%%b"
rem echo #%%b#
)
rem exit /b 0
echo %number_of_monitors%
rem :---- if it needed -----:
if defined number_of_monitors ( if %number_of_monitors% GTR 1 ( echo second monitor connected ) else (echo only one monitor connected ))
del ~.txt /q /f >nul 2>nul
#npocmaka's answer didn't quite work for me, but this variation of his code did (Windows 10):
rem #echo off
del %TEMP%\dxdiag.txt /q /f >nul 2>nul
start "" /w dxdiag -64bit -t %TEMP%\dxdiag.txt
for /f "tokens=3" %%f in ('find /c"Monitor Name:" %TEMP%\dxdiag.txt') do set MONITOR_COUNT=%%f
if defined MONITOR_COUNT ( if %MONITOR_COUNT% GTR 1 ( echo second monitor connected ) else (echo only one monitor connected ))
del %TEMP%\monitors.txt /q /f >nul 2>nul
SET monitors=monitors.txt
SET nMons=0
MultiMonitorTool.exe /scomma "%monitors%"
FOR /F "skip=1 tokens=9 delims=," %%a IN (%monitors%) DO IF %%a GTR 0 SET /A nMons += 1
echo Number of monitors: %nMons%
MultiMonitorTool
Here is quick way to get connected monitors count via powershell
$m = Get-PnpDevice -Class Monitor -Status OK | measure; $m.Count
I'm trying to get System information for My Installer script. Here's My simple batch script.
#echo off
setlocal enableextensions enabledelayedexpansion
echo System information now loading...
for /f "delims=" %%l in ('wmic os get * /format:list') do >nul 2>&1 set "OS_%%l"
for /f "delims=" %%l in ('wmic cpu get * /format:list') do >nul 2>&1 set "CPU_%%l"
set /a FreeSpace=0
for /f "skip=1 tokens=1,2" %%A in ('wmic logicaldisk get FreeSpace') do (
if "%%B" neq "" for /f %%N in ('powershell !FreeSpace!+%%A') do (
set FreeSpace=%%N
)
)
echo wsh.echo cdbl(%FreeSpace%)/1024/1024/1024 > %temp%.\tmp.vbs
for /f %%a in ('cscript //nologo %temp%.\tmp.vbs') do set /a HDD_FreeSpace=%%a
del %temp%.\tmp.vbs
set /a RAM_Memory=%OS_TotalVisibleMemorySize%/1024
set /a CPU_Speed=%CPU_NumberOfLogicalProcessors%*%CPU_CurrentClockSpeed%
>>SystemInfo.log 2>&1 echo Operating System: %OS_Caption%%OS_OSArchitecture% (%OS_Version%, Build %OS_BuildNumber%)
>>SystemInfo.log 2>&1 echo Processor: %CPU_Name%
>>SystemInfo.log 2>&1 echo RAM: %RAM_Memory% MB
>>SystemInfo.log 2>&1 echo HDD Total Free Space: %HDD_FreeSpace% GB
>>SystemSource.log 2>&1 echo %OS_Version%
>>SystemSource.log 2>&1 echo %CPU_Speed%
>>SystemSource.log 2>&1 echo %OS_TotalVisibleMemorySize%
>>SystemSource.log 2>&1 echo %FreeSpace%
exit
Output SystemInfo.log
Operating System: Microsoft Windows 7 Professional 32-bit (6.1.7601, Build 7601)
Processor: Intel(R) Core(TM)2 CPU 6600 # 2.40GHz
RAM: 3069 MB
HDD Total Free Space: 61 GB
Output SystemSource.log
6.1.7601
4784
3143284
66427858944
Everything seems good. But batch script has shown "Missing operator", I don't have any idea why a message has been shown but all the outputs are correct.
It will crash or not?
take away the #echo off. You'll see that it's the line sets that set /a HDD_FreeSpace=375.6279296875. The Period is invalid
c:\>for /F %a in ('cscript //nologo C:\Users\PREET~1.SAN\AppData\Local\Temp.\tmp.vbs') do set /a HDD_FreeSpace=%a
c:\>set /a HDD_FreeSpace=375.625617980957
Missing operator.
c:\>del C:\Users\PREET~1.SAN\AppData\Local\Temp.\tmp.vbs
Try it with *SET * instead