.bat - insert text before a period - batch-file

I have a .bat that I use to quickly query basic information from servers. After it gets the FQDN from DNS, I need to insert a "-r" (minus quotes) after the servername, but before the ".domain.com". The area that it will be added to the script is below -
for /f "delims=[] tokens=2" %%b in ('ping %servername% -n 1 ^| findstr "["') do (set thisip=%%b)
for /f "tokens=2" %%a in ('nslookup %thisip% ^| find /i "Name: "') do (set fqdnstat=%%a)
so how can I take the FQDN, which is set to fqdnstat, and modify it from -
server.domain.com
to server-r.domain.com ?
Edit - I guess I didn't really explain very well. I just need to insert text into a line of text, before a period. I need to take the following name: server.domain.com and edit it to read server-r.domain.com, using a command. The rest of the script above is context for the issue. The fqdnstat is the variable that I use to for the Fully Qualified Domain Name.

I am afraid I don't really understand your concern, but this Batch file may help you:
#echo off
set fqdnstat=server.domain.com
echo Before: "%fqdnstat%"
for /F "tokens=1* delims=." %%a in ("%fqdnstat%") do set "fqdnstat=%%a-r.%%b"
echo After: "%fqdnstat%"

set servername=%servername:.domain.com=-r.domain.com%
Presumably above the two lines you've put, but I'm not sure what the goal is, so maybe not.

Related

Batch commands for rds

I have a project for my Radio Station where I copy the text within a .wsx file of what is on air and parse it to a Audio Processor in my private network for RDS Display using a wget command like
set /p TEXTO= 0<R:\40.wsx
wget -q "http://x.x.x.x:7380/parameter/fm/rds/rds_rt=%TEXTO%" -O NUL
It works great but it won't filter if it's music or promotions.
My challenge is to be able to filter and only parse music names.
For the process I marked the Files that i don't want to show up like commercial, or promotions to start with a "#-" without the quotes.
So the text will show like #-Promo1
My Code:
for /F "delims=" %%a in ('FINDSTR "\<#-.*" C:\RDS\PRUEBAS\txt1.wsx') do set
"VAR=%%a"
echo %VAR%
if "%VAR%" == "true" (
set /p VAR=0<C:\FILEPATH\LOS40.wsx & wget -q
"http://x.x.x.x:7380/parameter/fm/rds/rds_rt=%VAR%" -O NUL
) else (
set /p TEXTO=0<C:\FILEPATH\ENVIVO.wsx & wget -q
"http://x.x.x.x:7380/parameter/fm/rds/rds_rt=%TEXTO%" -O NUL
)
I can't seem to find a correct way to filter it.
pls Heelpp..
for /F "delims=" %%a in ('FINDSTR "\<#-.*" C:\RDS\PRUEBAS\txt1.wsx') do set
should be
for /F "delims=" %%a in ('FINDSTR /b "#-" C:\RDS\PRUEBAS\txt1.wsx') do set
to find those lines in the .wsx file that do /b begin with "#-"
If you want to find those lines that do not begin with "#-" then add /v to the /b.
The result will be a line from the file which does [not] begin with "#-" which will be placed in %%a.
If you simply assign %%a to a variable as you are doing, that variable will contain after the for the last value that was assigned to it.
If you want to execute your wget on each name, then use
for /F "delims=" %%a in ('FINDSTR /B "#-" C:\RDS\PRUEBAS\txt1.wsx') do (
echo %%a
)
and between the parentheses you can execute commands using %%a as a filename.
Quite what you propose to do is obscure. I've no idea what the set/p from an unexplained file is meant to do, but be aware that any code between parentheses is subject to the delayedexpansion trap - please explain what processing you intend to apply to the filenames that do[not] match a leading #-.
You should read SO items on delayed expansion (it's documented with and without the space) to understand the problems with and solutions to processing values that are altered within a loop.
First of all thanks for your help.. I don't have experience in coding.
Let me explain a little bit more..
As I said before its a radio station which will provide text to the Car o home stereos using the RDS Protocol which allow me to send text like song name, title, etc.
Im My case the Audio Processor that let me send the text will receive the info as a URL where I add at the end the text I want to send.
For Example:
http://x.x.x.x:7380/parameter/fm/rds/rds_rt=%TEXTO%
%TEXTO% will be the text Im sending.
C:\RDS\PRUEBAS\txt1.wsx Contains the text of what it being played at the moment and which is being read to see if the #- for the script to avoid sending those titles.
I have a Pc running a Directory Monitor Program that will monitor events on file C:\RDS\PRUEBAS\txt1.wsx and that as soon as being modified, it will execute the batch file CHECKRDS.cmd.
After testing I decided to run a code in CHECKRDS.cmd like:
for /F "delims=" %%a in ('FINDSTR /v "#-" R:\40PPALES.wsx') do (
START "" RDS.bat
)
EXIT
RDS.bat contains code and it works fine:
set /p TEXTO= 0<C:\RDS\PRUEBAS\txt1.wsx
wget -q "http://x.x.x.x:7380/parameter/fm/rds/rds_rt=%TEXTO%" -O NUL
EXIT
As far as the set /p I test it from What does /p mean in set /p?
AS I said before Im new at coding and I just googled everything and started to assable the pieces of the puzzle.
Pls, If you think I should be doing these process diferently, pls let me know..
And sorry for my bad english..
regards

Correct syntax for nested for loops in batch file

I am trying to query the registry value of an installed application on many servers. I could hardcode the servers in, and have a lot of repetition and it seems to work. But sometimes a list of servers may change, and I'd like to take a more sensible modular approach.
So I can provide a test file with a list of server names, and then query the registry values of all of these servers, outputting them in a logfile.
I think the issue is definitely with my loops/variable storing. Not sure exactly what is going on, but it seems like once I get one set of Registry values, these are outputted for every single server, regardless of their respective registry values.
Not too experience with this kind of scripting, so I have been sort of mashing this together through trial and error, below is what I have so far. Please point out any woeful syntax errors I've made.
So essentially this is to find a McAfee scan engine version installed to each server. The reporting from the McAfee console itself is not always reliable, and I want to check that the contents are successfully pulled down to each server.
There are two registry values required to create a full engine version, so I am required to pull both of these and then combine them into a single string.
At the moment I do get an output that looks correct, but it does not represent what is actually installed to each server. It is like one value is being picked up and then replicated.
On an additional note, this only seems to work when executed in command line. And the first 1-2 times it is ran, no values are pulled up. Get the feeling I am quite far away from a solution.
SET LOGFILE=C:\LogFile.log
For /f %%i in (servers.txt) DO (
for /f "tokens=3" %%a in ('reg query \\%%i\HKLM\SOFTWARE\McAfee\AVEngine /v EngineVersion32Major ^| find /i "EngineVersion32Major"') do set /a major=%%a
for /f "tokens=3" %%b in ('reg query \\%%i\HKLM\SOFTWARE\McAfee\AVEngine /v EngineVersion32Minor ^| find /i "EngineVersion32Minor"') do set /a minor=%%b
echo %%i: %major%.%minor% >> %LOGFILE%
)
Would expect an output like this:
server1 : 5900.5647
server2 : 6000.4589
server3 : 5900.5647
server4 : 5900.5647
Cheers for any help you can provide.
It has nothing to do with for syntax, but how cmd parses scripts. See How does the Windows Command Interpreter (CMD.EXE) parse scripts?
When cmd parses a block (anything within parens), processes it as a single line. So it expands any %var% to its actual content. Changes made to it, are not taken into account until the block is exited. To retrieve new content within a block, you must enable delayed expansion, which forces the parser to evaluate it for every iteration. Also, syntax must be changed from %var% to !var!
Here, also, removed the /a switch from set command, as you are not doing calculations, and you may get results you won't expect (imagine a minor version equal to 0080 that will be treated as octal (invalid) and would break the script). Also, note both var name and var content enclosed in quotes (set "minor=%%b"), to avoid undesired trailing/leading spaces.
More also, I think you don't need the ^| find /i "EngineVersion32Major part, as possibly the key named EngineVersion32Major will content only what you are looking for. And again, enclose data in quotes (never know when a space may appear). You may also change "tokens=3" by "skip=1 tokens=3" to avoid process the heading reg echoes.
Thus
#echo off
SetLocal EnableDelayedExpansion
SET LOGFILE=C:\LogFile.log
for /f %%i in (servers.txt) DO (
for /f "tokens=3" %%a in ('reg query "\\%%i\HKLM\SOFTWARE\McAfee\AVEngine" /v "EngineVersion32Major"') do set "major=%%a"
for /f "tokens=3" %%b in ('reg query "\\%%i\HKLM\SOFTWARE\McAfee\AVEngine" /v "EngineVersion32Minor"') do set "minor=%%b"
echo %%i: !major!.!minor!>>%LOGFILE%
)
EndLocal
Also, this works within a block regardless delayed expansion is enabled or not (note double percent sign)
call echo %%i: %%major%%.%%minor%%>>%LOGFILE%
Another issue, any time a redirection is used within a block, the system opens and closes the file (or stream).
But
#echo off
SetLocal EnableDelayedExpansion
SET LOGFILE=C:\LogFile.log
>>"%LOGFILE%" (
for /f %%i in (servers.txt) DO (
for /f "tokens=3" %%a in ('reg query "\\%%i\HKLM\SOFTWARE\McAfee\AVEngine" /v "EngineVersion32Major"') do set "major=%%a"
for /f "tokens=3" %%b in ('reg query "\\%%i\HKLM\SOFTWARE\McAfee\AVEngine" /v "EngineVersion32Minor"') do set "minor=%%b"
echo %%i: !major!.!minor!
)
)
EndLocal
Processes all commands in the block, so the file is opened and closed only once. This may improve performance, specially with large files.
BTW,
>>"%LOGFILE%" (
...
...
)
Is the same as
(
...
...
)>>"%LOGFILE%"
Please use the search facility to locate many SO articles on delayed expansion.
The easy way in your case is to use
call echo %%i: %%major%%.%%minor%% >> %LOGFILE%

CMD Variable for registry

Alright so I was trying to delete the shell data in the registry. I can get to it and get all of the information right, but I want to automate it for all users. The one I can use right now only targets a specific file.
reg delete "HKEY_USERS\S-1-5-21-3793956547-500355711-2568367668-1002\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags" /f
What I wanted to do was skip the input for S-1-5-21 and have it target all of the keys within HKEY_USERS. This way I can get all of the shell data deleted with the press of a button.
I am not sure if there is a variable for this, or maybe I am going in the wrong direction here. Any input is appreciated and I will attempt to answer any questions I can.
To enumerate the HKEY_USERS you can Reg Query within a For /f
#Echo off
Set "Hive=HKEY_USERS"
For /F "delims=" %%A in (
'Reg Query "%Hive%" ^|findstr "%Hive%\S-1-5-21" '
) Do Echo %%A
Replace Echo with any cmd you like to execute.
Sample scrambled output:
> SO_41773670.cmd
HKEY_USERS\S-1-5-21-2140113576-3579786329-1990256020-1001
HKEY_USERS\S-1-5-21-2140113576-3579786329-1990256020-1001_Classes
HKEY_USERS\S-1-5-21-2140113576-3579786329-1990256020-1005
HKEY_USERS\S-1-5-21-2140113576-3579786329-1990256020-1006
Something like this may very well suit your needs, it is very likely language dependent, and blind automated removal of registry subkeys is not my recommendation.
#Echo Off
For /F "EOL=E Delims=" %%A In ('Reg Query HKU /S /F Bags /K'
) Do Echo=Reg Delete "%%A" /F&&Echo=Reg Add "%%A"
Timeout -1
remove the two instances of Echo= and the last line if you're happy with the output and wish to continue.

output net view (batch) into text then perform action against each computer

I have been trying to find away to search for the existence of my company's software on PC's by searching hostnames on the network \\computername\c$\Program Files\Foo, and if it finds it, copy over an updated config etc.
I've seen that net view will out put all the PC's on the network, something like this:
\\DISKSTATION
\\JWLAPTOP
\\TEST
\\XP
The command completed successfully.
I was wondering if there was a way to just get the computer names in a clean list (without "command completed" etc.):
\\DISKSTATION
\\JWLAPTOP
\\TEST
\\XP
Then run some commands against it, for everything in hostnames.txt, if exist:
\\JWLAPTOP\c$\Program Files\Foo --> do copy xyz to wherever
I can take care of the part \c$\Program Files\Foo as a variable to add after the computer names in the text file.
Hope that makes sense, thanks for any tips.
edit
Been re thinking this perhaps there is a more direct way to do this....
I need to see the list of PC's on customers network.....net view is a good way of getting this info so far, but I further need to see which ones are online. Any online, query for folder and update a *.CFG file, any offline, output to text for reference.
So at the minute....
FOR /F "tokens=1 delims= " %%G IN ('net view ^|findstr /L /B /C:"\\"')
this is working great, I then made it output to a text file..
FOR /F "tokens=1 delims= " %%G IN ('net view ^|findstr /L /B /C:"\\"') DO (echo %%G>>%~dp0netview.txt)
However, the %%G echo's back \somecomputer which means I am struggling to get a new line..
for /f %%G in (%~dp0netview.txt) DO (ping etc......
to ping because of the \ before the computer name. So was wonder if we can make the list 'just" have the PC name without the \ before it.
Also this is the content of the .cfg file I need to edit...
<?xml version="1.0" encoding="utf-8"?>
<ClientConfigurationFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ServerPath>**\\server\shared\data**</ServerPath>
<ApplicationMode>Workstation</ApplicationMode>
<VRPath />
<ServicePollingInterval>0</ServicePollingInterval>
</ClientConfigurationFile>
perhaps there is a way of editing a certain section of this directly once its existence is found. \server\shared\data...in bold is what I need to update often when clients have new servers and things and involves having to go round lots of rooms to update manually. This batch could save hours upon hours of unnecessary work.
over writing the existing .cfg file is still a good way of doing it if it's too tricky or not possible directly.
Hope it makes sense, thanks for the replies!!!
Assuming none of your computer names have spaces in them.
#echo off
FOR /F "tokens=1 delims= " %%G IN ('net view ^|findstr /L /B /C:"\\"') DO (
IF EXIST "%%~G\c$\Program Files\Foo" copy "C:\folder\xyz.txt" "C:\other folder\"
)
If you want the leading back slashes stripped then use it as a delimiter just like I am using the space as a delimiter to get rid of all the extraneous NET VIEW output.
#echo off
FOR /F "tokens=1 delims=\ " %%G IN ('net view ^|findstr /L /B /C:"\\"') DO (
PING %%G
IF EXIST "\\%%~G\c$\Program Files\Foo" copy "C:\folder\xyz.txt" "C:\other folder\"
)
You could do the following:
#echo off
setlocal EnableExtensions
set "TARGET=C$\Program Files\Foo"
for /F "eol=| delims=" %%C in ('
net view ^| find "\\"
') do (
pushd "%%C\%TARGET%"
if not ErrorLevel 1 (
rem do your operations here...
copy "\your\source\path\xyz" "."
popd
)
)
endlocal
The for /F loop walks through all host names returned by net view (supposing each one starts with \\ and there are only the host names).
Since the resulting path (for instance \\TEST\C$\Program Files\Foo) is a UNC path which is not supported by several commands, pushd is used, which is capable of connecting to the given resource by establishing a temporary drive letter like Z:, and changing the working directory to its root immediately (if the command extensions are on, which is the Windows default).
The query if not ErrorLevel 1 is used to skip over the remaining commands in case pushd could not connect to the resource for some reason.
After all your operations, popd ensures that the temporary drive created by pushd is unmounted and that the former working directory is restored.

script to findstr and then inject next line with variable - can't quite get it working

I've got a script I'm working on that checks a text file to match pc name, then match a port number. That then info gets injected into an ini file for specific settings. I'm using this in a Citrix setup.
Here's a piece of my test script:
:Set_Client_Name
for /f "tokens=1-3" %%1 in ('query session %USERNAME% ^| find ">"') do set ses_num=%%3
for /f "tokens=1-3" %%1 in ('reg query "HKCU\Volatile Environment\%ses_num%" /v CLIENTNAME') do set client_name=%%3
:CHECK
findstr /i /c:%client_name% "C:\star.txt"
IF ERRORLEVEL 1 goto end
:CREATE
set port=
set parse=findstr /i /c:%client_name% "C:\star.txt"
for /f "tokens=2 delims=," %%a in ('"%parse%"') do (set port=%%a)
for /F %%G IN C:\hbowem32.ini DO (
findstr /i /c:"[0_Network Def.]"
echo Local Port=%port% >> C:\hbowem32.ini
)
:END
`
The :Set_Client_Name, :Check, and :Create portions work correctly.
I'm just doing something wrong with the next piece, and I'm not sure what it is.
I need to find the string [0_Network Def.] in the hbowem32.ini, and right after that, inject the %port% variable. I can get it to add to the ini file at the bottom, but I need it to be able to inject this in the correct section of the ini.
I'm also wanting to add a section that pulls the client IP address (this is a Terminal Services/Citrix server) so it can be injected into a different ini/section. I can't seem to get it to pull the user's workstation IP address. It only pulls the IP address of the Citrix server. I no longer have this section in my test script above, but figured I'd go ahead and ask since I'm here and already stuck.
Thanks for any insight and advice.
Add the /L switch to the FINDSTR so that you are dealing with Literals not (default) Regular expressions.

Resources