PowerShell – управление общими папками Одна из тематик где не часто применяют PowerShell – управление общими папками. На мой взгляд подобное недопустимо и надо как то это исправлять. Конечно, назначение и чтение разрешений реализовывается немного через одно место (необходим вызов нескольких классов и пр.) , для некоторых это даже станет дополнительным поводом что бы отказаться от предлагаемого ниже, но не надо отчаиваться… Традиционно, без замахивания на мега мануал и без излишних описаний только практические примеры. Получение списка общих папок Для работы с общими папками из PowerShell используется WMI класс Win32_Share . Code: # получаем список доступных свойств и методов Get-WmiObject -Class Win32_Share | Get-Member В полученном списке видим следующее: Create – Создание общей папки. Delete – Удаление общей папки. GetAccessMask – Возвращает объект с описанием прав доступа SetShareInfo – Используется для установки параметров общего ресурса. Для начала ограничимся только чтением списка общих папок. Выведем данные в виде таблицы. Code: Get-WmiObject -Class Win32_Share | Sort -Property Type, Name | Format-Table type, name, path, description -auto Для получения сведений с удаленных серверов используем тот же самый запрос к классу WMI Win32_Share с ключом “-ComputerName” Code: # Вариант №1 $servers =@( "server01", "server02") # Вариант №2 $servers = Get-Content "Servers.txt" # сам запрос foreach($server in $servers) { get-WmiObject Win32_Share -computerName $server -filter "Type = 0" | ft name, description, type, path -auto } Создание общей папки Переходим к процессу создания общих папок. Для работы используется все тот же WMI класс Win32_Share. Code: $Shares = [WMICLASS]"Win32_Share" $Shares | Get-Member В полученном списке есть метод “Create”, который мы видели ранее, его можно использовать при условиях: Вы являетесь администратором на компьютере PowerShell запущен с опцией “Run as administrator”. Теперь создадим общий ресурс “Sample” в папке D:\Sample Code: $Shares.Create("D:\Sample","Sample",0) Если быть точнее, полный синтаксис команды будет выглядеть следующим образом Code: $Shares.Create("D:\SampleShare","Sample",0,100,"Share description") Примечание: документация по данному методу доступна по ссылке на MSDN. Параметры для метода “Create” имеют следующий вид Code: uint32 Create( [in] string Path, [in] string Name, [in] uint32 Type, [in] uint32 MaximumAllowed, [in] string Description, [in] string Password, [in] Win32_SecurityDescriptor Access ); Path – Локальный путь. Например, “D:\FolderToShare”. Name – Имя общей папки. Например “SampleShare”. Type – Тип ресурса. 0 – Disk Drive 1 – Print Queue 2 – Device 3 – IPC 2147483648 – Disk Drive Admin 2147483649 – Print Queue Admin 2147483650 – Device Admin 2147483651 – IPC Admin MaximumAllowed – Ограничение количества одновременно подключенных пользователей. Description – Комментарий. Password – Пароль (в случае если сервер запущен в режиме share-level security) если сервер работает в режиме user-level security, параметр игнорируется. Access – Дескриптор безопасности т.е. WMI класс Win32_SecurityDescriptor . Чтение разрешений Получения списка разрешений производится с помощью класса Win32_LogicalShareSecuritySettings Для примера можно посмотреть скрипт, взятый отсюда. Который выводит в файл D:\Info\SharesList.csv список имеющихся общих папок. Code: $filename = ‘D:\Info\SharesList.csv’ $shares = Get-WmiObject Win32_Share -filter ‘type=0′ $Shareinfo = @() foreach ($share in $shares) { $shareSec = gwmi Win32_LogicalShareSecuritySetting -filter "name=’$($share.name)’" if($shareSec) { $sd = $sharesec.GetSecurityDescriptor() $ShareInfo += $SD.Descriptor.DACL |% { $_ | select @{e={$share.name};n=‘Name’}, @{e={$share.Path};n=‘Path’}, @{e={$share.Description};n=‘Description’}, AccessMask, AceFlags, AceType, @{e={$_.trustee.Name};n=‘User’}, @{e={$_.trustee.Domain};n=‘Domain’}, @{e={$_.trustee.SIDString};n=‘SID’} } } } $ShareInfo | select Name,Path,Description,User,Domain,SID, AccessMask,AceFlags,AceType | export-csv -noType $filename Модификация разрешений Теперь самая сложная и самая интересная часть – модификация разрешений. В данный момент у нас имеется общая папка с дефолтовыми разрешениями Everyone – Read. Для того чтобы создать новый набор прав нам нужно знать следующее: Имя сетевой папки. имя пользователя, которому будем назначать права; тип доступа (FullControl, Change, Read). Для работы нам понадобится аж целых три класса: Win32_SecurityDescriptor Win32_Ace Win32_Trustee В скрипте приведенном ниже задается разрешения для группы “Authenticated Users” равными Change. Примечание: Готовый скрипт взят с http://www.sysadmins.lv/PermaLink,guid,4ef64f24-46fb-41d1-895c-cee009e2a483.aspx. Для детального изучения настоятельно рекомендую к прочтению. Code: # задаем имя общей папки $share="Sample" # создаем общую папку ([wmiClass] ‘Win32_share’).Create("D:\Sample", $share, "0", "0", "Sample Share") # кто будет иметь доступ $user = "Authenticated Users" # какой доступ $mask = "Change" # объявляем классы $SD = ([WMIClass] "Win32_SecurityDescriptor").CreateInstance() $ace = ([WMIClass] "Win32_Ace").CreateInstance() $Trustee = ([WMIClass] "Win32_Trustee").CreateInstance() # Выясняем SID пользователя $SID = (new-object security.principal.ntaccount $user).translate([security.principal.securityidentifier]) [byte[]] $SIDArray = ,0 * $SID.BinaryLength $SID.GetBinaryForm($SIDArray,0) $Trustee.Name = $user $Trustee.SID = $SIDArray # преобразовываем права в класс FileSystemRights $ace.AccessMask = [System.Security.AccessControl.FileSystemRights]"Modify, Synchronize" $ace.AceType = 0 $ace.Trustee = $Trustee $SD.DACL = $ace $share = get-wmiObject win32_share -filter "name=’$share’" $inParams = $share.psbase.GetMethodParameters("SetShareInfo") $inParams.Access = $SD # задаем необходимые параметры $share.psbase.invokemethod("setshareinfo", $inParams, $null) Удаление существующих общих папок Удаление общих папок вещь простая. Вводим команду в которой “ShareName” является именем существующей общей папки. Code: [wmi]‘root\cimv2:Win32_Share="ShareName"’ | Get-Member В списке методов есть “Delete”. Его и будем использовать. Для удаления локальной общей папки вводим ([wmi]‘root\cimv2:Win32_Share="ShareName"’).Delete() а для удаления общей папки на удаленном сервере вводится Code: ([wmi]‘\\SERVER_NAME\root\cimv2:Win32_Share="ShareName"’).Delete() Примечание: В PowerShell v3 все сказанное выше реализовано по другому, но об этом в следующий раз. Опубликовано: 11.07.2012 Сергей Мариничев http://blog.wadmin.ru/2012/07/powershell-manage-shares/
PowerShell – синхронизация настроек NPS PowerShell – синхронизация настроек NPS Как известно продукты компании Microsoft всегда имели две стороны. Первая это GUI, для любителей мыши и вторая – командная строка, в которой возможности по управлению и настройке гораздо шире. Сегодня речь пойдет про то как можно синхронизировать настройки NPS (Network Policy Server) с помощью скрипта, по расписанию. Алгоритм действий прост: Шаг №1 – выгружаем на источнике конфигурацию в файл. Code: netsh nps export filename = PATH_TO_FILE exportPSK = yes Шаг №2 – на целевом сервере импортируем настройки. Code: netsh nps import filename = $NPSConfigTempFile Для автоматизации процесса необходим скрипт который можно будет как задачу запускать по нужному нам расписанию. Code: # задаем имя сервера с которого будет браться информация $NPSMaster = "NPS-MASTER" # определяем имена файлов $NPSTempFile = "C:\TEMP\NPSConfig.xml" $NPSConfigTempFile = "C:\TEMP\NPSTempConfig.xml" $NPSRemoteConfigFile = "\\NPS-MASTER\c$\TEMP\NPSConfig.xml" # задаем источник NPS-Sync if (!(get-eventlog -logname "System" -source "NPS-Sync")) {new-eventlog -logname "System" -source "NPS-Sync"} trap {write-eventlog -logname "System" -eventID 1 -source "NPS-Sync" -EntryType "Error" -Message "An Error occured during NPS Sync: $_."; exit} # На сервере источнике экспортируем конфигурацию в файл (не забываем что WinRM должен быть включен и настроен) $configExportResult = invoke-command -ComputerName $NPSMaster -ArgumentList $NPSTempFile -scriptBlock {param ($NPSTempFile) netsh nps export filename = $NPSTempFile exportPSK = yes} # копируем файл на целевой хост Copy-Item $NPSRemoteConfigFile $NPSConfigTempFile # очищаем существующие настройки $configClearResult = netsh nps reset config # импортируем новые настройки $configImportResult = netsh nps import filename = $NPSConfigTempFile # удаляем файлы remove-item -path $NPSConfigTempFile remove-item -path $NPSRemoteConfigFile # создаем отчет $successText = "Network Policy Server Configuration synchronized from $NPSMaster. Export Results: $configExportResult Import Results: $configImportResult " # пишем отчет в журнал write-eventlog -logname "System" -eventID 1 -source "NPS-Sync" -EntryType "Information" -Message $successText # Отправляем его по почте $smtpServer = "mail.test.lab" $msg = new-object Net.Mail.MailMessage $smtp = new-object Net.Mail.SmtpClient($smtpServer) $msg.From = "nps.sync@test.lab" $msg.ReplyTo = "nps.sync@test.lab" $msg.To.Add("nps.admin@test.lab") $msg.subject = "NPS Sync report" $msg.body = $successText $smtp.Send($msg) Опубликовано: 11.07.2012 Сергей Мариничев http://blog.wadmin.ru/2012/07/powershell-sync-nps-config/