Новости из Блогов PowerShell – управление общими папками; синхронизация настроек NPS

Discussion in 'Мировые новости. Обсуждения.' started by Suicide, 12 Jul 2012.

  1. Suicide

    Suicide Super Moderator
    Staff Member

    Joined:
    24 Apr 2009
    Messages:
    2,373
    Likes Received:
    6,619
    Reputations:
    693
    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).
    Для работы нам понадобится аж целых три класса:


    В скрипте приведенном ниже задается разрешения для группы “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/
     
  2. Suicide

    Suicide Super Moderator
    Staff Member

    Joined:
    24 Apr 2009
    Messages:
    2,373
    Likes Received:
    6,619
    Reputations:
    693
    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/