Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   Требуется помощь по удалению... (http://forum.oszone.net/showthread.php?t=338163)

ILMagus 10-12-2018 21:02 2845252

Требуется помощь по удалению...
 
Здравствуйте, уважаемые.
Возможно, проблема тривиальна, но самому не дойти до решения.
Есть папка Users, в ней папки с именами пользователей, в них, естественно еще куча подпапок и файлов. Требуется с помощью bat файла удалить определенные файлы во всех корневых папках пользователей, не затрагивая их подпапки. Только в корневых папках пользователей. То есть, к примеру, в папке C:\Users\Vasia удалить файлы с расширением txt, не затрагивая подпапки C:\Users\Vasia\Documents, C:\Users\Vasia\Desktop и т.д.
Учитывая, что пользователей около трех сотен, и имена у них разные, надо это как то автоматизировать.
"Del /s" в моем случае не подходит, так как удаляет файлы во всех вложенных папках, а не только в корневой каждого пользователя.

megaloman 10-12-2018 21:45 2845263

Код:

@Echo Off
cls
        Set "BoxIn=C:\Users"
        Set "Box2=AppData"
        Set "DelFile=*.txt"

        FOR /F "usebackq delims=" %%u IN (`Dir /A:D /B "%BoxIn%"`) DO (
                If Exist "%BoxIn%\%%u\%Box2%" (
                        Echo === "%BoxIn%\%%u\%DelFile%"
                        Dir /B /A:-D "%BoxIn%\%%u\%DelFile%"
                )
        )
Pause
GoTo :Eof

Для боевой работы замените Dir /B /A:-D на Del

ILMagus 10-12-2018 22:57 2845270

Спасибо, работает.
А зачем включена переменная AppData? Просто, чтобы убедиться, что каталог действительно пользовательский а не левый?

alpap 11-12-2018 15:51 2845360

megaloman, а чего не перебрать файлы по путям переменной %Userprofile%

megaloman 11-12-2018 16:49 2845376

alpap,
Цитата:

Цитата alpap
а чего не перебрать файлы по путям переменной %Userprofile% »

Для активного пользователя мне понятно. Но я не умею (увы мне!) иначе найти профили всех пользователей на одном компьютере, если их несколько. А переменная AppData, действительно, Просто, чтобы убедиться, что каталог действительно пользовательский. Возможно, это примитив и не корректно с точки зрения применимости для разных Win

alpap 11-12-2018 18:42 2845404

megaloman,
я просто выразился так, а имел ввиду типа:
Код:

@echo off
set "d=C:\Users"

for /f "delims=" %%a in ('dir /ad/b "%d%"') do net user|>nul find "%%a"|| echo del /q "%d%\%%a\*"
pause


megaloman 11-12-2018 19:24 2845406

alpap,
Цитата:

....... find "%%a" || echo ......
имхо надо &&

alpap 11-12-2018 20:25 2845416

Цитата:

Цитата megaloman
надо ... »

не, мы же от этого имени работаем (себя только и найдем как в выводе %Userprofile%)
единственно, если что, то надо ставить в исключение пути:
Скрытый текст

"C:\Users\Administrator"
"C:\Users\All Users"
"C:\Users\Default"
"C:\Users\Default User"
"C:\Users\Public"
"C:\Users\Все пользователи"

но обычно там только папки, файлов нет, ведь в задаче мы не опускаемся ниже первого уровня.

mwz 11-12-2018 20:52 2845419

Цитата:

Цитата megaloman
найти профили всех пользователей на одном компьютере, если их несколько »

А через чтение реестра, анализом
Код:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList
определить?

megaloman 11-12-2018 22:35 2845436

alpap,
Посмотрите
Код:

dir C:\Users\ /A:D /B

All Users
Default
Default User
User111111111111111111111
Public
User222222222222222222222
Все пользователи

Ваш скрипт с ||
Код:

del /q "C:\Users\All Users\*"
del /q "C:\Users\Default\*"
del /q "C:\Users\Default User\*"
del /q "C:\Users\Public\*"
del /q "C:\Users\Все пользователи\*"

Ваш скрипт с &&
Код:

del /q "C:\Users\User1111111111\*"
del /q "C:\Users\User2222222222\*"

mwz,
Цитата:

Цитата mwz
А через чтение реестра »

- это надо поработать, предложите решение

mwz 11-12-2018 23:18 2845444

Цитата:

Цитата megaloman
предложите решение »

Что-то судя по вопросу, я неверно понял задачу... Но всё же (только принцип; хотя список папок пользователей может и проще обработать, тем более что в итоге фактически будем иметь то же самое):

Найти в ключе

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList

все ветви, начинающихся на

S-1-5-21

(это SID-ы пользователей, причём тех, кто хотя бы раз залогинился в системе: если пользователь создан, но в систему ни разу не входил — его ключа здесь не будет, как и папки его).

И прочитать в каждом из найденных S-1-5-21 значение параметра ProfileImagePath, которое и укажет на папку этого пользователя.

Ну и напомню на всякий случай, что SID S-1-5-21-XXXXXXX-XXXXXXXX-XXXXXXXXXXX-500 — это встроенный администратор. Если он в систему не входил — ни ключа, ни папки его профиля тоже не будет создано.

alpap 11-12-2018 23:44 2845449

Цитата:

Цитата megaloman
Ваш скрипт с || »

точно
так я делал в таком случае, когда были заданы имена пользователей
Код:

for %%a in (user1 user2 userN) do net user|find "%%a"||echo del /s /q "C:\Users\%%a"

alpap 12-12-2018 00:06 2845456

вот, собственно, все имена пользователей исключая текущего админа:
Код:

@echo off
for /f "skip=1 delims=" %%a in ('wmic path Win32_UserAccount get FullName /value^|find "="') do set "%%a"& call :#
pause& exit

:#
 if not "%FullName%"=="" echo %FullName%
exit /b

(если брать Name, то будет и имя текущего админа и еще Администратор и Гость)

megaloman 12-12-2018 00:37 2845463

mwz,
Код:

@Echo Off
cls
        Set "DelFile=*.txt"
        For /f "delims=" %%i In ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"') Do Call :RegPars "%%i" "%DelFile%"
pause
GoTo :Eof

:RegPars
        FOR /F "tokens=4*  delims=-" %%a IN (%1) DO If %%a==21 (
                For /f "skip=2 tokens=3 delims= " %%p In ('reg query %1 /v ProfileImagePath') Do (
                        Echo === %%p
                        Dir /A:-D /B "%%p\%~2"
                )
        )
GoTo :Eof

Наверное можно сделать элегантнее. (Dir /A:-D /B заменить на Del)

megaloman 12-12-2018 14:07 2845523

Немного подумал и подсократил
Код:

@Echo Off
cls
        Set "DelFile=*.txt"
        Set "BoxIn=C:\Users"
        For /f "tokens=1,2* delims= " %%i In ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" /S') Do (
                If /I "%%i"=="ProfileImagePath" If /I "%%~dpk"=="%BoxIn%\" Echo === %%k &Dir /A:-D /B "%%k\%DelFile%"
        )
pause
GoTo :Eof

Dir /A:-D /B --> Del
Может еще подумать?
После поста alpap
Код:

@Echo Off
cls
        Set "DelFile=*.txt"
        Set "BoxIn=C:\Users"
        For /f "tokens=3 delims= " %%i In ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" /S /V ProfileImagePath') Do (
                If /I "%%~dpi"=="%BoxIn%\" Echo === %%i &Dir /A:-D /B "%%i\%DelFile%"
        )
pause
GoTo :Eof


alpap 12-12-2018 14:30 2845529

Цитата:

Цитата megaloman
Может еще подумать? »

можно и сразу вывести
Код:

@echo off
for /f "tokens=2*" %%a in ('reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" /s /v "ProfileImagePath"^|find /i "C:\Users"') do echo %%b
pause

даже [/v "ProfileImagePath"] можно убрать.

mwz 12-12-2018 15:06 2845542

alpap
find /i "C:\Users"

В WS2003, например, этой подстроки в данном разделе нет вообще - при том, что значение ProfileImagePath указывает на правильную папку профиля. :)

DJ Mogarych 12-12-2018 15:35 2845546

Powershell:
Код:

$dirs = "$env:SystemDrive\Users"
$ext = "*.txt"
dir $dirs -Directory | dir -File | where Name -like $ext | Remove-Item -Confirm:$false


alpap 12-12-2018 17:09 2845568

Цитата:

Цитата mwz
В WS2003, например, »

а как там выглядит?
ведь нужны только определенные строки содержащие ProfileImagePath и еще их надо парсить до нужного вывода.

Iska 12-12-2018 17:19 2845572

Цитата:

Цитата alpap
а как там выглядит? »

Documents and Settings, конечно. Для пользовательских учётных записей.

mwz 12-12-2018 18:42 2845583

Цитата:

Цитата alpap
а как там выглядит? »

Так:

alpap 12-12-2018 20:13 2845601

У меня через реестр вообще не показывает новосозданных юзеров, а так показывает:
Код:

@echo off
set "uspath=Users"
:: для WS2003 и т.п. закомментировать строку выше и раскомментировать строку ниже (либо надо делать определение ОС и условие)
:: set "uspath=Documents and Settings"

for /f "delims=" %%a in ('wmic path Win32_UserAccount get FullName /value^|find "="') do set "%%a"& call :#
pause& exit

:#
 if not "%FullName%"=="" net user|>nul find "%FullName%" && echo "%Systemdrive%\%uspath%\%FullName%"
exit /b


megaloman 12-12-2018 21:07 2845610

ИМХО, вот это должно работать и в 2003, проверить не на чем
Код:

@Echo Off
cls
        Set "DelFile=*.txt"
        For /f "delims=" %%a In ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" /F "S-1-5-21-*"') Do (
                For /f "Skip=2 tokens=2,* delims= " %%i In ('2^>nul reg query "%%a" /V ProfileImagePath') Do  Echo === %%j &Dir /A:-D /B "%%j\%DelFile%"
        )
pause
GoTo :Eof

Исправлено после тестирования mwz

Iska 12-12-2018 21:09 2845611

Цитата:

Цитата alpap
У меня через реестр вообще не показывает новосозданных юзеров »

Пока не будет создан для него профиль — конечно, не будет. В принципе, достаточно будет запустить от имени этого новосозданного пользователя какое-нибудь приложение с ожиданием, чтобы профиль для него был создан.

Вообще же, все вещи, связанные с манипуляциями над файлами в профилях пользователей, за редким исключением, должны проводиться logon/logoff-скриптами, привязанными к этим пользователям.

mwz 12-12-2018 22:00 2845626

Цитата:

Цитата alpap
У меня через реестр вообще не показывает новосозданных юзеров »

Я об этом сразу написал, хоть и чуток другими словами: в http://forum.oszone.net/post-2845444.html#post2845444

Как и со скриншом из WS2003: там сразу после установки несколько лет назад было создано ещё 4 пользователя. Но они ни разу не логинились, заходят (и то не все) только по ftp, и их профили созданы не были. Исходная же задача — чистить файлы в профилях пользователей; а если профиля нет — то и чистить исходно нечего.

Цитата:

Цитата megaloman
вот это должно работать и в 2003, проверить не на чем »

Где-то кавычки забыты (Echo Off убрано; копия из окна CMD "as is", без устранения переноса строк):

Скрытый текст
c:\TEMP>Set "DelFile=*.txt"

c:\TEMP>For /F "delims=" %a In ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsof
t\Windows NT\CurrentVersion\ProfileList" /F "S-1-5-21-*"') Do (For /F "Skip=2 to
kens=3 delims= " %i In ('2>nul reg query "%a" /V ProfileImagePath') Do Echo ===
%i & Dir /A:-D /B "%i\*.txt" )

c:\TEMP>(For /F "Skip=2 tokens=3 delims= " %i In ('2>nul reg query "HKEY_LOCAL_M
ACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\S-1-5-21-1449298
094-4144929868-1542513627-1030" /V ProfileImagePath') Do Echo === %i & Dir /A:
-D /B "%i\*.txt" )

c:\TEMP>Echo === C:\Documents & Dir /A:-D /B "C:\Documents\*.txt"
=== C:\Documents
The system cannot find the file specified.

c:\TEMP>(For /F "Skip=2 tokens=3 delims= " %i In ('2>nul reg query "HKEY_LOCAL_M
ACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\S-1-5-21-1449298
094-4144929868-1542513627-500" /V ProfileImagePath') Do Echo === %i & Dir /A:-
D /B "%i\*.txt" )

c:\TEMP>Echo === C:\Documents & Dir /A:-D /B "C:\Documents\*.txt"
=== C:\Documents
The system cannot find the file specified.

c:\TEMP>(For /F "Skip=2 tokens=3 delims= " %i In ('2>nul reg query "End of searc
h: 2 match(es) found." /V ProfileImagePath') Do Echo === %i & Dir /A:-D /B "%i
\*.txt" )

c:\TEMP>pause
Press any key to continue . . .

megaloman 12-12-2018 22:25 2845632

mwz, Там сложнее: при разборе не было учтено, что "Documents and Settings" содержит пробелы. Исправил. Если можно, протестируйте, пожалуйста.

Кстати, я обычно при отладке при Echo On записываю получившееся в файл способом файл.bat >результат.txt 2>&1
Читабельность лучше.
Единственное, если есть пауза, надо на черном экране энтер нажать для завершения батника.

mwz 12-12-2018 22:55 2845639

Вложений: 1
  • cls1.gif (3.80 KB, скачиваний: 15)
Цитата:

Цитата megaloman
не было учтено, что "Documents and Settings" содержит пробелы »

Ну я-то и имел в вижу именно это. Просто чаще всего так бывает при отсутствии кавычек: если выражение не заключено в кавычки, то синтаксический разбор идёт до первого пробела, который рассматривается как разделитель.

Вот теперь вроде нормально (не знаю только, что за значок появился в результате выполнения команды cls :) — тут-то его видно не будет, так что приложил скриншот):
Скрытый текст
c:\TEMP>cls

c:\TEMP>Set "DelFile=*.txt"

c:\TEMP>For /F "delims=" %a In ('reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList" /F "S-1-5-21-*"') Do (For /F "Skip=2 tokens=2,* delims= " %i In ('2>nul reg query "%a" /V ProfileImagePath') Do Echo === %j & Dir /A:-D /B "%j\*.txt" )

c:\TEMP>(For /F "Skip=2 tokens=2,* delims= " %i In ('2>nul reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\S-1-5-21-1449298094-4144929868-1542513627-1030" /V ProfileImagePath') Do Echo === %j & Dir /A:-D /B "%j\*.txt" )

c:\TEMP>Echo === C:\Documents and Settings\UpdatusUser & Dir /A:-D /B "C:\Documents and Settings\UpdatusUser\*.txt"
=== C:\Documents and Settings\UpdatusUser
Test.txt

c:\TEMP>(For /F "Skip=2 tokens=2,* delims= " %i In ('2>nul reg query "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\S-1-5-21-1449298094-4144929868-1542513627-500" /V ProfileImagePath') Do Echo === %j & Dir /A:-D /B "%j\*.txt" )

c:\TEMP>Echo === C:\Documents and Settings\Administrator & Dir /A:-D /B "C:\Documents and Settings\Administrator\*.txt"
=== C:\Documents and Settings\Administrator
Test1.txt

c:\TEMP>(For /F "Skip=2 tokens=2,* delims= " %i In ('2>nul reg query "End of search: 2 match(es) found." /V ProfileImagePath') Do Echo === %j & Dir /A:-D /B "%j\*.txt" )

c:\TEMP>pause
Press any key to continue . . .

c:\TEMP>GoTo :Eof

Iska 12-12-2018 23:42 2845652

Цитата:

Цитата megaloman
Кстати, я обычно при отладке при Echo On записываю получившееся в файл способом файл.bat >результат.txt
Читабельность лучше.
Единственное, если есть пауза, надо на черном экране энтер нажать для завершения батника. »

Far Manager наше всё ;).

Цитата:

Цитата mwz
(не знаю только, что за значок появился в результате выполнения команды cls — тут-то его видно не будет, так что приложил скриншот): »

Вероятно, это 0x0С — FORM FEED, когда хост не может/не знает/не умеет сделать прогон печати, которым, надо полагать, и реализуется очистка консоли в cmd.exe, а в данном случае просто делается попытка отображения его как символа. Можете проверить также посредством echo c символами BELL (0x07), BACKSPACE (0x08) и т.п.

Кстати, что за хост на скриншоте?

mwz 13-12-2018 00:53 2845656

Цитата:

Цитата Iska
Кстати, что за хост на скриншоте? »

На котором? :)
Если не на последнем — то это мой домашний серверок.

А значок... Проверил исходный текст, хотя мог бы и сразу сообразить это сделать — и увидел, что в вывод действительно ушёл код 0x0C. Ну а значок — это просто такой глиф в шрифте, которым пошла вставка: с номером непечатного символа 000С в рамке. При других шрифтах он и смотрится по-другому (или не виден вообще), поскольку глифы другие.

Iska 13-12-2018 00:55 2845657

Цитата:

Цитата mwz
На котором? »

На этом:

явно же не гольная консоль.

mwz 13-12-2018 01:15 2845658

Iska

А, так это окно ввода в FireFox 63.0.3 :)
Куда я Ctrl+V сделал.

А в IE, как я сейчас посмотрел, этот значок не проявляется.

Iska 13-12-2018 01:27 2845659

Цитата:

Цитата mwz
А, так это окно ввода в FireFox 63.0.3
Куда я Ctrl+V сделал. »

Ясно. А где Ctrl-C делался?

mwz 13-12-2018 13:44 2845718

Цитата:

Цитата Iska
А где Ctrl-C делался? »

Перенаправил вывод так, как предложил megaloman (test.bat>result.txt), а затем открыл result.txt в Akelpad — откуда и скопировал. Символ 0x0C там выглядел как прямоугольник, который во многих шрифтах используют как глиф-заместитель (в частности для непечатных символов).

PS
А, наконец-то понял смысл вопроса. :)
Нет, не из консоли.

Iska 13-12-2018 14:33 2845730

Цитата:

Цитата mwz
Перенаправил вывод так, как предложил megaloman (test.bat>result.txt), а затем открыл result.txt в Akelpad — откуда и скопировал. »

Точно, простое перенаправление вывода кажет:

Оказывается, я просто сто лет не использовал команду CLS в пакетных файлах :lol:.

Цитата:

Цитата mwz
А, наконец-то понял смысл вопроса.
Нет, не из консоли. »

Я думал, может какой-нибудь SciTE или ещё что-нибудь подобное (когда увидел вертикальный курсор), которые умеют исполнять код под внешним исполнителем и перехватывать вывод.

megaloman 13-12-2018 14:43 2845734

mwz, Простите меня! Надо делать так: файл.bat >результат.txt 2>&1 При этом и сообщения CMD о ошибках тоже попадут в файл, что при отладке немаловажно. А первый символ при этом меня никогда не напрягал и я о нём даже не задумывался. Спасибо Iska, просветил

Iska 13-12-2018 15:37 2845748

Я тогда напишу сюда же, как сие может выглядеть под Far Manager'ом:
Скрытый текст
Код:

@echo off
setlocal enableextensions enabledelayedexpansion

echo Какой-то вывод
несуществующая команда

endlocal
exit /b 0


где «edit:» — префикс плагина FarCmd, указывающий плагину перехватить вывод («<») stdout и stderr («*») команды, в роли которой в данном случае выступает "%comspec% /c" с параметром «0003.cmd». Перехваченный вывод направляется во временный файл, который открывается в редакторе:

Если нужно направить вывод stdout и stderr в отдельные окна — вместо «*» используется «?».

Команду можно поместить в меню пользователя (вызываемое по «F2») и пользовать по необходимости. Я чаще всего пользую данный плагин для получения справки, в несколько изменённом виде, а именно в виде Lua-кода:
Код:

lua:if CmdLine.Empty then print("edit:<" .. mf.clip(0)); else Keys("CtrlHome");print("edit:<"); Keys("CtrlEnd Enter"); end;
т.е., я набираю в командной строке, например, «for /?», нажимаю «F2», нажимаю «R» (горячая клавиша, заданная этому созданному пункту меню, «Run & Edit»), выполняется вышеуказанный код, который, если командная строка пуста, вводит в командную строку текст «edit:<», затем вводит содержимое буфера обмена и останавливается (позволяя либо сразу выполнить команду по ручному нажатию «Enter», либо предварительно откорректировать её, а потом уже нажимать «Enter»), в противном случае «нажимает» комбинацию клавиш «CtrlHome», помещающую курсор ввода в начало командной строки, вводит в позиции курсора ввода текст «edit:<», затем «нажимает» комбинацию клавиш «CtrlEnd», помещающую курсор ввода в конец командной строки и «нажимает» «Enter» отправляя команду на исполнение. В описанном примере результатом будет открытый редактор, в котором будет находиться вся выведенная справка по команде «for»:


В общем и целом — до чёртиков удобно.

mwz 13-12-2018 16:22 2845756

Цитата:

Цитата megaloman
Надо делать так »

Что, повторить так? Без проблем, но вот тут уже не пойму, как запускается и работает вторая часть. :)

megaloman 13-12-2018 18:16 2845769

mwz, возьмите, например, батник от Iska
Запустите его. (Для определенности обзовём его файл.bat)
Получите на консоли то что в эхо и сообщение об отсутствующей команде.
Запустите файл.bat >результат.txt
Получите в тхт- файле то, что в эхо, и на консоли сообщение об отсутствующей команде
Запустите файл.bat >результат.txt 2>&1
Получите в файле и то, что в эхо, и аварийное сообщение об отсутствующей команде
Стандартно вывод направляется в поток с дескриптором 1 (мы его направляем в файл.
Ошибочные сообщения направляются в поток 2. Указание 2>&1 перенаправляет этот поток туда же, куда направлен поток 1.
Поищите в гугле cmd перенаправление вывода.

alpap 13-12-2018 23:59 2845829

Цитата:

Цитата Iska
... команду CLS »

этот символ можно лицезреть еще так:
Код:

@echo off& for /f %%a in ('cls') do echo:%%a& pause>nul

Iska 14-12-2018 00:25 2845834

alpap, значит, вероятнее всего, моё предположение было неверным, и ClearScreen реализует сам командный процессор через «сладкую парочку» FillConsoleOutputCharacter() и FillConsoleOutputAttribute().


Время: 23:14.

Время: 23:14.
© OSzone.net 2001-