Как известно, Windows не позволяет производить какие-либо операции с целым рядом файлов и каталогов по причине отсутствия у пользователя прав или хотя бы потому, что файл в данный момент используется. Как правило, это системные объекты, то есть те, владельцами которых являются Система, а также службы Local Service и TrustedInstaller. А еще проблемы с доступом могут возникнуть при попытке изменить файл или папку, созданные учетной записью, которая затем была удалена. Чтобы просмотреть имя владельца, необходимо зайти в свойства объекта, переключиться на вкладку «Безопасность» и нажать кнопку «Дополнительно».
Не очень удобно, так как приходится выполнять много действий.
Как быстро узнать имя владельца любого объекта в Windows 10
{banner_google1}
Вы можете упростить себе задачу получению имени владельца любого файла или папки в Windows, добавив в контекстное меню Проводника соответствующую опцию. Для этого придется применить твик реестра. Он несложный, но изменения нужно внести в несколько ключей, поэтому будет лучше воспользоваться готовым решением.
Скачайте по ссылке
этот архив
и распакуйте его содержимое в любое удобное расположение.
Выполните слияние REG-файла AddViewOwner.reg.
После этого в контекстном меню Проводника у вас появится новый пункт «Владелец объекта».
Кликните ПКМ по любому файлу или папке и выберете в меню эту новую опцию. Тут же откроется консоль PowerShell, в которой будет указано имя владельца данного объекта.
Для удаления опции из меню выполните слияние файла RemoveViewOwner.reg.
В обоих случаях изменения вступают в силу немедленно.
- Примечание: этим способом не получится узнать имя владельца некоторых типов ярлыков, например, ярлыков апплетов, созданных в классической панели управления и помещенных на рабочий стол.
Тот же самый результат можно было получить, используя PowerShell командлет Get-ACL с указанием пути к вашему файлу. Этот командлет получает объекты, предоставляющие дескриптор безопасности исследуемого ресурса. Помимо прав доступа, ACL содержит также информацию о владельце, которую и выводит команда Get-ACL. Но использование консоли PowerShell для определения владельца было бы еще менее удобным, чем просмотр дополнительных свойств, поэтому добавление команды в контекстное меню в данном случае самое лучшее решение.
Иногда для оптимизации управления хранением данных на диске администратору требуется узнать, какие файлы принадлежат пользователю и сколько места на диске они занимают. Эту информацию нельзя получить из пользовательского графического интерфейса Windows или с помощью сценария Windows. Я написал библиотеку ActiveX DLL и сценарий VBScript, который выводит список файлов, принадлежащих определенному владельцу, а также размеры этих файлов
Получение информации, не предоставляемой средством квотирования дисков в Windows
.
Ограничения функции квотирования диска
В Windows 2000 и более поздних версиях имеется функция квотирования диска, которую можно использовать для отслеживания или ограничения работы с диском NTFS. Для просмотра или настройки квотирования диска нужно щелкнуть правой кнопкой мыши на выбранном диске в Windows Explorer, выбрать пункт Properties, и перейти на закладку Quota.
Щелкните на кнопке Quota Entries, чтобы увидеть список пользователей и объем занимаемого каждым из них дискового пространства. Эта информация берется из сведений о владельце в файлах NTFS. Диалоговое окно Quota Entries позволяет переопределить записи квот, установленные по умолчанию, последовательно (один пользователь за другим), добавлять и удалять записи квот и даже импортировать и экспортировать их. К сожалению, настраивать записи квот на основе групп невозможно, а функция квотирования может быть разрешена или запрещена только для томов. Однако даже с этими ограничениями функция квотирования диска может быть полезной.
Окно Quota Entries отображает список владельцев файлов и объем используемого ими дискового пространства, но операционная система не предоставляет способ получения списка файлов, принадлежащих пользователю, если только не щелкнуть правой кнопкой мыши на записи пользователя, не выбрать пункт Delete, а потом Yes. Если пользователь имеет файлы на данном томе, Windows отобразит диалоговое окно, которое позволит удалить или присвоить себе право владения файлами пользователя. В этом окне отображаются файлы, принадлежащие пользователю, но не показано занимаемое ими дисковое пространство. Также нет возможности экспортировать список файлов в новый файл для отчетности. Это ограничение может вызвать проблемы, если пользователи начнут превышать объем имеющегося дискового пространства.
Чтобы решить задачу построения списка файлов и дискового пространства для данного владельца файлов, я решил написать сценарий. Сценарии Windows не позволяют получить имя владельца файла, и хотя существует возможность узнать имя владельца файла с помощью средств Windows Management Instrumentation (WMI), я решил отказаться от нее из соображений сохранения производительности. Вместо этого я создал библиотеку ActiveX DLL GetOwner.dll, которая возвращает имя владельца файла. Еще я написал сценарий OwnedBy.vbs на VBScript, использующий библиотеку DLL для вывода неограниченного списка файлов, принадлежащих определенному пользователю, их размеров и содержащих их папок. Можно настроить вывод списка в файл для дальнейшего анализа и при необходимости импортировать его в электронную таблицу или базу данных.
Можно загрузить файлы GetOwner.dll, OwnedBy.vbs и исходный код библиотеки DLL с сайта Windows IT Pro/RE (ссылка на файл 46487.zip). Некоторые читатели не смогут воспользоваться библиотекой DLL, даже при наличии исходного кода. Для них я написал версию файла OwnedBy.vbs, которая использует файл ADsSecurity.dll из набора разработчика программного обеспечения (SDK) для Active Directory Service Interfaces (ADSI). Однако, по возможности, я рекомендую задействовать библиотеку GetOwner.dll, для сохранения производительности: судя по моим тестам, данный вариант работает почти в 9 раз быстрее.
Требования сценария
Для работы OwnedBy.vbs под Windows 2000 необходим пакет VBScript 5.6. Это требование можно удовлетворить, установив пакет Microsoft Internet Explorer (IE) 6.0. В системах Windows Server 2003 и Windows XP пакет VBScript 5.6 является частью операционной системы.
Сценарий также требует регистрации библиотеки GetOwner.dll на локальном компьютере. Для этого нужно скопировать файл GetOwner.dll в папку (например, %systemroot%system32) и ввести в командной строке следующую команду:
regsvr32 [/s] pathgetowner.dll
где path — путь к файлу getowner.dll. Параметр /s (silent) отключает появление диалогового окна с подтверждением. Чтобы удалить библиотеку DLL из реестра, следует добавить параметр /u после команды regsvr32. Для удаления без подтверждения нужно одновременно использовать параметры /u и /s. Чтобы иметь возможность удалять и добавлять библиотеки DLL в реестр, пользователь должен быть членом локальной группы Administrators.
Для компиляции библиотеки GetOwner.dll я использовал пакет Visual Basic (VB) 6.0. Рабочий модуль VB (msvbvm60.dll) устанавливается по умолчанию вместе с системой Windows 2000 и более поздними версиями.
Использование сценария OwnedBy.vbs
Из-за того, что сценарий OwnedBy.vbs использует для вывода окно команд, он должен исполняться с применением хоста CScript. Для настройки CScript в качестве хоста по умолчанию для текущего пользователя нужно ввести в командную строку следующую команду:
cscript //h:cscript //nologo //s
Сценарий OwnedBy.vbs использует следующий синтаксис командной строки:
[cscript] ownedby.vbs [/s] [/d:char] [/o:owner] [/nh] [/ns]
Ключевое слово cscript требуется только в том случае, если узел CScript не является хостом сценария по умолчанию. Другие параметры командной строки могут присутствовать всегда.
Необходимо указать одно или несколько имен папок вместо параметра . Если имя папки содержит пробелы, его следует заключить в кавычки. Если требуется получить информацию по файлам в подкаталогах, добавьте параметр /s. Сценарий выдает выходные данные в форме столбцов. По умолчанию в выходных данных столбцы отделяются друг от друга символом табуляции. Чтобы указать другой разделительный символ, используйте параметр /d, сопровождаемый символом «;», например ключ /d:; позволяет вывести список, разделяемый символом «;».
Можно указать, что в списке должны отображаться только файлы, принадлежащие определенному пользователю. Для этого нужно ввести ключ /o и заменить параметр owner именем пользователя в формате «доменимя пользователя». Если не указать имя домена, используется текущий домен (тот, в котором вы регистрировались). Если не указать ключ /o, сценарий OwnedBy.vbs включает в список файлы, принадлежащие каждому из пользователей.
По умолчанию сценарий OwnedBy.vbs выводит строку заголовка, описывающую каждый столбец (то есть Owner, ParentFolder, Name, Size). Надписи заголовка могут пригодиться при импортировании отчета в электронную таблицу или базу данных, но если вы не хотите, чтобы сценарий выводил строку заголовка, используйте ключ /nh.
В конце сценарий выводит итоговую строку вида
n byte(s) in x file(s)
где n — суммарный размер файлов, x — число найденных файлов. Чтобы отключить вывод итоговой строки, используйте ключ /ns.
Возможно, вы захотите сохранить результаты работы сценария для просмотра в дальнейшем. Для этого нужно перенаправить стандартный вывод сценария в файл. Например, команда
ownedby.vbs d: /o:corpsmithj /s > d:smithj.txt
добавляет в список все файлы на диске D, принадлежащие пользователю corpsmithj, и сохраняет отчет в файле d:smithj.txt. Если сценарий сталкивается с ошибкой чтения файла или каталога, он прописывает сведения об ошибке в стандартное сообщение, определенное по умолчанию в окне команд. Можно перенаправить вывод стандартного сообщения об ошибке в файл, например
ownedby.vbs d: /o:corpsmithj /s > d:smithj.txt 2> d:errors.log
Эта команда пересылает только сообщения об ошибках в файл d:errors.log.
Вы также можете направить стандартный вывод и вывод стандартного сообщения об ошибке в один и тот же файл, например
ownedby.vbs d: /o:corpsmithj /s > d:smithj.txt 2>&1
Эта команда сохраняет и стандартный вывод, и стандартные сообщения об ошибках в файле d:smithj.txt. Нужно иметь в виду, что если запустить сценарий OwnedBy.vbs для целого тома, он, возможно, выдаст объем используемого дискового пространства, несколько заниженный по сравнению с результатами в окне Quota Entries. Это происходит в силу завышения объемов файловой системой NTFS.
Подпрограмма Main
Подпрограмма Main сценария OwnedBy.vbs, показанная в Листинге 1, сначала объявляет свои переменные, а затем проверяет наличие аргументов командной строки. Если в командной строке присутствует параметр /? или отсутствуют имена папок, сценарий вызывает подпрограмму Usage, которая отображает краткое сообщение об использовании сценария и заканчивает работу.
Затем сценарий вызывает функцию ScriptHost(), чтобы определить, какой исполнитель работает со сценарием. Если это не CScript, сценарий вызывает подпрограмму Die для завершения работы сценария с сообщением об ошибке и кодом выхода, отличным от нуля.
Если сценарий OwnedBy.vbs исполняет CScript, подпрограмма Main пытается создать экземпляр объекта ListByOwner. Так как описание класса для объекта ListByOwner существует в файле сценария OwnedBy.vbs, подпрограмма использует ключевое слово New оболочки VBScript вместо метода CreateObject оболочки WScript. Если сценарий OwnedBy.vbs не может создать объект ListByOwner, он заканчивает работу с сообщением об ошибке.
Если объект ListByOwner успешно создается, сценарий проверяет наличие аргументов командной строки /o, /d, /s, /nh и /ns. Аргументы /o, /d и /s соответствуют свойствам объекта ListByOwner — Owner, Delim и Recurse. Я вкратце остановлюсь на них. Булевы переменные blnHeader и blnSummary устанавливаются в значение False, если параметры /nh и /ns, соответственно, присутствуют в командной строке.
Если переменная blnHeader имеет значение True (то есть ключ /nh отсутствует в командной строке), сценарий выполняет метод OutputHeader объекта ListByOwner. Далее сценарий отключает установленный по умолчанию обработчик ошибок VBScript с помощью выражения On Error Resume Next и переходит к перебору аргументов командной строки (то есть имен папок) с помощью цикла For Each.
В теле цикла For Each сценарий устанавливает свойство Folder объекта ListByOwner в соответствии с аргументом командной строки. Если объект ListByOwner вызывает ошибку (например, если папка не существует), сценарий прописывает сообщение об ошибке в стандартное сообщение об ошибке; если нет — сценарий вызывает метод Run объекта ListByOwner. Последним шагом подпрограммы Main является проверка переменной blnSummary. Если значение — True (то есть параметр /ns отсутствует в командной строке), сценарий вызывает метод OutputSummary объекта ListByOwner.
Работа с объектом ListByOwner
Работа сценария OwnedBy.vbs выполняется с помощью объекта ListByOwner. Свойства, используемые объектом ListByOwner, как и частные переменные, применяемые каждым свойством, приведены в Таблице 1. Методы объекта ListByOwner приведены в Таблице 2.
Когда сценарий создает экземпляр объекта ListByOwner с помощью ключевого слова New среды VBScript, автоматически вызывается процедура события Class_Initialize, для инициализации частных переменных объекта и выполнения других задач, возникающих при создании объекта.
Первое, что пытается сделать объект ListByOwner, это создать экземпляр объекта GetOwner.Owner. Это действие не может быть выполнено, если файл библиотеки GetOwner.dll не зарегистрирован в системе. Код процедуры события выполняет собственную обработку ошибки — если метод CreateObject вызывает ошибку, объект ListByOwner вызывает собственную ошибку, вместо отмены выполнения всего сценария. Подпрограмма Main перехватывает эту ошибку и заканчивает работу в штатном режиме.
Затем процедура события Class_Initialize создает частный указатель на объект Scripting.FileSystemObject и устанавливает для свойств значения по умолчанию. После завершения процедуры Class_Initialize переменная objLBO подпрограммы Main содержит инициализированный объект ListByOwner.
Установка свойства Folder
Выражения Public Property Let, которые являются частью языка VBScript, определяют процедуры свойств, которые выполняют управление свойствами объекта ListByOwner. Каждая из процедур свойств устанавливает соответствующую частную переменную, как показано в Таблице 1. При установке свойства Folder код выполняет собственную обработку ошибки и вызывает ошибку, если метод GetFolder объекта FileSystem-Object не может быть выполнен. В этом случае подпрограмма Main может обнаружить ошибку в штатном режиме и перейти к следующей папке, указанной в командной строке.
Подпрограмма ProcessFolder
Когда подпрограмма Main вызывает метод Run объекта ListByOwner, он выполняет подпрограмму ProcessFolder с частной переменной objFolder в качестве аргумента. Подпрограмма ProcessFolder выполняет работу по перебору множеств файлов и папок.
Подпрограмма ProcessFolder выполняет собственную обработку ошибок. Она отключает установленный по умолчанию обработчик ошибок VBScript с помощью выражения On Error Resume Next. Потом, если частная переменная blnRecurse имеет значение True, подпрограмма перебирает множество подкаталогов исходной папки с помощью цикла For Each и вызывает сама себя для каждого подкаталога.
Далее подпрограмма перебирает множество файлов и папок с помощью цикла For Each. Имя владельца каждого файла мы получаем с помощью вызова метода GetOwner объекта objGetOwner, который возвращает строку, содержащую имя владельца файла в виде доменимя пользователя. Если свойство Owner объекта ListByOwner содержит пустую строку (например, конкретный пользователь не указан) или совпадает с именем владельца текущего файла, тогда подпрограмма выводит информацию о файле в следующем виде:
Owner ParentFolder Name Size
В конце подпрограмма ProcessFolder обновляет внутренние переменные объекта ListByOwner, содержащие общее количество файлов и их суммарный размер. Нужно иметь в виду, что вывод без ошибок направляется на стандартный вывод, а вывод с ошибками — на стандартный вывод сообщений об ошибках.
Дополнение к средству квотирования диска
Функция квотирования дисков в Windows полезна, но она недостаточно мощная. Библиотека GetOwner.dll в связке со сценарием OwnedBy.vbs снимает ограничения квотирования, позволяя искать все файлы, принадлежащие пользователю, в одной или нескольких папках и получать сведения об их размерах. Даже если квотирование не используется, эта библиотека DLL и сценарий помогут администратору управлять дисковым пространством более эффективно.
Листинг 1. Подпрограмма Main
Sub Main ' BEGIN COMMENT ' Переменная objLBO содержит указатель на объект ListByOwner. ' END COMMENT Dim objLBO, blnHeader, blnSummary, strFolder ' BEGIN COMMENT ' Если в командной строке присутствует параметр /? или если отсутствуют имена папок, ' выполняется выход с сообщением об использовании. ' END COMMENT With WScript.Arguments If .Named.Exists(?) Or .Unnamed.Count = 0 Then Usage End With ' BEGIN COMMENT ' Завершение сценария с сообщением об ошибке, если он не выполняется хостом CScript. ' END COMMENT If ScriptHost() <> cscript.exe Then _ Die You must run this script using the CScript host., 1 ' BEGIN COMMENT ' Сценарий завершится с ошибкой, если в случае создания экземпляра объекта ListByOwner ' выявляется ошибка. Это ошибка часто связано с тем, что библиотека ADsSecurity.dll не зарегистрирована. ' END COMMENT On Error Resume Next Set objLBO = New ListByOwner If Err <> 0 Then Die [0x & Hex(Err) & ] & Err.Description, Err On Error GoTo 0 With WScript.Arguments ' BEGIN COMMENT ' Получение имени владельца из параметра /O. Если пусто - вывод для всех владельцев. ' END COMMENT objLBO.Owner = .Named(O) ' BEGIN COMMENT ' Получение разделителя выходных данных. ' END COMMENT objLBO.Delim = .Named(D) ' BEGIN COMMENT ' Если присутствует параметр /S, выполняется рекурсия в каждом подкаталоге. ' END COMMENT objLBO.Recurse = .Named.Exists(S) ' BEGIN COMMENT ' Если присутствуют параметры /NH или /NS, выполняется пропуск строки заголовка и итоговой строки соответственно. ' END COMMENT blnHeader = Not .Named.Exists(NH) blnSummary = Not .Named.Exists(NS) End With ' BEGIN COMMENT ' Вывод строки заголовка (при необходимости). ' END COMMENT If blnHeader Then objLBO.OutputHeader ' BEGIN COMMENT ' Сценарий будет обрабатывать собственные ошибки в приведенном ниже цикле For Each. ' END COMMENT On Error Resume Next For Each strFolder In WScript.Arguments.Unnamed objLBO.Folder = strFolder If Err <> 0 Then ' The ListByOwner object raised an error. WScript.StdErr.WriteLine [0x & Hex(Err) & : _ & Err.Description & ] & strFolder Else objLBO.Run End If Err.Clear Next ' BEGIN COMMENT ' Вывод итоговой строки (при необходимости). ' END COMMENT If blnSummary Then objLBO.OutputSummary End Sub
Таблица 1. Свойства и частные переменные объекта ListByOwner
| Свойство | Описание | Частная переменная |
| Folder | Свойство Folder принимает значение, соответствующее имени каждой папки, указанной в командной строке. Если при доступе к папке возникает ошибка (например, папки не существует), объект вызовет ошибку | objFolder |
| Recurse | Свойство Recurse устанавливается в значение True, если объект должен обращаться к подкаталогам указанной папки. Значение по умолчанию — False | blnRecurse |
| Owner | Свойство Owner принимает значение вида домен/имя пользователя, соответствующее имени пользователя, по которому должен осуществляться поиск. Если имя домена не указано, используется текущий домен. Если это свойство содержит пустую строку (по умолчанию), будут выведены данные по всем владельцам | strOwner |
| Delim | Свойство Delim определяет символ, используемый для разделения столбцов на выходе. По умолчанию — символ табуляции | strDelim |
Таблица 2: Методы объекта ListByOwner
| Метод | Описание |
| OutputHeader | Метод OutputHeader выводит строку заголовка. Столбцы отделены друг от друга символом, указанным в свойстве Delim |
| Run | Метод Run запускает процесс вывода для папки, указанной в свойстве Folder. Работа управляется частной подпрограммой ProcessFolder |
| OutputSummary | Метод OutputSummary выводит итоговую строку (общий размер в байтах и количество файлов) |
Powershell — поиск владельца файла
Powershell — поиск владельца файла
Хотите узнать, как найти владельца файла с помощью Powershell? В этом учебнике мы покажем вам, как использовать Powershell для обнаружения владельца файла на компьютере под управлением Windows.
• Windows 2012 R2
• Windows 2016
• Windows 2019
• Windows 2022
• Windows 10
• Окна 11
Список оборудования
Здесь вы можете найти список оборудования, используемого для создания этого учебника.
Эта ссылка будет также показать список программного обеспечения, используемого для создания этого учебника.
Похожий учебник — PowerShell
На этой странице мы предлагаем быстрый доступ к списку учебников, связанных с PowerShell.
Учебник Powershell — поиск владельца файла
Запустите командную линию Powershell.
Найдите владельца нескольких файлов.
Узнайте владельца всех файлов в каталоге.
Поздравляю! Вы можете узнать, кто является владельцем файла, с помощью Powershell.
VirtualCoin CISSP, PMP, CCNP, MCSE, LPIC22022-02-12T15:20:10-03:00
Related Posts
Page load link
Ok
Джеффри Хикс опубликовал очередную статью по PowerShell, посвященную на этот раз управлению файловыми серверами. Мы решили разбить ее на две части: построение отчетов по файловому серверу и непосредственно управление файловыми шарами. В первой части рассмотрим отчеты.
В посте будут рассмотрены следующие вопросы:
- Как вывести список всех сетевых папок на компьютере (компьютерах)
- Создаем отчеты о размерах сетевых папок
- Определяем владельцев файлов
- Находим дату создания файлов выявляем «старые» файлы и файлы, созданные за определенный промежуток времени)
Итак, под катом вы найдете перевод статьи File Server Management with Windows PowerShell.
Получаем все сетевые папки
Начнем с того, что определим, что же расшарено. Задача проста: просто осуществляем запрос класса Win32_Share, чтобы использовать Windows Management Instrumentation (WMI). Вам даже не нужно логиниться на файловом сервере. Вы можете запустить эту команду откуда угодно.
Get-WmiObject -class -Win32_Share -computername chi-fp01
Вместо chi-fp01 укажем имя интересующего нас компьютера
Запустив эту команду Вы получите все сетевые папки, включая принтеры (если таковые имеются). Но так как мы говорим о файловых шарах, то давайте ограничим запрос. Все экземпляры Win32_Share имеют свойство Type, как показано в таблице 1.
Добавим фильтр в первоначальную команду:
Get-WmiObject -class -Win32_Share -computername chi-fp01 –filter "Type=0"
Тем самым мы выводим только нужную информацию.
Но если вы ищите также и скрытые папки – те, которые заканчиваются знаком доллара ($) – фильтр придется слегка переписать:
Get-WmiObject -Class win32_share -computername chi-fp01 –filter "Type=0 AND name like '%$'"
В WMI знак процента (%) используется вместо знака подстановки (wildcard). Вывести все папки, кроме тех, которые скрыты чуть сложнее.
Get-WmiObject -Class win32_share -computername chi-fp01–filter "type=0 AND name like '%[^$]'"
Команда выведен все объекты Win32_Share, у которых свойство Type равно 0 и имя не заканчивается на $.
Получаем размер сетевой папки
Довольно часто необходима информация о том, сколько места занимают файловые шары. Используем Get-ChildItem, или его сокращение dir, и передадим результаты в Measure-Object:
dir c:\shares\public -recurse | where {-Not $_.PSIsContainer}| Measure-Object -Property length -Sum -Minimum -Maximum
В итоге вы получите информацию об общем числе объектов, размер в байтах, наименьшие и наибольшее размерах файлов. В предыдущей команде, применил фильтр. В PowerShell 3.0 то же самое можно сделать проще, однако та команда, которую я использовал, работает как v2.0, так и 3.0. Ее лучше всего запускать локально. Код в примере 1 комбинирует эту команду с нашей техникой WMI, чтобы получить отчет о размере высокоуровневых папок.
Пример 1: Отчет о размерах высокоуровневых сетевых папок
$share=Get-WmiObject -Class Win32_Share -ComputerName
CHI-FP01 -filter "name='Sales'"
$sb={
Param ($path)
dir $path | where {$_.PSIscontainer} |
foreach {
$stats=dir $_.Fullname -recurse -errorAction
"SilentlyContinue" | where {-NOT $_.PSIscontainer} |
Measure-object -Property Length -sum
New-Object -TypeName PSObject -Property @{
Computername=$env:Computername
Path=$_.Name
Fullname=$_.Fullname
SizeKB=[math]::Round(($stats.sum/1KB),2)
NumberFiles=$stats.count
} #property
} #foreach
} #sb
$results=Invoke-Command -ScriptBlock $sb -ComputerName
$share.__SERVER -ArgumentList @($share.path)
-HideComputerName
Вы можете форматировать или обрабатывать $results как вашей душе будет угодно. Нужна удобоваримая таблица? Просто используйте следующую команду:
$results | Format-Table Computername,Fullname,SizeKB,NumberFiles -autosize
Тем самым можно сделать полный отчет по использованию всех папок на файловом сервере не составляет труда. Сэкономьте время, воспользуетесь примером 2.
Пример 2: Отчет об использовании файловых шар
$sb={
#Get the file shares locally.
$shares=Get-WmiObject -Class Win32_Share -filter "type=0"
foreach ($share in $shares) {
#Suppress any access denied error messages.
Write-Host "Measuring $($share.path)" -ForegroundColor Green
$stats=dir $share.path -Recurse -ErrorAction SilentlyContinue |
Where {-Not $_.PSIscontainer} |
Measure-Object -Property Length -Sum
$hash=@{
Computername=$env:Computername
Path=$share.path
Share=$share.Name
SizeKB=[math]::Round(($stats.sum/1KB),2)
Files=$stats.count
}
#Write a custom object to the pipeline for each share.
New-Object -TypeName PSObject -Property $hash
} #foreach $share
}#sb
$results = Invoke-Command -ScriptBlock $sb -ComputerName
CHI-FP01 -HideComputerName
И снова я слегка отформатирую таблицу.
$results | sort SizeKB –Descending | Select Computername,Share,SizeKB,Files | ft -auto
Получаем файлы по владельцу
Двигаемся дальше – найдем владельцев файлов. Если вы используете квоты, отчеты уже наверняка получаете. В противном случае, все, что вам нужно – это извлечь ACL файла, который включает в себя владельца, и агрегировать результаты. Лучше всего добавить владельца файла в качестве кастомного свойства
$data=dir | where {-not $_.PSIsContainer} | select name, @{Name="Owner";Expression={(Get-ACL $_.fullname).Owner}}, length
Мы можем группировать по свойству нового владельца и затем обрабатывать новый объект.
$data | group owner | Select Name,Count,@{Name="Size";Expression={($_.Group | Measure-Object -Property Length -sum).Sum}}
Пара усилий и вы можете применить тот же подход к файловой шаре, как указано в коде примера 3.
Пример 3: Группируем файловые шары по владельцу
$sb={
Param($path)
$data=dir $path |
where {-not $_.PSIsContainer} |
select name, @{Name="Owner";Expression=
{(Get-ACL $_.fullname).Owner}},length
$data | group -property owner |
Select @{Name="Computername";Expression={$env:computername}},
@{Name="Path";Expression={$path}},Name,Count,@{Name=
"Size";Expression={
($_.Group | Measure-Object -Property Length -sum).Sum}}
} #sb
<#
Run the command remotely and suppress the RunspaceID since we
don't really need it.
#>
Invoke-Command -ScriptBlock $sb -ComputerName CHI-FP01
-ArgumentList @("c:\shares\public") -HideComputerName |
Select * -ExcludeProperty RunspaceID
Я также должен указать на то, что могут проблемы: с файлами, имя которых более 260 символов или содержит необычные символы, особенно если вы пытаетесь запустить Get-ACL. В PowerShell 3.0 этот командлет имеет параметр -LiteralPath, что помогает решить вышеуказанные проблемы.
Опять выведем читаемую таблицу.
$data | Sort Size | ft -auto
Получаем файлы по дате создания
Последняя техника создания отчетов, которую я хочу продемонстрировать – это создание отчета с последними созданными файлами. Фактически, мы создаем коллекцию объектов, которую можем использовать несколькими способами. Возможно вы захотите использовать объекты или удалить или переместить файлы, или можете захотите построить отчет, который можно отправить руководству. Всегда создавайте команды PowerShell так, чтобы потом их можно использовать.
Определить возраст файл не так просто. В PowerShell файловый объект (объект типа файл) имеет несколько свойств, которые вы возможно захотите использовать. Например, команда:
get-item c:\work\wishlist.txt | Format-List Name,*time
дает вывод, представленный на скриншоте ниже.
Лично я считаю, что лучше использовать LastWriteTime, который обозначает, когда к файлу в последний раз обращались. Мне встречались ситуации, когда LastAccessTime обновлялся через сторонние программы, например, антивирус, что само по себе уже не означает правды. И LastAccessTime был деактивировал еще со времени Windows Vista, хотя вы можете его включить. Вам также нужно быть осторожным, потому что эти значения могут меняться в зависимости от того, копируете ли вы или перемещаете файлы между дисками (between volumes). Но вы можете решить это сами. Используя этот файл как пример, мы может заставить PowerShell сказать нам, насколько стар файл. См. пример 4.
Пример 4. Определяем возраст файлов
PS C:\work> get-item wishlist.txt | format-list name,
CreationTime,LastWriteTime,
>> @{Name="Age";Expression={(Get-Date)-$_.LastWriteTime}},
>> @{Name="Days";Expression={((Get-Date)
-$_.LastWriteTime).TotalDays}}
>>
Name : wishlist.txt
CreationTime : 11/23/2010 10:31:10 PM
LastWriteTime : 2/15/2011 7:36:34 AM
Age : 511.06:42:17.4251748
Days : 511.279372271039
Свойство Age является объектом TimeSpan, и свойство Days является просто свойством TotalDays этого объекта. Но так как мы можем этом сделать для одного файла, мы можем сделать и для других Давайте взглянем на мою общую папку и найдем все файлы, которые не менялись за последние 400 дней.
dir c:\shares\public -recurse | Select Fullname,CreationTime,LastWriteTime,
@{Name="Age";Expression={(Get-Date)-$_.LastWriteTime}},
@{Name="Days";Expression={[int]((Get-Date) -$_.LastWriteTime).TotalDays}},
@{Name="Owner";Expression={(Get-ACL $_.fullname).Owner}} | Where {$_.Days -ge 400} | Sort Days -Descending
Я пойду дальше и включу еще и владельца файла. На скриншоте ниже показаны результаты от запуска этого код в удаленной сессии на моем файловом сервере.
Я могу сохранить эти результаты в переменную и использовать их в любое время. Так как у меня есть полное имя файла, передать в другую команду, например, Remove-Item, не составит труда.
Одной из моих любимых техник является определение того, сколько файлов было изменено за год.
dir c:\shares\sales -recurse | Select Fullname,LastWriteTime,
@{Name="Age";Expression={(Get-Date)-$_.LastWriteTime}},
@{Name="Year";Expression={$_.LastWriteTime.Year}} | Group-Object Year | Sort Name
Как вы можете видеть на скриншоте, все выглядит причесано. Нужны детали? Можно проанализировать свойство Group, которое представляет собой коллекцию файлов.
Полезно знать, сколько файлов не изменялось за 30, 90 или 180 дней. К сожалению, простого способа использовать Group-Object для этого не существует, поэтому мне необходимо придется «пойти иным путем»; смотрите пример 5.
Пример 5: Определяем период изменения файлов
$path="c:\scripts"
#Get some other properties in case we want to further
#break down each bucket.
$files=dir $path -recurse |
Select Fullname,CreationTime,LastWriteTime,Length,
@{Name="Age";Expression={(Get-Date)-$_.LastWriteTime}},
@{Name="Days";Expression={[int]((Get-Date)
-$_.LastWriteTime).TotalDays}}
$hash=@{
Path=$path
Over= ($files | Where {$_.Days -gt 365} | Measure-Object).Count
'365Days'= ($files | Where {$_.Days -gt 180 -AND
$_.Days -le 365} | Measure-Object).Count
'180Days'= ($files | Where {$_.Days -gt 90 -AND
$_.Days -le 180} | Measure-Object).Count
'90Days'= ($files | Where {$_.Days -gt 30 -AND
$_.Days -le 90} | Measure-Object).Count
'30Days'= ($files | Where {$_.Days -gt 7 -AND
$_.Days -le 30} | Measure-Object).Count
'7Days'= ($files | Where {$_.Days -gt 0 -AND
$_.Days -le 7} | Measure-Object).Count
}
New-Object -TypeName PSObject -Property $hash |
Select Path,Over,365Days,180Days,90Days,30Days,7Days
На рисунке ниже показан результат, когда я запустил этот код для папки с моими скриптами, которая, как я знаю, имеет плотное распределение по возрасту (decent age distribution). Мой код не включает в себя актуальные файлы, но это было бы слишком сложно изменить мой пример.
За основу поста использована первая часть статьи File Server Management with Windows PowerShell.
Бонус:
Кстати, о том, как найти файлы с помощью PowerShell и WMI Джеффри Хикс пишет в своем блоге (часть 1 и 2).
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Во второй части статьи рассматриваются вопросы создания и удаления файловых шар и делегирования прав доступа к ним. Был бы интересен ее перевод?
Проголосовали 146 пользователей. Воздержались 14 пользователей.
