ok - i'll see if I can add a code (not so) snippet...
@echo off
setlocal enabledelayedexpansion
REM ************************************************************************************************
REM * File: get-versions.bat
REM * Purpose: Build a csv file of versions of all NetBackup clients, and servers.
REM *
REM * Vers Date Who Description
REM * ---- ---- --- -----------
REM * v0.01 6-AUG-2009 sdo Original version.
REM * v0.02 20-SEP-2010 sdo Updates for v6.5.6.
REM * v0.03 4-APR-2011 sdo Updates for v7.0.1.
REM * v0.04 24-APR-2015 sdo Added more error checking.
REM * v0.05 25-APR-2015 sdo Retrieve binaries path, and build command paths.
REM ************************************************************************************************
REM * Disclaimer
REM * ----------
REM * This script was developed and tested using:
REM * - Windows 2008 R2 SP1
REM * - NetBackup Server v7.6.0.4
REM *
REM * This script is not endorsed, nor has it been tested, by Symantec. Neither the author, nor
REM * Symantec, shall accept any liability from any harm, loss, or damage caused by the use
REM * and/or mis-use of this script, either in its original form, or in a modified form. Use of
REM * this script in its original, or modified, form is entirely at the end user's own risk.
REM * This script is furnished on an example basis only, and may not be suitable for any given
REM * environment.
REM ************************************************************************************************
REM * Sharing
REM * -------
REM * This script is free to share and modify, as long as this entire header section is kept with
REM * the script, and maintained and updated appropriately as any changes are made.
REM ************************************************************************************************
REM * Notes
REM * -----
REM * 1) This script will create a sub-folder named '\data', within which it retains any previous
REM * results from bpgetconfig. This is useful in that it speeds up re-runs of this script.
REM * 2) However, the above does mean that, after sometime, it may be prudent to manually delete
REM * the sub-folder, so that the script will re-fetch client details - and it is probably
REM * especially important to delete the '\data' sub-folder after doing a round of client
REM * upgrades and/or patches.
REM * 3) This script can appear to be slow to run if you have lots of clients that do not resolve
REM * in DNS and/or do not ping. Search for the string "_MOD_ME_" in this script for two
REM * places where if you de-REM (i.e. uncomment) then the script may run quicker.
REM * 4) Another thing that can be done, is to create a static lookup file of "owner" names, i.e.
REM * a list of client names and some kind of descriptive text, which will then be included
REM * in the "owner" column of the CSV file created by this script.
REM * e.g. create a plain text (use Notepad) file named "get-versions.own", and enter:
REM * clienta TeamA
REM * client-B team B
REm * ...i.e. a list of client names, one space character, and then any text including any...
REM * ...spaces, but do not use round brackets ( ) in the text, as this confuses DOS/batch.
REM ************************************************************************************************
set z_script_started=!date! !time:~0,8!
set z_path=%~dp0
set z_name=%~n0
set z_debug=NO
REM ************************************************************************************************
REM ************************************************************************************************
REM *** To make re-runs of this script faster, we collect/save the the client queries...
set z_data=!z_path!data
if not exist "!z_data!" mkdir "!z_data!"
REM ************************************************************************************************
REM ************************************************************************************************
REM *** Build some file names for use by this script...
REM ***
REM *** The 'dat' files are actually saved in the "\data" sub-folder. The variable 'z_file_dat' is
REM *** actually re-defined later. It is only listed here to remind us that we do make use of
REM *** another file later in the script.
set z_file_csv=!z_path!!z_name!.csv
set z_file_cli=!z_path!!z_name!.cli
set z_file_dat=!z_path!!z_name!.dat
set z_file_own=!z_path!!z_name!.own
set z_file_ser=!z_path!!z_name!.ser
set z_file_log=!z_path!!z_name!.log
set z_file_tmp=!z_path!!z_name!.tmp
set z_file_txt=!z_path!!z_name!.txt
if exist "!z_file_csv!" del "!z_file_csv!"
if exist "!z_file_cli!" del "!z_file_cli!"
if exist "!z_file_dat!" del "!z_file_dat!"
if exist "!z_file_log!" del "!z_file_log!"
if exist "!z_file_ser!" del "!z_file_ser!"
if exist "!z_file_tmp!" del "!z_file_tmp!"
if exist "!z_file_txt!" del "!z_file_txt!"
REM ************************************************************************************************
REM ************************************************************************************************
call :log ""
call :log ""
call :log "Script started: !z_script_started!"
call :log "...hostname: !computername!"
call :log "...username: !username!"
REM ************************************************************************************************
REM ************************************************************************************************
call :log ""
call :log "Checking for presence of NetBackup..."
reg query HKLM\Software\Veritas\NetBackup\CurrentVersion\Config /v "client_name" >"!z_file_tmp!" 2>&1
set z_sts=!errorlevel!
if not !z_sts!==0 (
call :log "...NetBackup does not appear to be installed on this server, script aborting..."
goto :end
)
for /f "tokens=1,2,3 skip=1" %%a in ('type "!z_file_tmp!"') do (
set z_client_name=%%c
)
reg query HKLM\Software\Veritas\NetBackup\CurrentVersion /v "InstallDir" >"!z_file_tmp!" 2>&1
set z_sts=!errorlevel!
if not !z_sts!==0 (
call :log "...cannot locate `InstallDir` registry value, script aborting..."
goto :end
)
for /f "tokens=1,2,* skip=1" %%a in ('type "!z_file_tmp!"') do (
set z_install_dir=%%c
)
reg query HKLM\Software\Veritas\NetBackup\CurrentVersion /v "Install Type" >"!z_file_tmp!" 2>&1
set z_sts=!errorlevel!
if not !z_sts!==0 (
call :log "...cannot locate `Install Type` registry value, script aborting..."
goto :end
)
for /f "tokens=1,2,3,* skip=1" %%a in ('type "!z_file_tmp!"') do (
set z_install_type=%%d
)
if /i not "!z_install_type!"=="NetBackup Master Server" (
if /i not "!z_install_type!"=="NetBackup Media Server" (
if /i not "!z_install_type!"=="NetBackup Administration Console" (
call :log "...this script cannot be run on NetBackup installation of `!z_install_type!`, script aborting..."
goto :end
)
)
)
set z_netbackup_bin=!z_install_dir!NetBackup\bin
if not exist "!z_netbackup_bin!" (
call :log "...unable to locate NetBackup binaries folder `!z_netbackup_bin!`, script aborting..."
goto :end
)
set z_volmgr_bin=!z_install_dir!Volmgr\bin
if not exist "!z_volmgr_bin!" (
call :log "...unable to locate Volume Manager binaries folder `!z_volmgr_bin!`, script aborting..."
goto :end
)
set z_bpclntcmd=!z_netbackup_bin!\bpclntcmd.exe
set z_bpgetconfig=!z_netbackup_bin!\admincmd\bpgetconfig.exe
set z_bpplclients=!z_netbackup_bin!\admincmd\bpplclients.exe
if not exist "!z_bpclntcmd!" (
call :log "...unable to find bpclntcmd at `!z_bpclntcmd!`, script aborting..."
goto :end
)
if not exist "!z_bpgetconfig!" (
call :log "...unable to find bpgetconfig at `!z_bpgetconfig!`, script aborting..."
goto :end
)
if not exist "!z_bpplclients!" (
call :log "...unable to find bpplclients at `!z_bpplclients!`, script aborting..."
goto :end
)
call :log "...NetBackup client name: !z_client_name!"
call :log "...NetBackup type: !z_install_type!"
call :log "...NetBackup path: !z_install_dir!"
call :log "...done..."
REM ************************************************************************************************
REM ************************************************************************************************
call :log ""
call :log "Determining master server name..."
"!z_bpclntcmd!" -pn >"!z_file_tmp!" 2>&1
set z_sts=!errorlevel!
if not !z_sts!==0 (
call :log "...call to bpclntcmd failed, status `!z_sts!`, script aborting..."
goto :end
)
for /f "tokens=1,2,3,4,5" %%a in ('type "!z_file_tmp!"') do (
if /i "%%a %%b %%c %%d"=="expecting response from server" (
set z_master=%%e
)
)
call :log "...master server is: !z_master!"
call :log "...done..."
REM ************************************************************************************************
REM ************************************************************************************************
REM *** Fetch list of clients, and a list of servers of the master...
if not exist "!z_file_cli!" (
call :log ""
call :log "Listing clients..."
"!z_bpplclients!" -allunique -noheader -l > "!z_file_cli!" 2>&1
set z_sts=!errorlevel!
if not !z_sts!==0 (
call :log "...call to bpplclients failed, status `!z_sts!`..."
goto :end
)
call :log "...done..."
)
if not exist "!z_file_ser!" (
call :log ""
call :log "Listing servers..."
"!z_bpgetconfig!" -M !z_master! SERVER > "!z_file_ser!" 2>&1
set z_sts=!errorlevel!
if not !z_sts!==0 (
call :log "...call to bpgetconfig for master `!z_master!` failed, status `!z_sts!`..."
goto :end
)
call :log "...done..."
)
REM ************************************************************************************************
REM ************************************************************************************************
REM *** Write a header to the report file. We use a leading underscore, so that when the file is
REM *** sorted later, the header floats to the top...
(echo "_client",ping,ip,owner,hw,os,patch,type,platform,protocol,product,version_name,version_number,install_path,client_os)>>"!z_file_txt!"
REM goto :skip1
REM ************************************************************************************************
REM ************************************************************************************************
Call :log ""
call :log "Counting clients and servers..."
set /a z_cli_total=0
set /a z_cli_attempted=0
set /a z_cli_suceeded=0
set /a z_cnt=0
for /f "tokens=1,2,3,4" %%a in ('type "!z_file_cli!"') do (
set /a z_cnt+=1
set z_hw=%%c
set z_wanted=y
if /i "!z_hw!"=="VMware" set z_wanted=n
if /i "!z_hw!"=="vmx-07" set z_wanted=n
if /i "!z_hw!"=="NDMP" set z_wanted=n
if /i "!z_wanted!"=="y" (set /a z_cli_total+=1)
)
for /f "tokens=1,2,3" %%a in ('type "!z_file_ser!"') do (
set z_client=%%c
find /i """!z_client!""" "!z_file_txt!" >NUL 2>&1
if "!errorlevel!"=="1" (
set /a z_cnt+=1
set /a z_cli_total+=1
)
)
call :log "...found `!z_cli_total!` to check from a total of `!z_cnt!` client/server names..."
call :log "...done..."
REM ************************************************************************************************
REM ************************************************************************************************
call :log ""
call :log "Processing list of clients..."
set z_section=clients
for /f "tokens=1,2,3,4" %%a in ('type "!z_file_cli!"') do (
set z_client=%%b
set z_hw=%%c
set z_os=%%d
set z_check=yes
if /i "!z_hw!"=="VMware" set z_check=no
if /i "!z_hw!"=="vmx-07" set z_check=no
if /i "!z_hw!"=="NDMP" set z_check=no
if /i "!z_check!"=="yes" call :r_check
REM if !z_cli_attempted! geq 5 goto :skip1
)
call :log "...done..."
:skip1
REM ************************************************************************************************
REM ************************************************************************************************
call :log ""
call :log "Processing list of servers..."
set z_section=servers
for /f "tokens=1,2,3" %%a in ('type "!z_file_ser!"') do (
set z_client=%%c
set z_hw=
set z_os=
find /i """!z_client!""" "!z_file_txt!" >NUL 2>&1
if "!errorlevel!"=="1" call :r_check
)
call :log "...done..."
:skip2
REM ************************************************************************************************
REM ************************************************************************************************
call :log ""
call :log "Sorting output..."
sort "!z_file_txt!" /o "!z_file_csv!"
call :log "...done..."
REM ************************************************************************************************
REM ************************************************************************************************
call :log ""
call :log "Totals:
call :log "...clients total: !z_cli_total!"
call :log "...clients attempted: !z_cli_attempted!"
call :log "...clients succeeded: !z_cli_suceeded!"
call :log "...output file is: !z_file_csv!"
call :log "...done..."
if exist "!z_file_tmp!" del "!z_file_tmp!"
if exist "!z_file_txt!" del "!z_file_txt!"
REM ************************************************************************************************
REM ************************************************************************************************
:end
set z_script_finished=!date! !time:~0,8!
call :log ""
call :log "Script started: !z_script_started!"
call :log "Script completed: !z_script_finished!"
echo+
pause
exit /b
REM ************************************************************************************************
REM ************************************************************************************************
REM *** Here we gather the client details...
:r_check
set /a z_cli_attempted+=1
set z_ping=
set z_ip=
set z_file_owner=
REM set z_hw= Leave this REM'd.
REM set z_os= Leave this REM'd.
set z_type=
set z_platform=
set z_protocol=
set z_product=
set z_version_name=
set z_version_number=
set z_install_path=
set z_client_os=
set z_patch_level=
call :r_owner
call :r_ip
REM *** _MOD_ME_
REM *** Comment out this next line, if you want the script to ignore cases where this script is...
REM *** ...unable to determine the IP of a client...
REM if /i "!z_ip!"=="missing" goto :r_check_skip
call :r_alive
if /i "!z_ping!"=="no" (
call :log "Client: !z_client! does not ping..."
REM *** _MOD_ME_
REM *** Comment out this next line, if you want the script to ignore cases where a client does not ping...
REM goto :r_check_skip
)
call :log "Checking !z_cli_attempted! of !z_cli_total!, client `!z_client!`..."
set z_file_dat=!z_data!\!z_client!.dat
if not exist "!z_file_dat!" (
bpgetconfig -g !z_client! -A -L > "!z_file_dat!" 2>&1
set z_sts=!errorlevel!
if not !z_sts!==0 (
call :log "...call to bpgetconfig for client `!z_client!` failed, status `!z_sts!`..."
goto :eof
)
)
for /f "tokens=1,2 delims==" %%a in ('type "!z_file_dat!"') do (
if /i "%%a"=="Client/Master " set z_type=%%b
if /i "%%a"=="NetBackup Client Platform " set z_platform=%%b
if /i "%%a"=="NetBackup Client Protocol Level " set z_protocol=%%b
if /i "%%a"=="Product " set z_product=%%b
if /i "%%a"=="Version Name " set z_version_name=%%b
if /i "%%a"=="Version Number " set z_version_number=%%b
if /i "%%a"=="NetBackup Installation Path " set z_install_path=%%b
if /i "%%a"=="Client OS/Release " set z_client_os=%%b
if /i "%%a"=="Patch Level " set z_patch_level=%%b
)
if not "!z_type!"=="" set z_type=!z_type:~1,99!
if not "!z_platform!"=="" set z_platform=!z_platform:~1,99!
if not "!z_protocol!"=="" set z_protocol=!z_protocol:~1,99!
if not "!z_product!"=="" set z_product=!z_product:~1,99!
if not "!z_version_name!"=="" set z_version_name=!z_version_name:~1,99!
if not "!z_version_number!"=="" set z_version_number=!z_version_number:~1,99!
if not "!z_install_path!"=="" set z_install_path=!z_install_path:~1,99!
if not "!z_client_os!"=="" set z_client_os=!z_client_os:~1,99!
if not "!z_patch_level!"=="" set z_patch_level=!z_patch_level:~1,99!
if "!z_client_os:~-1!"==" " set z_client_os=!z_client_os:~0,-1!
set /a z_cli_suceeded+=1
:r_check_skip
(echo "!z_client!","!z_ping!","!z_ip!","!z_owner!","!z_hw!","!z_os!","!z_patch_level!","!z_type!","!z_platform!","!z_protocol!","!z_product!","!z_version_name!","!z_version_number!","!z_install_path!","!z_client_os!")>>"!z_file_txt!"
goto :eof
REM ************************************************************************************************
REM ************************************************************************************************
REM *** Lookup the client name in an optional static list of client owners...
:r_owner
set z_owner=
if not exist "!z_file_own!" goto :eof
for /f "tokens=1,* skip=2" %%a in ('find /i "!z_client!" "!z_file_own!"') do (
set z_owner=%%b
)
goto :eof
REM ************************************************************************************************
REM ************************************************************************************************
REM *** Determine IP, and also detect if client accidentally has a round-robin IP in DNS...
:r_ip
set z_1st_ip=
set z_2nd_ip=
nslookup !z_client! >"!z_file_tmp!" 2>&1
for /f "tokens=1,2 skip=4" %%a in ('type "!z_file_tmp!"') do (
if /i "%%a"=="Address:" set z_1st_ip=%%b
)
nslookup !z_client! >"!z_file_tmp!" 2>&1
for /f "tokens=1,2 skip=4" %%a in ('type "!z_file_tmp!"') do (
if /i "%%a"=="Address:" set z_2nd_ip=%%b
)
if "!z_1st_ip!"=="!z_2nd_ip!" (
set z_ip=!z_1st_ip!
if "!z_ip!"=="" set z_ip=missing
) else (
set z_ip=duplicated
)
if /i not "!z_ip!"=="missing" goto :eof
ping !z_client! -n 1 -w 100 >"!z_file_tmp!" 2>&1
for /f "tokens=1,2,3,4 delims=[] " %%a in ('type "!z_file_tmp!"') do (
if /i "%%a %%d"=="Pinging with" (
set z_ip=%%c
)
)
goto :eof
REM ************************************************************************************************
REM ************************************************************************************************
REM *** Detect whether client pings or not...
:r_alive
set z_ping=no
ping !z_client! -n 1 -w 100 >"!z_file_tmp!" 2>&1
set z_sts=!errorlevel!
if not !z_sts!==0 goto :eof
for /f "tokens=1" %%a in ('type "!z_file_tmp!"') do (
if /i "%%a"=="reply" (
set z_ping=yes
goto :eof
)
if /i "%%a"=="request" goto :eof
if /i "%%a"=="unknown" goto :eof
)
goto :eof
REM ************************************************************************************************
REM ************************************************************************************************
:log
(echo !date! !time:~0,8! %~1)
(echo !date! !time:~0,8! %~1)>>"!z_file_log!"
goto :eof