Перспективы использования геосоциальных сервисов в маркетинговой деятельности...
Управление файловым сервером с помощью PowerShell
2. Содержание
Введение ......................................................................................................................................................3
Получаем отчеты по сетевым папкам с помощью PowerShell ................................................................4
Получаем все сетевые папки..................................................................................................................4
Получаем размер сетевой папки ...........................................................................................................5
Получаем файлы по владельцу..............................................................................................................7
Управляем сетевыми папками с помощью PowerShell..........................................................................12
Создаем новые папки ...........................................................................................................................12
Расширенные настройки папки............................................................................................................13
Удаляем сетевые папки ........................................................................................................................14
Сводим воедино....................................................................................................................................15
3. Введение
PowerShell позволяет упростить ряд задач управления файловыми серверами. В этом руководстве
Джеффри Хикс рассматривает как с помощью простых интерактивных команд можно построить
отчеты по файлам и сетевым папкам на файлом сервере, а также осуществить такие простые
операции как создание и удаление папки и задание разрешений.
4. Получаем отчеты по сетевым папкам с
помощью 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"
Тем самым мы выводим только нужную информацию.
5. Но если вы ищите также и скрытые папки – те, которые заканчиваются знаком доллара ($) –
фильтр придется слегка переписать:
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'"
6. $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/ 1 KB), 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.
7. 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/ 1 KB), 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
8. Мы можем группировать по свойству нового владельца и затем обрабатывать новый объект.
$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:sharespublic" ) -HideComputerName |
Select * -ExcludeProperty RunspaceID
Я также должен указать на то, что могут проблемы: с файлами, имя которых более 260 символов
или содержит необычные символы, особенно если вы пытаетесь запустить Get-ACL. В PowerShell
3.0 этот командлет имеет параметр -LiteralPath, что помогает решить вышеуказанные проблемы.
Опять выведем читаемую таблицу.
$data | Sort Size | ft -auto
9. Получаем файлы по дате создания
Последняя техника создания отчетов, которую я хочу продемонстрировать – это создание отчета
с последними созданными файлами. Фактически, мы создаем коллекцию объектов, которую
можем использовать несколькими способами. Возможно вы захотите использовать объекты или
удалить или переместить файлы, или может захотите построить отчет, который можно отправить
руководству. Всегда создавайте команды PowerShell так, чтобы потом их можно использовать.
Определить возраст файл не так просто. В PowerShell файловый объект (объект типа файл) имеет
несколько свойств, которые вы возможно захотите использовать. Например, команда:
get -item c:workwishlist.txt | Format-List Name,* time
дает вывод, представленный на скриншоте ниже.
Лично я считаю, что лучше использовать LastWriteTime, который обозначает, когда к файлу в
последний раз обращались. Мне встречались ситуации, когда LastAccessTime обновлялся через
сторонние программы, например, антивирус, что само по себе уже не означает правды.
И LastAccessTime был деактивировал еще со времени Windows Vista, хотя вы можете его
включить. Вам также нужно быть осторожным, потому что эти значения могут меняться в
зависимости от того, копируете ли вы или перемещаете файлы между дисками (between
volumes). Но вы можете решить это сами. Используя этот файл как пример, мы может заставить
PowerShell сказать нам, насколько стар файл. См. пример 4.
10. Пример 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, не составит труда.
Одной из моих любимых техник является определение того, сколько файлов было изменено за
год.
11. dir c:sharessales -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
12. $_.Days -le 7 } | Measure-Object).Count
}
New -Object - TypeName PSObject - Property $hash |
Select Path,Over, 365 Days, 180 Days, 90 Days, 30 Days, 7 Days
На рисунке ниже показан результат, когда я запустил этот код для папки с моими скриптами,
которая, как я знаю, имеет плотное распределение по возрасту (decent age distribution). Мой код
не включает в себя актуальные файлы, но это было бы слишком сложно изменить мой пример.
Управляем сетевыми папками с помощью
PowerShell
В этом разделе в зоне нашего внимания находятся такие вопросы как создание сетевой папки,
делегирование прав доступа к ней и прекращение совместного доступа.
Создаем новые папки
Теперь давайте взглянем на то, как можно использовать PowerShell для создания файлов и папок
и управления ими. Все, что я продемонстрирую, Вы можете использовать в PS 2.0 и 3.0 (хотя в
PS 3.0 приводимые мною примеры можно упростить). Управление файловым сервером в
PowerShell 2.0 требует обращения к WMI и написанию сложных скриптов. В PowerShell 3.0,
особенно если у вас Windows Server 2012, этот тип управления значительно упрощен. Именно его
я и собираюсь рассмотреть.
Все, что нам необходимо, уже имеется в модуле SMBShare, который по умолчанию установлен
на моей машине Windows 8. Команды в этом модуле позволят нам локально и удаленно управлять
папками. Я не собираюсь останавливаться на каждой команде подробно – они довольно
однотипны; рекомендую прочитать справку и примеры. Мы же начнем с использования
команды New-SMBShare, чтобы создать новую папку.
Сделать это нужно за пару шагов. Так как папка должна быть на удаленном сервере, я
установлю удаленную сессию PowerShell:
$session= New -PSSession -ComputerName SRV2K12RC
Я, конечно, могу использовать интерактивную сессию, однако передо нами стоит задача
автоматизации, так что использую команду Invoke-Command. Для начала я создам новую
папку:
invoke-command -ScriptBlock {mkdir c:sharescompanyfiles}-Session $session
А сейчас сложная часть. Я хочу установить такие NTFS разрешения, чтобы JDHLABDomain
Users имела разрешения на изменения (Change). Для этого необходимо создать новое правило
доступа, изменяющего список правил доступа и заново применяющих их к папке. В примере 6
13. приведен пример скрипта:
Пример 6: Создание, изменение и применение правила доступа
$sb={
Param($path)
$du= new -object System.Security.AccessControl.FileSystem
AccessRule "jdhlabdomain users" , "Modify" , "allow"
$acl = Get -ACL $path
$acl.AddAccessRule($du)
Set -Acl -Path $path -AclObject $acl
}
В примере 6 я сделал так, чтобы параметр пути можно было заново использовать.
Invoke-Command -ScriptBlock $sb -Session $session -ArgumentList
c:sharescompanyfiles
Существует способы упростить этот процесс, но для целей ясности мы сохраним все так как есть.
Сейчас мы готовы создать новую папку.
Я могу использовать эту сессию, но я хочу продемонстрировать, как можно использовать
команду New-SmbShare, чтобы удаленно подключиться к файловому серверу:
New -SmbShare -Name Files -Path c:sharescompanyfiles
-CimSession SRV2K12RC -FullAccess "jdhlabdomain admins"
-ChangeAccess Everyone -Description "Company files"
Право доступа к папке по умолчанию стоит “Только чтение” (ReadOnly). Я выдал доменным
админам Полный контроль (Full Control) на папку, и всем остальным выдал права на изменение
(Change). Этот путь относителен к удаленному компьютеру, который должен работать под PS 3.0.
Расширенные настройки папки
Получить информацию о папке можно в любое время, использовав команду Get-SMBShare, как
вы можете видеть на рисунке 9. Можно сделать еще парочку вещей с нашими папками,
например, зашифровать SMB соединение, какой режим перечисления (enumeration mode) и тип
кеширования использовать для папки. Я собираюсь использовать Set-SMBShare, чтоб
осуществить гибкую настройку для только что созданной папки. Посмотрим это на примере 7.
Пример 7: Гибкая настройка папки
PS C:> Set -SmbShare -Name Files -EncryptData $ True
-FolderEnumerationMode AccessBased -CachingMode
Documents -CimSession SRV2K12RC
Confirm
Are you sure you want to perform this action?
SRV2K12RC: Performing operation 'Modify' on Target '*,Files'.
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?]
Help ( default is "Y" ):
14. Указанное выше применяется к одной единственной папке, но вы с легкостью можете
использовать Get-SMBShare для извлечение всех папок и их последующей передачи в Set-
SMBShare и применения изменений к ним всем:
Get -SMBShare -CimSession SRV2K12RC -Special $ False | Set -SmbShare -EncryptData $ True -Confirm:$ false
Эта команда извлечет все папки (кроме административных папок) на компьютере SRV2K12RC и
установим свойствоEncryptData в значении True. Мне не хочется подтверждать каждое
действие, поэтому переключатель Confirm установлен в значение False. Set-SMBshare не
запишет ничего в конвейер, в том случае если вы не используете –Passthru. Как видите, я смог
изменить все с помощью одной единственной команды.
Удаляем сетевые папки
Напоследок удалим сетевую папку. Код в примере 8 полностью отключает совместный доступ к
папке, которую я только что создал. Можно ли это сделать проще? Конечно, структура папок до
сих пор на файловом сервере.
Пример 8: Удаляем сетевую папку
PS C:> Remove-SmbShare -Name Files -CimSession SRV2K12RC
Confirm
Are you sure you want to perform this action?
SRV2K12RC: Performing operation 'Remove-Share' on Target
'*,Files'.
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?]
Help ( default is "Y" ):
15. Сводим воедино
А теперь давайте сведем все в одном скрипте. Не вдаваясь с детали кода, отмечу, что команды
могут быть запущены параллельно. Например, после создания папки, создаю сетевую папку и
устанавливаю NTFS разрешения в то же время, см. пример 9.
Пример 9: Создаем сетевую папку и устанавливаем NTFS разрешения
Workflow New-FileShare {
Param(
[string]$Name,
[string]$Path,
[string]$Principal,
[string]$Right="Modify"
)
#Это делаем в первую очередь.
Sequence {
#создаем папку
Write-Verbose -Message "Creating new folder $path on
$pscomputername"
$newfolder = New-Item -Path $path -ItemType Directory
}
#Идем дальше.
Sequence {
Parallel {
#эти команды могут быть запущены параллельно
InlineScript {
Write-Verbose -Message "Modifying NTFS permissions"
Write-Verbose -Message "Creating entry for
$using:principal with a right of $using:Right"
$entry=New-Object -typename System.Security
.AccessControl.FileSystemAccessRule -argumentlist
$using:Principal,$using:Right,"allow"
#получаем существующий ACL
$acl = Get-ACL -path $using:path
#добавляем новую запись
$acl.AddAccessRule($entry)
Write-Verbose -Message "Applying the new ACL"
Set-Acl -Path $using:path -AclObject $acl
} #inline
#Создаем сетевую папку.
Write-Verbose -message "Creating the file share $name"
$newshare = New-SmbShare -Name $name -Path $path
-Description "File share for $principal" -EncryptData $True
-FolderEnumerationMode AccessBased -CachingMode
Documents -FullAccess "$env:userdomaindomain admins"
-ChangeAccess $Principal
} #Parallel
} #sequence
#Получаем результаты.
Sequence {
Parallel {
16. Write-Verbose -Message "Getting the new share"
Get-SmbShare -Name $name
Write-Verbose -Message "Getting the new share access"
Get-SmbShareAccess -Name $name
}
}
Этот скрипт создает новую сетевую папку, присваивает разрешения пользователю или группе. Я
могу запустить ее из-под Windows 8 или на файловом сервере Windows Server 2012, использовав
следующую команду (которая должна быть введена в одну строчку):
New -FileShare -Name adeco -Path c:sharesadeco -Principal jdhlabadeco - Right "FullControl" -
PSComputerName SRV2K12RC
Процесс займет пару секунд. Результаты на скриншоте ниже.
Нет ничего плохого в том, чтобы использовать обыкновенный графический интерфейс для того
же самого. Однако если Вам нужны специализированные отчеты или же вы желаете
автоматизировать этот процесс, PowerShell подойдет как нельзя лучше.