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

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

timahvey 29-08-2019 16:20 2885896

bat-файл на удаление папок и файлов по списку из txt-файла
 
Имеется файл txt, в котором построчно указаны пути к файлам и папкам. Например:
Код:

c:\Program Files\NVIDIA Corporation\license.txt
c:\Program Files\Windows Defender\ThirdPartyNotices.txt

c:\Program Files (x86)\ASUS\ASUS Smart Gesture\AsTPCenter\x86\

Пути на разных разделах и с кириллическими символами.

Можно ли сделать отдельный bat файл, который будет смотреть в рядом лежащий с ним файл need_to_delete.txt и удалять все папки и файлы по указанным (в need_to_delete.txt) адресам?
+ по итогам выдавать инфу: "столько то удалено файлов и папок, столько то места освобождено".

Iska 29-08-2019 16:51 2885901

Цитата:

Цитата timahvey
и с кириллическими символами. »

Упакуйте образец Вашего «файл txt» в архив и приложите к сообщению.

timahvey 29-08-2019 17:31 2885906

Вложений: 1
пароль: picasso

timahvey 29-08-2019 17:33 2885907

P.S. В файле не указаны пути с кириллическими буквами. Но в дальнейшем будут таковые, т.к. есть папки с русскими названиями.

Iska 29-08-2019 18:19 2885914

Цитата:

Цитата timahvey
В файле не указаны пути с кириллическими буквами. »

Укажите. В файле. Я хочу посмотреть на кодировку Вашего файла.

Цитата:

Цитата timahvey
пароль: picasso »

Пароль не нужен.

YuS_2 29-08-2019 19:03 2885923

Цитата:

Цитата timahvey
В файле не указаны пути с кириллическими буквами. »

это важно. необходимо определить кодировку файла...
скрипт powershell подойдет для решения задачи?

megaloman 29-08-2019 21:32 2885936

CMD
Код:

@Echo Off
cls
>nul chcp 1251
        Set "FileIn=%~dp0need_to_delete.txt"
        Set "WorkDisk=C:"

        If Not Exist "%FileIn%" (Echo !!! File "%FileIn%" not found &Pause &Exit /B 2)

        FOR /F "usebackq skip=2 delims=" %%i IN (`"wmic logicaldisk where caption="%WorkDisk%" get FreeSpace,Size /value"`) DO >nul 2>&1 Call Set "%%i"
        Set "F1=%FreeSpace%"

        Set /A Ndir=0
        Set /A Nfile=0

        FOR /F "usebackq delims=" %%s IN ("%FileIn%") DO (
                If Exist "%%s" (
                        If "%%~nxs"=="" (
                                >nul 2>&1 Rd /q /s "%%s" &&Set /A Ndir+=1
                        ) Else (
                                >nul 2>&1 Del /A /F "%%s" &&Set /A Nfile+=1
                        )
                )
        )
        FOR /F "usebackq skip=2 delims=" %%i IN (`"wmic logicaldisk where caption="%WorkDisk%" get FreeSpace,Size /value"`) DO >nul 2>&1 Call Set "%%i"
        Set "F2=%FreeSpace%"

        Echo Total Size %WorkDisk%              =%Size% bytes
        Echo free space before deleting =%F1% bytes
        Echo deleted %Ndir% folders and %Nfile% files 
        Echo free space  after deleting =%F2% bytes

        Set "F1=%F1:~0,-6%"
        Set "F2=%F2:~0,-6%"
        If "%F1%"=="" Set /A F1=0
        If "%F2%"=="" Set /A F2=0
        Set /A Freed=%F2%-%F1%

        Echo %Freed% million bytes freed
pause
Exit /B

Если список имеет кириллические символы в кодировке 866 >nul chcp 1251удалить

alpap 29-08-2019 22:42 2885943

timahvey, не помню точно, утверждать не буду, но был случай когда по примерно такому (как у вас в файле) пути:
c:\Windows\WinToolkit_Temp\
скрипт отказался удалять вроде из-за нехватки прав, но при этом остановился весь процесс. Проконтролируйте этот момент на всякий случай.

timahvey 30-08-2019 09:34 2885980

Цитата:

Цитата YuS_2
скрипт powershell подойдет для решения задачи? »

Да. можно и PowerShell.
Пока у меня кодировка используется 1251.
Цитата:

Цитата megaloman
CMD »

Благодарю! Попробую в ближайшие дни. Я правильно понимаю, сносить будет все файлы: хоть для чтения, хоть скрытые (окромя в папке Windows\System32\) и папки с файлами?

Цитата:

Цитата alpap
скрипт отказался удалять вроде из-за нехватки прав »

А можно это как-то обойти? ну или хотя бы сразу же запрашивать права админа и сносить все к чертям?

timahvey 30-08-2019 11:18 2885996

Цитата:

Цитата megaloman
CMD »

Показывает лишь свободное пространство до и после в байтах.
А можно как-то не вычетом этих цифр, а именно просчетом занимаемого пространства на диске суммировать все высвобожденное пространство в МБ?

megaloman 30-08-2019 18:12 2886045

просчетом занимаемого пространства на диске суммировать все высвобожденное пространство.
Но будет работать только если общий объем высвобождаемого места не более 2Gb
Иначе надо vbs или JS либо еще что-нибудь
Код:

@Echo Off
cls
>nul chcp 1251
        Set "FileIn=%~dp0need_to_delete.txt"

        If Not Exist "%FileIn%" (Echo !!! File "%FileIn%" not found &Pause &Exit /B 2)

        Set /A Ndir=0
        Set /A Nfile=0
        Set /A Zfile=0

        FOR /F "usebackq delims=" %%s IN ("%FileIn%") DO (
                If Exist "%%s" (
                        If "%%~nxs"=="" (
                                FOR /F "usebackq delims=" %%f IN (`2^>nul Dir "%%s" /b /s /a:-d`) DO (
                                        Del "%%f" &&(Set /A Zfile+=%%~zf &Set /A Nfile+=1)
                                )
                                >nul 2>&1 Rd /q /s "%%s" &&Set /A Ndir+=1
                        ) Else (
                                Del /A /F "%%s" &&(Set /A Zfile+=%%~zs &Set /A Nfile+=1)
                        )
                )
        )
        Set /A ZfileK=%Zfile%/1024
        Set /A ZfileM=%Zfile%/(1024*1024)

Echo Ndir=%Ndir%
Echo Nfile=%Nfile%
Echo Zfile=%Zfile% byte
Echo Zfile=%ZfileK% Kbyte
Echo Zfile=%ZfileM% Mbyte

pause
Exit /B

считает реальное число удаленных файлов, в том числе в каталогах и подкаталогах. суммирует их общий объем. Количество папок считает по папкам, помянутым в списке, подпапки не рассматриваются

YuS_2 30-08-2019 20:04 2886054

Цитата:

Цитата timahvey
можно и PowerShell. »

скрипт powershell
Код:

function Get-SizeDirectory {
        param (
                [parameter(ValueFromPipeline=$true)]
                [string[]]$arr
        )
        process {
                foreach ($item in $arr) {
                        try {
                                $tmp = gi $item -ea 1
                                $math = dir -lit $tmp.fullname -rec -force|
                                        ?{!$_.psiscontainer}|measure -prop length -sum
                                [pscustomobject]@{
                                        Name = $tmp.name #Имя каталога
                                        Fullname = $tmp.fullname #Абсолютный путь с именем
                                        Count = $math.count #Счетчик файлов в каталоге, рекурсивно
                                        Size = $math.sum #Размер каталога
                                }
                        } catch {
                                $(
                                        ('{0:dd.MM.yy HH:mm:ss}' -f (get-date)
                                )+' - folder_error'),$item.fullname,$_|
                                out-file $logerr -enc utf8 -app
                        }
                }
        }
}

# Файл со списком
$list = 'need_to_delete.txt'
# Кодировка файла
$enc = 'default'
# Логи
$log = 'log.log'
$logerr = 'error.log'

gc $list -enc $enc|%{
        try{
                $a = gi -lit $_ -force -ea 1
                if(test-path -lit $a.fullname -patht 'leaf'){
                        $x = $a.length
                        del -lit $a.fullname -force -ea 1
                        $size += $x; $cntfile += 1
                } else {
                        $b = $a.fullname|get-sizedirectory
                        del $a.fullname -rec -force -ea 1
                        $size += $b.size; $cntfolder += 1
                }
        }catch{
                $(('{0:dd.MM.yy HH:mm:ss}' -f (get-date))+' - item_error'),$_|
                out-file $logerr -enc utf8 -app
        }
}

@"
Удалено файлов: $cntfile
Удалено каталогов: $cntfolder (без учета подкаталогов и вложенных файлов)
$('Освобождено: {0:G} Mb' -f ($size/1mb))
"@|tee $log


Чтобы не было проблем с доступом, запускать лучше от имени админа.
При ошибках будет выводить логи.
Считать будет общий размер каталогов и файлов из списка
При подаче на удаление каталога (указание пути к каталогу, а не к файлу в списке), в количестве удаленных будет учтена только единица самого каталога из списка... ни подкаталоги, ни вложенные файлы не считаются.
А как надо?

DJ Mogarych 30-08-2019 20:43 2886056

Проще сначала всё посчитать, а потом удалить. Первая строчка требует запуска от админа.
Округление только в конце, т. к. определение каталогов сделано по нулевой длине, вернее, по её отсутствию. Можно сделать по фен-шую, в том числе отчёт в csv, но вряд ли это в данном случае нужно.
Код:

#Requires -RunAsAdministrator

$all = @()
gc ~\Downloads\need_to_delete.txt |% {
$temp = "" |select "path","length"
$temp.path = "$_"
$temp.length = get-item "$_" |select -expand length -ErrorAction Ignore
$all += $temp
}

$all += "`n" + "Файлов: " + ($all |? length -ne $null |measure).count
$all += "Каталогов: " + ($all |? length -eq $null |measure).count
$all += "Общий размер: " + [math]::Round((($all |select -expand length |measure -sum).sum / 1MB),2) + " МБ"

$all |out-file ~\Downloads\reports.txt

$all.path |% {Remove-Item "$_" -Recurse -Force -Confirm:$false -ErrorAction Ignore}


alpap 30-08-2019 21:23 2886063

Цитата:

Цитата timahvey
сразу же запрашивать права админа »

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

YuS_2 30-08-2019 22:12 2886068

Цитата:

Цитата DJ Mogarych
определение каталогов сделано по нулевой длине »

Тут одна загвоздка:
Цитата:

Цитата timahvey
столько то места освобождено »

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

Iska 30-08-2019 22:23 2886072

YuS_2, в реальности, если уж строго придерживаться заявленного ТЗ «столько то места освобождено» — ещё хуже: а) часть удалённых файлов, банально умещавшихся в самом MFT, никак не повлияет на «освобождённое место», б) к размерам «освобождённого места» нужно добавлять не просто размеры файлов, а размеры, которые файлы занимают на диске (освобождаемые кластеры).

DJ Mogarych 30-08-2019 22:24 2886073

YuS_2, не понял, в чём проблема. Сумма размеров файлов и будет освобождённым местом, нет?

timahvey 30-08-2019 23:55 2886082

Цитата:

Цитата DJ Mogarych
Можно сделать по фен-шую »

Верно, достаточно и этого варианта! На нём пока и остановлюсь.

Единственное, что хотелось бы решить, так это удаление фалов системных. Можно ли это как-то обойти?
Например, файл c:\Program Files\Windows Defender\ThirdPartyNotices.txt сносится через мелкую утилиту "Unlocker". Возможно она просто автоматом в NTFS правах делает меня (пользователя запустившего скрипт) владельцем файла?

YuS_2 30-08-2019 23:57 2886083

Цитата:

Цитата Iska
часть удалённых файлов, банально умещавшихся в самом MFT, никак не повлияет на «освобождённое место» »

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

Цитата:

Цитата Iska
часть удалённых файлов, банально умещавшихся в самом MFT, никак не повлияет на «освобождённое место» »

то же самое...

Цитата:

Цитата Iska
к размерам «освобождённого места» нужно добавлять не просто размеры файлов, а размеры, которые файлы занимают на диске (освобождаемые кластеры). »

Этого точно нет в условии, да и проблематично это было бы, считать средствами powershell.

Цитата:

Цитата DJ Mogarych
не понял, в чём проблема. Сумма размеров файлов и будет освобождённым местом, нет? »

Нет. Если говорить о размерах каталога, то, это, как раз, сумма размеров ВСЕХ файлов, содержащихся в нем.
И именно поэтому, такая конструкция:
Цитата:

Цитата DJ Mogarych
$temp.length = get-item "$_" |select -expand length -ErrorAction Ignore »

не покажет размера, если "$_" - каталог.

YuS_2 31-08-2019 00:15 2886085

Цитата:

Цитата timahvey
Возможно она просто автоматом в NTFS правах делает меня (пользователя запустившего скрипт) владельцем файла? »

Вот именно, даже администратор не сможет удалять то, владельцем чего является не он, а пользователь с более высоким уровнем доступа... по иерархии прав доступа в Windows.
В частности, владельцы с именем TrustedInstaller и System, имеют более высокий уровень, чем Администратор.

Iska 31-08-2019 02:46 2886090

Цитата:

Цитата YuS_2
Это смотря что понимать под "освобожденным местом". Если расчетные показатели, то да, а если фактические, то это, как раз, только размер файлов... »

Судя по ТЗ — это именно занимаемое место на диске. Оно же — фактически. А теоретически, расчётное — это сумма объёмов файлов.


Цитата:

Цитата YuS_2
…да и проблематично это было бы, считать средствами powershell. »

Да и не нужно.

YuS_2, DJ Mogarych, в Scripting.FileSystemObject свойство .Size класса Folder как раз показывает размер каталога, подсчитывая сумму объёмов всех входящих в него файлов, включая подкаталоги. В классах .Net, относящихся к работе с каталогами файловой системы, как я понял, аналогичное свойство отсутствует, так?

DJ Mogarych 31-08-2019 07:51 2886096

Всё, понял. Я просто генерил свой текстовый файл, где все объекты были внутри одного каталога, поэтому содержимое вложенных каталогов можно было не учитывать, т. к. их пути уже были в файле.

Можно вставить вот такую конструкцию для подсчёта размеров каталогов:

Код:

gc ~\Downloads\need_to_delete.txt |% {
    if (((Get-Item "$_") -is [System.IO.DirectoryInfo]) -eq 'True') {
    (gci "$_" -Recurse |select -expand length |measure -sum).sum / 1MB
    }
}

Цитата:

Цитата timahvey
файл c:\Program Files\Windows Defender\ThirdPartyNotices.txt сносится через мелкую утилиту "Unlocker". Возможно она просто автоматом в NTFS правах делает меня (пользователя запустившего скрипт) владельцем файла? »

Файл не удаляется, если какой-либо процесс его в данный момент использует, и Анлокер просто "освобождает" файл из-под процесса. Не могу назвать это хорошей практикой, лучше подобные вещи не делать без крайней необходимости.

YuS_2 31-08-2019 10:12 2886101

Цитата:

Цитата Iska
теоретически, расчётное — это сумма объёмов файлов. »

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

Цитата:

Цитата Iska
В классах .Net, относящихся к работе с каталогами файловой системы, как я понял, аналогичное свойство отсутствует, так? »

Утверждать не берусь, но пока не попадалось, а целенаправленно не искал.
К тому же, мы всегда можем дернуть тот же Scripting.FileSystemObject:
Код:

$fso = new-object -com scripting.filesystemobject
$folder = $fso.getfolder("d:\test")
$folder.size

В общем, с этим проблем немного.

Цитата:

Цитата DJ Mogarych
(gci "$_" -Recurse |select -expand length |measure -sum).sum / 1MB »

Для начала, имеет смысл протестировать этот метод... сразу скажу, он негоден, начиная с версии PS -v 3.0, т.к. в версии 2.0 было:
Цитата:

Параметр Recurse работает только в том случае, если путь указывает на контейнер с дочерними элементами, например "C:\Windows" или "C:\Windows\*", и не работает, если путь указывает на элементы без дочерних элементов, например "C:\Windows\*.exe".
Теперь же, ошибки он тоже не выдаст, но при условии, что элемент $_ - файл, он выдаст не размер файла, а именно рекурсивно размер родительского каталога относительно файла $_... как-то так.

DJ Mogarych 31-08-2019 10:44 2886104

YuS_2, там условие стоит - "если каталог".

Единственное - можно убрать один ненужный пайп:
Код:

(gci "$_" -Recurse |measure -sum length).sum / 1MB

Iska 31-08-2019 10:45 2886105

Цитата:

Цитата YuS_2
Но, в любом случае, посчитать мы можем только то, что отдает система... »

Взять свободное место на разделе до, взять свободное место на разделе после, показать разницу :). Тут, конечно, надо будет вести учёт, с каких разделов мы удаляем.

YuS_2 31-08-2019 11:56 2886112

Цитата:

Цитата DJ Mogarych
там условие стоит - "если каталог". »

Да, с условным оператором работать будет, но всё равно, к общей сумме придется увязывать в конечном итоге... и файлы надо не забыть посчитать внутри каталога, если таки понадобится информация именно по файлам, а не единице каталога... в моем варианте они считаются, просто не используются эти данные.

Цитата:

Цитата Iska
Взять свободное место на разделе до, взять свободное место на разделе после, показать разницу . Тут, конечно, надо будет вести учёт, с каких разделов мы удаляем. »

На расшаренном каталоге, например, по сетевому пути... :)

timahvey 31-08-2019 12:34 2886116

Все же пока будет оптимальным этот вариант.
Цитата:

Цитата megaloman
просчетом занимаемого пространства на диске суммировать все высвобожденное пространство. »

Удобно, запустить пакетный файл на любом ПК в пару кликов без копипастов..

Из хотелок осталось лишь: возможность удалять файлы и папки других владельцев. Т.е., что б скрипт автоматом при выдаче "Отказано в доступе." делал смену владельца (скрипт то будет запущен из под пользователя с админ правами) для удаления уже с повышенными привилегиями.
Но это уже смахивает на мини программу :)

В пн.-вт. закроем тему, если нет доп. предложений.

Благодарю всех участвующих!

Iska 31-08-2019 14:12 2886142

Цитата:

Цитата YuS_2
На расшаренном каталоге, например, по сетевому пути... »

Это да. Хотя, если временно «примапить»… Хрен его знает, мне даже проверить негде.

YuS_2 01-09-2019 01:30 2886199

Цитата:

Цитата Iska
Хотя, если временно «примапить»… »

Да, получить свободное пространство сетевого диска можно через get-item, тут только надо будет как-то контролировать тип пути, unc или замапленный диск.
Если путь не UNC, то всё сводится к этому:
Код:

(($x = gi z:\).psprovider.drives|? name -ceq $x.psdrive).free
а если путь unc, то придется его мапить... ну, а если путей таких много, придется подключать, замерять, отключать в каждой итерации...
В общем, имхо, проще посчитать сумму размеров файлов.

Iska 01-09-2019 02:14 2886202

Цитата:

Цитата YuS_2
В общем, имхо, проще посчитать сумму размеров файлов. »

Не, проще не обрабатывать UNC, объявив сие фичей ;).

YuS_2 01-09-2019 08:15 2886210

Цитата:

Цитата Iska
проще не обрабатывать UNC, объявив сие фичей »

ну, это-то да, как вариант... :good: :ok: :smoke:

megaloman 01-09-2019 10:31 2886219

Iska, YuS_2,
Цитата:

Но поезд идёт, и бутыль опустела, и тянет поговорить...
Если WSH, то .GetDriveName справляется и с буквой и с UNC. Далее .GetDrive(то что получили в GetDriveName).FreeSpace считает свободное место. Массив по помянутым в списке буквам диска и UNC-путям организовать не проблема,
Например
Код:

FileIn = "Z:\need_to_delete.txt"

With CreateObject("Scripting.FileSystemObject")
    On Error Resume Next
    With .OpenTextFile(FileIn, 1)
        LErr = Not Err.Number <> 0
        If Not LErr Then
            MsgBox "Error open file " + vbCrLf + vbCrLf + FileIn + vbCrLf + vbCrLf + "Err.Number " + CStr(Err.Number) + vbCrLf + Err.Description
            WScript.Quit 1
        Else
            InTxt = Split(.ReadAll, vbCrLf)
            LErr = Not Err.Number <> 0
            If Not LErr Then
                MsgBox "Error read file " + vbCrLf + vbCrLf + FileIn + vbCrLf + vbCrLf + "Err.Number " + CStr(Err.Number) + vbCrLf + Err.Description
                WScript.Quit 1
            End If
        End If
        .Close
    End With
    On Error GoTo 0
   
    jN = -1
    AllDisk = ""
   
    For Each jName In InTxt
        jN = jN + 1
        InTxt(jN) = Trim(jName)
        jDisk = .GetDriveName(InTxt(jN))
        If jDisk <> "" Then
            If InStr(1, AllDisk, jDisk) = 0 Then AllDisk = AllDisk + "*" + jDisk
        End If
    Next
   
    AllDisk = Split(Mid(AllDisk, 2), "*")
    jN = UBound(AllDisk)
   
    Msg = ""
    ReDim DFree(jN + 1)
    For j = 0 To jN
        DFree(j) = .GetDrive(AllDisk(j)).FreeSpace
        Msg = Msg + AllDisk(j) + "  " + CStr(DFree(j) / 1024 / 1024) + vbCrLf
    Next
    MsgBox Msg
End With

а затем посчитать разность места до некоего действа и после него на каждом из элементов. А подсчитывать число удалённых файлов и папок практически ни о чём - зачем это нужно? С правами по любому напряжно ... :Beer:

YuS_2 01-09-2019 20:01 2886287

Цитата:

Цитата megaloman
Но поезд идёт, и бутыль опустела, и тянет поговорить... »

Цитата:

А первый кричал - куда хотим, туда едем, и можем если надо cвернуть,
Второй отвечал, что поезд проедет лишь там, где проложен путь.
Цитата:

Цитата megaloman
А подсчитывать число удалённых файлов и папок практически ни о чём - зачем это нужно? С правами по любому напряжно »

удалили - посчитали, не удалили - запись в лог ошибок. Далее анализ. Но согласен, что цифры количества удаленных элементов не несут никакого смысла.


Цитата:

Цитата megaloman
Если WSH, то .GetDriveName справляется и с буквой и с UNC. »

да справиться-то не проблема, вопрос только в надобности ТС-у всего этого кода...
так-то можно легко получить свободное пространство удаленной машины:
Код:

(icm -comp serv1 {Get-PSDrive}).free|measure -sum
т.е. надо только определить, что путь является unc путем, выделить имя сервера и вуаля...

timahvey 01-09-2019 23:19 2886299

Цитата:

Цитата YuS_2
цифры количества удаленных элементов не несут никакого смысла »

Суть лишь в том, что если покажет "удалено 10 файлов", то сразу пойдут мысли "что-то тут не то или уже проводилось удаление ранее".

Iska 02-09-2019 01:59 2886304

Цитата:

Цитата YuS_2
т.е. надо только определить, что путь является unc путем, выделить имя сервера и вуаля... »

Не, ещё надо по имени разделённого ресурса определить, на каком разделе он расположен.

YuS_2 02-09-2019 06:39 2886308

Цитата:

Цитата timahvey
что-то тут не то или уже проводилось удаление ранее »

Ну, хорошо, получили мы цифру 9, вместо 10 (условно)... а дальше, что делать будем, что даст для анализа эта недостающая единица? Каждый файл из списка проверять - удалился или нет? Зачем тогда скрипт? Ведь список может состоять и из 10000 файлов... мне, например, было бы жалко своего времени на подобные поиски.
Вот, в чем вопрос.

Цитата:

Цитата Iska
Не, ещё надо по имени разделённого ресурса определить, на каком разделе он расположен. »

Тоже, сначала, решил, что надо бы определить, но потом подумалось - а какую это даст информацию и для чего? Ведь требуется, всего лишь, определить освобожденное пространство.
Разницу нетрудно посчитать по всем разделам удаленной машины...
Цитата:

Цитата YuS_2
(icm -comp serv1 {Get-PSDrive}).free|measure -sum »

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

((get-psdrive).free|measure -sum).sum
- запущенное на локальной машине до удаления и после него, выдаст цифры, разница которых и будет искомым освобожденным пространством.

timahvey 02-09-2019 10:56 2886329

Цитата:

Цитата YuS_2
цифру 9, вместо 10 »

:) Нет, цифру 9 вместо 123 (или 500).

Iska 02-09-2019 17:17 2886382

Цитата:

Цитата YuS_2
а какую это даст информацию и для чего? »

А… Вы имеете в виду, просто посчитать сумму всех свободных мест. Понял Вашу мысль.

YuS_2 03-09-2019 08:54 2886436

Цитата:

Цитата timahvey
Нет, цифру 9 вместо 123 (или 500). »

Допустим... и что будет предприниматься? Какие файлы удалились, а какие нет? Где искать? Сравнивать весь список с наличием файлов? Сизифов труд...
В этих цифрах информации ноль.

Цитата:

Цитата Iska
просто посчитать сумму всех свободных мест. »

Да, типа того. Правда в таком методе есть большой недостаток, хоть он и будет работать быстрее, но в нем не учитывается наличие других процессов, работающих с файловой системой. Т.е. существует большая вероятность, что свободное пространство может и в минус уйти, и больше оказаться, чем сумма размера удаленных элементов.
В общем, использование метода будет сильно зависеть от требований точности в определении свободного пространства. Наиболее точный, всё же, это подсчет размера удаляемых элементов.

timahvey 03-09-2019 09:00 2886437

Цитата:

Цитата YuS_2
Какие файлы удалились, а какие нет? Г »

Скрипт от megaloman как раз таки и показывает какие не удалились файлы.
Суть в цифре, как уже ранее писал, наглядность: удалило 9 файлов - значит либо скрипт уже был запущен ранее, либо что-то пошло не так., Удалило 100+ файлов - ок. (понятно, что в зависимости от количества элементов в списке эта цифра может быть больше).

megaloman 03-09-2019 09:11 2886438

Попробую примерить костюмчик на себя:
Зачем всё это нужно - удалить с диска заведомо ненужное и проконтролировать свободное место.
Главное в процессе - почему что-то не удалилось. Для этого нужен лог с отказами. Его изучение полезно.
В принципе, не столь важна цифра освобожденного места.
Но если очень хочется, удаляем каждый файл из указанных и каждый файл в указанных папках и их подпапках и суммируем их объем или пишем в лог отказ и его причину.

timahvey 03-09-2019 09:17 2886440

Цитата:

Цитата megaloman
Зачем всё это нужно »

все именно так!

megaloman 03-09-2019 21:13 2886529

timahvey,
VBS. Считает свободное место на диске до и после работы скрипта и разницу в Mb.
Количество реально удалённых файлов и их общий объём.
При отказе в удалении имя файла и причина отказа заносится в лог.
Код:

FileIn = "Z:\need_to_delete.txt"
FileLog = "Z:\need_to_delete.txt.Err.log"

Set FSO = CreateObject("Scripting.FileSystemObject")
With FSO
    Set Finfo = .OpenTextFile(FileLog, 2, True)

    On Error Resume Next
    With .OpenTextFile(FileIn, 1)
        LErr = Not Err.Number <> 0
        If Not LErr Then
            MsgBox "Error open file " + vbCrLf + vbCrLf + FileIn + vbCrLf + vbCrLf + "Err.Number " + CStr(Err.Number) + vbCrLf + Err.Description
            WScript.Quit 1
        Else
            InTxt = Split(.ReadAll, vbCrLf)
            LErr = Not Err.Number <> 0
            If Not LErr Then
                MsgBox "Error read file " + vbCrLf + vbCrLf + FileIn + vbCrLf + vbCrLf + "Err.Number " + CStr(Err.Number) + vbCrLf + Err.Description
                WScript.Quit 1
            End If
        End If
        .Close
    End With
    On Error GoTo 0
   
    jN = -1
    strAllDisk = ""
   
    For Each jName In InTxt
        jN = jN + 1
        InTxt(jN) = Trim(jName)
        jDisk = .GetDriveName(InTxt(jN))
        If jDisk <> "" Then
            If InStr(1, strAllDisk, jDisk) = 0 Then strAllDisk = strAllDisk + vbCrLf + jDisk
        End If
    Next
    strAllDisk = Mid(strAllDisk, 3)
    AllDisk = Split(strAllDisk, vbCrLf)
    jN = UBound(AllDisk)
   
    strAllFree1 = ""
    Msg = ""
    ReDim AllFree1(jN + 1), AllFree2(jN + 1)
   
    On Error Resume Next
    For j = 0 To jN
        Err.Number = 0
        AllFree1(j) = .GetDrive(AllDisk(j)).FreeSpace
        If Err.Number <> 0 Then
            AllFree1(j) = Err.Description
            strAllFree1 = strAllFree1 + vbCrLf + AllDisk(j) + " = " + AllFree1(j)
        Else
            strAllFree1 = strAllFree1 + vbCrLf + AllDisk(j) + " = " + CStr(Round(AllFree1(j) / 1024 / 1024, 1)) + " Mb"
        End If
    Next
    On Error GoTo 0
    Msg = Msg + "До обработки свободно:" + vbCrLf + "=====" + strAllFree1
   
    TotalNfiles = 0
    TotalDelete = 0
       
    On Error Resume Next
    For Each F In InTxt
        If .FileExists(F) Then
            SizeOne = .GetFile(F).Size
            Err.Number = 0
            .DeleteFile F, True
            If Err.Number <> 0 Then
                Finfo.WriteLine ("--- " + Err.Description + " -> " + F)
            Else
                TotalNfiles = TotalNfiles + 1
                'Finfo.WriteLine "+++ Ok" + " -> " + F + "  " + CStr(TotalNfiles) + "  " + CStr(SizeOne) + "  " + CStr(TotalDelete)
                TotalDelete = TotalDelete + SizeOne
            End If
        Else
            If .FolderExists(F) Then
                If Right(F, 1) = "\" Then F = Left(F, Len(F) - 1)
                Call AllFiles(FSO, Finfo, F, TotalNfiles, TotalDelete)
                Err.Number = 0
                .DeleteFolder F, True
                If Err.Number <> 0 Then
                    Finfo.WriteLine ("--- " + Err.Description + " -> " + F)
                End If
            End If
        End If
    Next
    On Error GoTo 0
   
    strAllFree2 = ""
   
    On Error Resume Next
    For j = 0 To jN
        Err.Number = 0
        AllFree2(j) = .GetDrive(AllDisk(j)).FreeSpace
       
        If Err.Number <> 0 Then
            AllFree2(j) = Err.Description
            strAllFree2 = strAllFree2 + vbCrLf + AllDisk(j) + " = " + AllFree2(j)
        Else
            strAllFree2 = strAllFree2 + vbCrLf + AllDisk(j) + " = " + CStr(Round(AllFree2(j) / 1024 / 1024, 1)) + " Mb"
        End If
    Next
    On Error GoTo 0
   
'    Msg = Msg + vbCrLf + vbCrLf + "Удалено " + CStr(TotalNfiles) + " файлов " + CStr(TotalDelete) + " bytes"
    Msg = Msg + vbCrLf + vbCrLf + "Удалено " + CStr(TotalNfiles) + " файлов " + CStr(Round(TotalDelete / 1024/ 1024,1)) + " Mb"
    Msg = Msg + vbCrLf + vbCrLf + "После обработки свободно:" + vbCrLf + "=====" + strAllFree2

    TotalFree = 0
    For j = 0 To jN
        If IsNumeric(AllFree2(j)) And IsNumeric(AllFree1(j)) Then
            TotalFree = TotalFree + AllFree2(j) - AllFree1(j)
        End If
    Next
    On Error GoTo 0
   
    Msg = Msg + vbCrLf + vbCrLf + "Суммарная разность = " + CStr(Round(TotalFree / 1024 / 1024, 1)) + " Mb"
    Finfo.Close
End With

MsgBox Msg
' ============================
Sub AllFiles(FSO, Finfo, WDir, TotalNfiles, TotalDelete)
    Set Folds = FSO.GetFolder(WDir)
    Set SubF = Folds.SubFolders
    Set Files = Folds.Files
       
    On Error Resume Next
    For Each jF In Files
        SizeOne = jF.Size
        Err.Number = 0
        FSO.DeleteFile jF, True
        If Err.Number <> 0 Then
            Finfo.WriteLine ("--- " + Err.Description + " -> " + jF)
        Else
                TotalNfiles = TotalNfiles + 1
                'Finfo.WriteLine "+++ Ok" + " -> " + jF + "  " + CStr(TotalNfiles) + "  " + CStr(SizeOne) + "  " + CStr(TotalDelete)
                TotalDelete = TotalDelete + SizeOne
        End If
    Next
    On Error GoTo 0

    For Each Folder In SubF
        Call AllFiles(FSO, Finfo, WDir + "\" + Folder.Name, TotalNfiles, TotalDelete)
    Next
End Sub


timahvey 04-09-2019 10:29 2886583

Вложений: 1
Цитата:

Цитата megaloman
megaloman »

Благодарю. В конечном итоге удобный log с путями, где отказано в доступе было.
А вот картинка c кракозябрами и минусовым объемом высвобожденного пространства.

timahvey 04-09-2019 10:37 2886587

Вложений: 1
Цитата:

Цитата megaloman
1251»


timahvey 04-09-2019 10:45 2886590

Вложений: 1
Символ в символ с тем что Вы выложили.
Возможно Вы сами ошиблись кодировкой, т.к. даже в web показывает кракозябры.

megaloman 04-09-2019 11:40 2886601

Вложений: 1
Цитата:

Цитата timahvey
Символ в символ с тем что Вы выложили.
Возможно Вы сами ошиблись кодировкой, т.к. даже в web показывает кракозябры. »

В общем, сам дурак :) . Не посмотрел, когда переносил скрипт на форум. Исправил (см выше). На всякий случай приложил файл.

timahvey 04-09-2019 11:49 2886602

Цитата:

Цитата megaloman
Исправил »

Красота :)


Время: 23:24.

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