Показать полную графическую версию : [решено] Работа с циклом
Всем доброго времени суток!
Господа, в продолжении темы http://forum.oszone.net/thread-349049.html.
Навоял вот такую штуку, но она не спешит работать, подскажите пожалуйста, где косяк? Все наверняка очень плохо, и проблемы с синтаксисом.
Идея заключается в том чтобы забирать из текстового файла IP адреса, и подставлять их в цикл, для автоматического удаленного заведения пользователей сразу на нескольких удаленных ПК.
echo off
echo Введите имя пользователя
set /p username=
echo Введите пароль
set /p password=
echo Введите имя нового пользователя
set /p newuser=
echo Введите пароль нового пользователя
set /p newpass=
rem количество переменных (ip) считывается из файла
for /f "usebackq" %%S in (`find /c /v ""^<"ip.txt"`) do (set /a NumStr=%%S)
rem забирает в переменную ipinfile значение из файла IP.txt
:M2
if [NOT] NumStr = 0 goto M0
goto M1
:M0
for /f "skip=%NumStr% - 1" %%A IN ("IP.txt") do (set "ipinfile=%%~A"&&goto:M3)
:M3
set /a NumStr = NumStr - 1
wmic /user:"%username%" /password:"%password%"/node:"%ipinfile%" process call create "cmd /c net user %newuser% /add"
wmic /user:"%username%" /password:"%password%"/node:"%ipinfile%" process call create "cmd /c net user %newuser% %newpass%"
wmic /user:"%username%" /password:"%password%"/node:"%ipinfile%" process call create "cmd /c net localgroup Администраторы %newuser% /add"
wmic /user:"%username%" /password:"%password%"/node:"%ipinfile%" process call create "cmd /c net localgroup Administrators %newuser% /add"
goto M2
:M1
pause
Nilf, чем больше вы будете усложнять код и себе работу тем больше у вас будет проблем и непонимания
зачем вот это
echo Введите имя пользователя
set /p username=
echo Введите пароль
set /p password=
echo Введите имя нового пользователя
set /p newuser=
echo Введите пароль нового пользователя
set /p newpass= »
если есть какой-то мифический "IP.txt". Почему мифический - никто его не видел, что в нем, как это там записано чтобы проверить правильно ли вы считываете из него информацию. О его необходимости выше сказал, что-то одно только нужно, код делается для автоматизации и упрощения работы, это не должен быть комбайн со стразами.
Ядрёны поммидоры, а зачем goto? И зачем перебирать файл с ip для выяснения количества оных, если все равно используются все?
Особо доставило вот это вот:
for /f "skip=%NumStr% - 1" %%A IN ("IP.txt") do (set "ipinfile=%%~A"&&goto:M3)
:M3
set /a NumStr = NumStr - 1
Т.е. выяснить количество IP, перебирать файл с ними каждый раз ПОЛНОСТЬЮ но брать только одно значение и уменьшать в следующий раз количество пропускаемых строк, а последующие итерации обламываются безусловным переходом.
Это я, извините, на эмоциях написал, но оно - правда. Теперь собственно к делу, из скрипта удаляем к лешему начиная с rem количество переменных (ip) считывается из файла
до pause, оставляем только это:
for /f %%A IN ("IP.txt") do (
set "ipinfile=%%~A"
wmic /user:"%username%" /password:"%password%"/node:"%ipinfile%" process call create "cmd /c net user %newuser% /add"
wmic /user:"%username%" /password:"%password%"/node:"%ipinfile%" process call create "cmd /c net user %newuser% %newpass%"
wmic /user:"%username%" /password:"%password%"/node:"%ipinfile%" process call create "cmd /c net localgroup Администраторы %newuser% /add"
wmic /user:"%username%" /password:"%password%"/node:"%ipinfile%" process call create "cmd /c net localgroup Administrators %newuser% /add"
)
ну и комментарии по желанию можно оставить.
Протестить негде, но вроде как если всё остальное в порядке - должно работать.
еще один момент, вот это
set "ipinfile=%%~A"
тоже является лишним, т.к. можно %%~A подставлять прямо в строчки с wmic, но это уже на усмотрение ТСа.
alpap, согласен. Судя по тому что ТС пытается сделать - у него одноранговая сеть с одинаковой учеткой с правами администратора на хостах, но я откровенно устал писать что запуск подобной, эмммм... автоматизации в одноранговой сети штука довольно спорная и геморная, если так уж хочется выстрелить себе в ногу - кто я такой чтобы мешать? В конце концов сами мы тоже когда-то по граблям ходили, однако помочь с мягкими насадками на рукоять - в наших силах.
Ну и насчет насадок на грабли: есть такая хорошая и полезная штука как ansible - с ней возня в одноранговой сети (если уж нет возможности AD) становится чуть менее болезненной.
непонятно видимо?
Если собираетесь считывать информацию из файла, то только там и должна быть вся информация, причем в таком примерно виде
192.168.31.2,Vasya,12345
192.168.31.5,Petya,67890
...
Ок. Понял.
Пример файла IP.txt:
192.168.31.1
192.168.31.2
192.168.31.3
192.168.31.4
....
Т.е. происходит банальное перечисление IP адресов на которые нужно отправить команду о добавлении нового пользователя. одна строка - один IP. Идея была такова что считается количество строк из файла, это значение подставляется в цикл, и по итог когда это значение придет к нулю (т.е. закончиться перебор всех строк) исполнение файла заканчивается.
Nilf, чем больше вы будете усложнять код и себе работу тем больше у вас будет проблем и непонимания
зачем вот это
Цитата Nilf:
echo Введите имя пользователя
set /p username=
echo Введите пароль
set /p password=
echo Введите имя нового пользователя
set /p newuser=
echo Введите пароль нового пользователя
set /p newpass= »
Касаемо этого, мне необходимо задавать логин и пароль нового пользователя, плюс логин и пароль пользователя-администратора, под которым будет запускаться скрипт на удаленном ПК.
ansible »
Спасибо за разъяснение, будем попробовать. А по поводу того чтобы юзать сторонний софт, к сожалению не получиться, есть такое ограничений что только встроенными в ОС средствами.
непонятно видимо?
Если собираетесь считывать информацию из файла, то только там и должна быть вся информация, причем в таком примерно виде
Код:Выделить весь код
192.168.31.2,Vasya,12345
192.168.31.5,Petya,67890
...
У меня там только IP было.
закончиться перебор всех строк »
не нужно этого, цикл и так прекратится
перечисление IP адресов на которые нужно отправить команду о добавлении нового пользователя. одна строка - один IP »
ха, а если на одну машину надо несколько пользователей, я не просто так предложил свой вариант txt, например так может ведь быть?
192.168.31.1,Vasya,1234
192.168.31.1,Petya,5678
192.168.31.1,Olya,4321
192.168.31.2,Oleg,A1B1C1
но это все подойдет только если пользователи создаются одинаковые
иначе надо составлять файл примерно так:
Vasya,1234,192.168.31.1,net user UserNew1
Petya,5678,192.168.31.1,net user UserNew2 3476
Olya,4321,192.168.31.1,net localgroup Администраторы UserN
Oleg,A1B1C1,192.168.31.2,net localgroup Administrators NewUser2
тогда код будет выглядеть довольно просто:
@echo off
for /f "usebackq tokens=1-3* delims=," %%a in ("IP.txt") do (
wmic /user:"%%~a" /password:"%%~b" /node:"%%~c" process call create "cmd /c %%~d /add"
)
pause
Цитата Nilf:
перечисление IP адресов на которые нужно отправить команду о добавлении нового пользователя. одна строка - один IP »
ха, а если на одну машину надо несколько пользователей, я не просто так предложил свой вариант txt, например так может ведь быть? »
Да, действительно, так куда удобнее получиться в таком случае, спасибо!
еперь собственно к делу, из скрипта удаляем к лешему начиная с rem количество переменных (ip) считывается из файла
до pause, оставляем только это:
Код:
for /f %%A IN ("IP.txt") do (
set "ipinfile=%%~A"
wmic /user:"%username%" /password:"%password%"/node:"%ipinfile%" process call create "cmd /c net user %newuser% /add"
wmic /user:"%username%" /password:"%password%"/node:"%ipinfile%" process call create "cmd /c net user %newuser% %newpass%"
wmic /user:"%username%" /password:"%password%"/node:"%ipinfile%" process call create "cmd /c net localgroup Администраторы %newuser% /add"
wmic /user:"%username%" /password:"%password%"/node:"%ipinfile%" process call create "cmd /c net localgroup Administrators %newuser% /add"
)
ну и комментарии по желанию можно оставить.
Протестить негде, но вроде как если всё остальное в порядке - должно работать. »
Ошибка получается: "Учетные данные пользователя не могут быть использованы для местных подключений."
Видимо если в такой последовательности, то получается что скрипт не стучится по заданному адресу, а пытается выполниться на локальном компе.
у меня нет под рукой cmd чтобы проверить наверняка. больше всего похоже на какие-то грабли с переменной/переменными.
для проверки значения можно вывести все используемые переменные, например так:
echo ipinfile = %ipinfile%
echo username = %username%
ну и так далее.
но скорей всего дело в set, вроде бы в нем кавычки не нужны, т.е.
set ipinfile=%%~A
megaloman
25-06-2021, 16:06
192.168.31.1
192.168.31.2
192.168.31.3
192.168.31.4@Echo Off
Set "IpTxt=Z:\Box_In\Ip.txt"
:nameuser
cls
SET /P "nameuser=Введите имя пользователя >"
SET /P "password=Введите пароль пользователя %nameuser% >"
Echo Введенное имя пользователя "%nameuser%"
Echo.
:newuser
SET /P "newuser=Введите имя нового пользователя >"
SET /P "newpass=Введите пароль нового пользователя %newuser% >"
Cls.
Echo Введенное имя пользователя "%nameuser%"
Echo Введенное имя нового пользователя "%newuser%" "%newpass%"
Echo.
CHOICE /C NUCB /N /M "N-новый пользователь, U-пользователь, C-завершить, B-сделать"
:begin
If %ErrorLevel%==1 GoTo :newuser
If %ErrorLevel%==2 GoTo :nameuser
If %ErrorLevel%==3 Exit /B
For /f "usebackq tokens=1 delims= " %%i in ("%IpTxt%") Do (
Echo wmic /user:"%nameuser%" /password:"%password%"/node:"%%i" process call create "cmd /c net user %newuser% /add"
Echo wmic /user:"%nameuser%" /password:"%password%"/node:"%%i" process call create "cmd /c net user %newuser% %newpass%"
Echo wmic /user:"%nameuser%" /password:"%password%"/node:"%%i" process call create "cmd /c net localgroup Администраторы %newuser% /add"
Echo wmic /user:"%nameuser%" /password:"%password%"/node:"%%i" process call create "cmd /c net localgroup Administrators %newuser% /add"
)
Echo.
CHOICE /C NUC /N /M "N-новый пользователь, U-пользователь, C-завершить"
CLS
GoTo :begin
Exit /B 0
В боевой версии Echo уберите
megaloman, нельзя брать имя %username%, это имя переопределит система в cmd и не будет выхода на удаленные компьютеры, останемся на локальном юзере.
megaloman
25-06-2021, 19:54
alpap, Не вспомнил %username%, наверное возможны неприятности, жара в 36 градусов сказывается. Потестировал, но не так всё просто, не очень-то переопределяется. При перезапуске окна CMD всё возвращается на круги своя. На всякий случай исправил.
Поэтому iCount, sUserName, sPassword, aNames и т.п.
megaloman
26-06-2021, 09:29
Iska, Вы конечно правы, стиль, батюшка, это всё!Верно определяйте слова, и вы освободите мир от половины недоразумений.
megaloman
26-06-2021, 09:58
Iska, alpap, Вообще-то что касается аккуратности и осмотрительности, то, ИМХО, было бы полезным применять SetLocal. Это может избавить от последствий недомыслия при образовании имен переменных.@Echo Off
cls
Echo 1111 %UserName%
SetLocal
Echo 2222 %UserName%
Set "UserName=kuku"
Echo 3333 %UserName%
EndLocal
Echo 4444 %UserName%
pause
Exit /B
megaloman, конечно. У меня прям шаблон под это дело задан в Far Manager'е при создании пакетного файла:
https://i.imgur.com/dlOPU2w.png
megaloman
26-06-2021, 11:15
Iska, Шаблон - это конечно полезно. Теперь я понимаю (постоянно недоумевал), почему у Ваших CMD всегда упорно присутствуют
SetLocal EnableExtensions EnableDelayedExpansion
Тут бы я не согласился: SetLocal - полезно
А вот EnableDelayedExpansion я стараюсь всеми силами избегать: как-то споткнулся, что в именах файлов присутствовали "!"
С фаром, конечно, удобно: Вы запускаете bat-файл, открывается CMD-окно, Вы бесчинствуете, переопределяете переменные окружения, затем, после завершения сценария CMD-окно закрывается и все эти бесчинства отменяются.
При работе в CMD-окне, запущенного, допкустим, в пуске, если не перезапускать его, получим переопределённые для этого сеанса CMD переменные окружения.
Цитата ip.txt:
192.168.31.1
192.168.31.2
192.168.31.3
192.168.31.4
Код:
@Echo Off
Set "IpTxt=Z:\Box_In\Ip.txt"
:nameuser
cls
SET /P "nameuser=Введите имя пользователя >"
SET /P "password=Введите пароль пользователя %nameuser% >"
Echo Введенное имя пользователя "%nameuser%"
Echo.
:newuser
SET /P "newuser=Введите имя нового пользователя >"
SET /P "newpass=Введите пароль нового пользователя %newuser% >"
Cls.
Echo Введенное имя пользователя "%nameuser%"
Echo Введенное имя нового пользователя "%newuser%" "%newpass%"
Echo.
CHOICE /C NUCB /N /M "N-новый пользователь, U-пользователь, C-завершить, B-сделать"
:begin
If %ErrorLevel%==1 GoTo :newuser
If %ErrorLevel%==2 GoTo :nameuser
If %ErrorLevel%==3 Exit /B
For /f "usebackq tokens=1 delims= " %%i in ("%IpTxt%") Do (
Echo wmic /user:"%nameuser%" /password:"%password%"/node:"%%i" process call create "cmd /c net user %newuser% /add"
Echo wmic /user:"%nameuser%" /password:"%password%"/node:"%%i" process call create "cmd /c net user %newuser% %newpass%"
Echo wmic /user:"%nameuser%" /password:"%password%"/node:"%%i" process call create "cmd /c net localgroup Администраторы %newuser% /add"
Echo wmic /user:"%nameuser%" /password:"%password%"/node:"%%i" process call create "cmd /c net localgroup Administrators %newuser% /add"
)
Echo.
CHOICE /C NUC /N /M "N-новый пользователь, U-пользователь, C-завершить"
CLS
GoTo :begin
Exit /B 0
В боевой версии Echo уберите »
Большое спасибо за Ваш вариант! Но получается что мне будет необходим тогда файлик choise.exe либо choise.com? Ежили его не будет, в случае например с XP, то ничего работать не будет? А если этот файлик воткнуть из ранней в позднюю или наоборот, то он не сможет выполниться, будет говорить что это не системная программа.
megaloman
28-06-2021, 12:48
Nilf, Солнце встало, сдохли мухи: продолжаем в том же духе :jester: @Echo Off
Set "IpTxt=Z:\Box_In\Ip.txt"
:nameuser
cls
SET /P "nameuser=Введите имя пользователя >"
SET /P "password=Введите пароль пользователя %nameuser% >"
Echo Введенное имя пользователя "%nameuser%"
Echo.
:newuser
SET /P "newuser=Введите имя нового пользователя >"
SET /P "newpass=Введите пароль нового пользователя %newuser% >"
Cls.
Echo Введенное имя пользователя "%nameuser%"
Echo Введенное имя нового пользователя "%newuser%" "%newpass%"
Echo.
:Choice1
Set "Answer="
Set /P "Answer=Введите N-новый пользователь, U-пользователь, C-завершить, B-сделать >"
:begin
If /I "%Answer%"=="N" GoTo :newuser
If /I "%Answer%"=="U" GoTo :nameuser
If /I "%Answer%"=="C" Exit /B
If /I Not "%Answer%"=="B" (Echo Ввод неверный: "%Answer%" &GoTo :Choice1)
For /f "usebackq tokens=1 delims= " %%i in ("%IpTxt%") Do (
Echo wmic /user:"%nameuser%" /password:"%password%"/node:"%%i" process call create "cmd /c net user %newuser% /add"
Echo wmic /user:"%nameuser%" /password:"%password%"/node:"%%i" process call create "cmd /c net user %newuser% %newpass%"
Echo wmic /user:"%nameuser%" /password:"%password%"/node:"%%i" process call create "cmd /c net localgroup Администраторы %newuser% /add"
Echo wmic /user:"%nameuser%" /password:"%password%"/node:"%%i" process call create "cmd /c net localgroup Administrators %newuser% /add"
)
Echo.
:Choice2
Set "Answer="
Set /P "Answer=Введите N-новый пользователь, U-пользователь, C-завершить >"
CLS
If /I Not "%Answer%"=="N" If /I Not "%Answer%"=="U" If /I Not "%Answer%"=="C" (Echo Ввод неверный: "%Answer%" &GoTo :Choice2)
GoTo :begin
Exit /B 0
В XP вроде бы выполняется (WMIC не тестировал)
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.